MeshDeformSave.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. /*
  2. ** Command & Conquer Generals Zero Hour(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. /* $Header: /Commando/Code/Tools/max2w3d/MeshDeformSave.cpp 6 11/12/99 11:12a Greg_h $ */
  19. /***********************************************************************************************
  20. *** Confidential - Westwood Studios ***
  21. ***********************************************************************************************
  22. * *
  23. * Project Name : Commando / G 3D engine *
  24. * *
  25. * File Name : MeshDeformSafe.CPP
  26. * *
  27. * Programmer : Patrick Smith *
  28. * *
  29. * Start Date : 05/28/99 *
  30. * *
  31. * Last Update :
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  36. #include "MeshDeform.H"
  37. #include "MeshDeformSave.H"
  38. #include "MeshDeformData.H"
  39. #include "MeshDeformSet.H"
  40. #include "MeshDeformSaveSet.H"
  41. #include "Util.H"
  42. #include "ModStack.H"
  43. #include "MeshBuild.H"
  44. #include "MeshSave.H"
  45. ///////////////////////////////////////////////////////////////////////////
  46. //
  47. // Initialize
  48. //
  49. ///////////////////////////////////////////////////////////////////////////
  50. void
  51. MeshDeformSaveClass::Initialize
  52. (
  53. MeshBuilderClass &builder,
  54. Object * object,
  55. Mesh & mesh,
  56. Matrix3 * transform
  57. )
  58. {
  59. // Start fresh
  60. Reset ();
  61. //
  62. // Attempt to gain access to the IDerivedObject this node references
  63. //
  64. int test = object->SuperClassID ();
  65. int test2 = GEN_DERIVOB_CLASS_ID;
  66. if ((object != NULL) &&
  67. (object->SuperClassID () == GEN_DERIVOB_CLASS_ID)) {
  68. //
  69. // Loop through all the modifiers and see if we can find the
  70. // Westwood Damage Mesh modifier.
  71. //
  72. IDerivedObject *derived_object = static_cast<IDerivedObject *> (object);
  73. int modifier_count = derived_object->NumModifiers ();
  74. bool found = false;
  75. for (int index = 0; (index < modifier_count) && !found; index ++) {
  76. //
  77. // If this is the right modifier, then initialize using the
  78. // data it contains.
  79. //
  80. Modifier *modifier = derived_object->GetModifier (index);
  81. if ((modifier != NULL) && (modifier->ClassID () == _MeshDeformClassID)) {
  82. //
  83. // Attempt to get at the modifier data for this context
  84. //
  85. ModContext *mod_context = derived_object->GetModContext (index);
  86. if ((mod_context != NULL) && (mod_context->localData != NULL)) {
  87. MeshDeformModData *mod_data = static_cast<MeshDeformModData *> (mod_context->localData);
  88. Initialize (builder, mesh, *mod_data, transform);
  89. }
  90. // Found it!
  91. found = true;
  92. }
  93. }
  94. }
  95. return ;
  96. }
  97. ///////////////////////////////////////////////////////////////////////////
  98. //
  99. // Initialize
  100. //
  101. ///////////////////////////////////////////////////////////////////////////
  102. void
  103. MeshDeformSaveClass::Initialize
  104. (
  105. MeshBuilderClass & builder,
  106. Mesh & mesh,
  107. MeshDeformModData & mod_data,
  108. Matrix3 * transform
  109. )
  110. {
  111. //
  112. // Loop through all the sets in the modifier
  113. //
  114. for (int index = 0; index < mod_data.Get_Set_Count (); index ++) {
  115. //
  116. // If this set isn't empty then add its data to our list
  117. //
  118. MeshDeformSetClass &deform_set = mod_data.Peek_Set (index);
  119. if (deform_set.Is_Empty () == false) {
  120. //
  121. // Add this set to our list
  122. //
  123. MeshDeformSaveSetClass *save_set = new MeshDeformSaveSetClass;
  124. deform_set.Save (builder, mesh, *save_set, transform);
  125. m_DeformSets.Add (save_set);
  126. }
  127. }
  128. return ;
  129. }
  130. ///////////////////////////////////////////////////////////////////////////
  131. //
  132. // Reset
  133. //
  134. ///////////////////////////////////////////////////////////////////////////
  135. void
  136. MeshDeformSaveClass::Reset (void)
  137. {
  138. //
  139. // Delete all the damage sets
  140. //
  141. for (int index = 0; index < m_DeformSets.Count (); index ++) {
  142. SAFE_DELETE (m_DeformSets[index]);
  143. }
  144. m_DeformSets.Delete_All ();
  145. return ;
  146. }
  147. ///////////////////////////////////////////////////////////////////////////
  148. //
  149. // Export
  150. //
  151. ///////////////////////////////////////////////////////////////////////////
  152. bool
  153. MeshDeformSaveClass::Export (ChunkSaveClass &chunk_save)
  154. {
  155. bool retval = true;
  156. if (m_DeformSets.Count() > 0) {
  157. retval = chunk_save.Begin_Chunk (W3D_CHUNK_DEFORM);
  158. if (retval) {
  159. //
  160. // Write the deform header to the file
  161. //
  162. W3dMeshDeform header = { 0 };
  163. header.SetCount = m_DeformSets.Count ();
  164. header.AlphaPasses = m_AlphaPasses;
  165. retval &= (chunk_save.Write (&header, sizeof (header)) == sizeof (header));
  166. if (retval) {
  167. //
  168. // Export all the sets in the deformation
  169. //
  170. retval &= Export_Sets (chunk_save);
  171. }
  172. retval &= chunk_save.End_Chunk ();
  173. }
  174. }
  175. // Return the true/false result code
  176. return retval;
  177. }
  178. ///////////////////////////////////////////////////////////////////////////
  179. //
  180. // Export_Sets
  181. //
  182. ///////////////////////////////////////////////////////////////////////////
  183. bool
  184. MeshDeformSaveClass::Export_Sets (ChunkSaveClass &chunk_save)
  185. {
  186. bool retval = true;
  187. //
  188. // Loop through all the sets and write them to the file
  189. //
  190. for (int set_index = 0; (set_index < m_DeformSets.Count ()) && retval; set_index ++) {
  191. retval &= chunk_save.Begin_Chunk (W3D_CHUNK_DEFORM_SET);
  192. if (retval) {
  193. //
  194. // Write a chunk of information out for this set
  195. //
  196. MeshDeformSaveSetClass *set_save = m_DeformSets[set_index];
  197. W3dDeformSetInfo set_info = { 0 };
  198. set_info.KeyframeCount = set_save->Get_Keyframe_Count ();
  199. set_info.flags = set_save->Get_Flags ();
  200. retval &= (chunk_save.Write (&set_info, sizeof (set_info)) == sizeof (set_info));
  201. if (retval) {
  202. //
  203. // Export all the keyframes for this chunk
  204. //
  205. retval &= Export_Keyframes (chunk_save, *set_save);
  206. }
  207. retval &= chunk_save.End_Chunk ();
  208. }
  209. }
  210. // Return the true/false result code
  211. return retval;
  212. }
  213. ///////////////////////////////////////////////////////////////////////////
  214. //
  215. // Export_Keyframes
  216. //
  217. ///////////////////////////////////////////////////////////////////////////
  218. bool
  219. MeshDeformSaveClass::Export_Keyframes
  220. (
  221. ChunkSaveClass & chunk_save,
  222. MeshDeformSaveSetClass &set_save
  223. )
  224. {
  225. bool retval = true;
  226. //
  227. // Loop through all the keyframes in the set
  228. //
  229. int count = set_save.Get_Keyframe_Count ();
  230. for (int keyframe_index = 0; (keyframe_index < count) && retval; keyframe_index ++) {
  231. //
  232. // Write a chunk of information out for this keyframe
  233. //
  234. retval &= chunk_save.Begin_Chunk (W3D_CHUNK_DEFORM_KEYFRAME);
  235. if (retval) {
  236. W3dDeformKeyframeInfo keyframe_info = { 0 };
  237. keyframe_info.DeformPercent = set_save.Get_Deform_State (keyframe_index);
  238. keyframe_info.DataCount = set_save.Get_Deform_Data_Count (keyframe_index);
  239. retval &= (chunk_save.Write (&keyframe_info, sizeof (keyframe_info)) == sizeof (keyframe_info));
  240. if (retval) {
  241. //
  242. // Loop through all the verticies in this keyframe
  243. //
  244. int data_count = set_save.Get_Deform_Data_Count (keyframe_index);
  245. for (int index = 0; (index < data_count) && retval; index ++) {
  246. MeshDeformSaveSetClass::DEFORM_DATA &data = set_save.Get_Deform_Data (keyframe_index, index);
  247. //
  248. // Write a chunk of information out for this vertex
  249. //
  250. retval &= chunk_save.Begin_Chunk (W3D_CHUNK_DEFORM_DATA);
  251. if (retval) {
  252. W3dDeformData data_struct = { 0 };
  253. data_struct.VertexIndex = data.vert_index;
  254. data_struct.Position.X = data.position.x;
  255. data_struct.Position.Y = data.position.y;
  256. data_struct.Position.Z = data.position.z;
  257. data_struct.Color.R = data.color.x * 255;
  258. data_struct.Color.G = data.color.y * 255;
  259. data_struct.Color.B = data.color.z * 255;
  260. // If we are using vertex alpha instead of vertex color, then convert
  261. // the v-color into an alpha setting
  262. data_struct.Color.A = 255;
  263. if (m_AlphaPasses != 0) {
  264. data_struct.Color.A = (data_struct.Color.R + data_struct.Color.G + data_struct.Color.B) / 3.0F;
  265. }
  266. retval &= (chunk_save.Write (&data_struct, sizeof (data_struct)) == sizeof (data_struct));
  267. retval &= chunk_save.End_Chunk ();
  268. }
  269. }
  270. }
  271. retval &= chunk_save.End_Chunk ();
  272. }
  273. }
  274. // Return the true/false result code
  275. return retval;
  276. }
  277. ///////////////////////////////////////////////////////////////////////////
  278. //
  279. // Re_Index
  280. //
  281. ///////////////////////////////////////////////////////////////////////////
  282. /*void
  283. MeshDeformSaveClass::Re_Index (MeshBuilderClass &builder)
  284. {
  285. DynamicVectorClass<MeshDeformSaveSetClass::DEFORM_DATA> temp_list;
  286. //
  287. // Reindex each set of deform data
  288. //
  289. for (int set_index = 0; set_index < m_DeformSets.Count (); set_index ++) {
  290. MeshDeformSaveSetClass *set_save = m_DeformSets[set_index];
  291. //
  292. // Loop through all the deform entries in this set
  293. //
  294. for (int keyframe_index = 0; keyframe_index < set_save->Get_Keyframe_Count (); keyframe_index ++) {
  295. temp_list.Delete_All ();
  296. for (int index = 0; index < set_save->Get_Deform_Data_Count (keyframe_index); index ++) {
  297. MeshDeformSaveSetClass::DEFORM_DATA &data = set_save->Get_Deform_Data (keyframe_index, index);
  298. //
  299. // Now try to find the 'W3D' index of this vertex (its different than the max version).
  300. //
  301. //bool found = false;
  302. for (int vert_index = 0; vert_index < builder.Get_Vertex_Count (); vert_index++) {
  303. MeshBuilderClass::VertClass &vert = builder.Get_Vertex (vert_index);
  304. //
  305. // Reindex this vertex if its the one we are looking for.
  306. //
  307. if (vert.Id == (int)data.vert_index) {
  308. MeshDeformSaveSetClass::DEFORM_DATA new_data = data;
  309. new_data.vert_index = vert_index;
  310. temp_list.Add (new_data);
  311. //data.vert_index = vert_index;
  312. //found = true;
  313. }
  314. }
  315. }
  316. set_save->Replace_Deform_Data (keyframe_index, temp_list);
  317. }
  318. }
  319. return ;
  320. }*/
  321. ///////////////////////////////////////////////////////////////////////////
  322. //
  323. // Does_Deformer_Modify_DCG
  324. //
  325. ///////////////////////////////////////////////////////////////////////////
  326. bool
  327. MeshDeformSaveClass::Does_Deformer_Modify_DCG (void)
  328. {
  329. bool retval = false;
  330. //
  331. // Loop through all the sets
  332. //
  333. for (int set_index = 0; (set_index < m_DeformSets.Count ()) && !retval; set_index ++) {
  334. MeshDeformSaveSetClass *set_save = m_DeformSets[set_index];
  335. if (set_save) {
  336. //
  337. // Loop through all the keyframes in this set
  338. //
  339. int count = set_save->Get_Keyframe_Count ();
  340. for (int keyframe_index = 0; (keyframe_index < count) && !retval; keyframe_index ++) {
  341. //
  342. // Loop through all the entries in this keyframe
  343. //
  344. int data_count = set_save->Get_Deform_Data_Count (keyframe_index);
  345. for (int index = 0; (index < data_count) && !retval; index ++) {
  346. MeshDeformSaveSetClass::DEFORM_DATA &data = set_save->Get_Deform_Data (keyframe_index, index);
  347. //
  348. // If the color is not 'white' then we will
  349. // modify the DCG array.
  350. //
  351. if ((data.color.x != 1) ||
  352. (data.color.y != 1) ||
  353. (data.color.z != 1)) {
  354. retval = true;
  355. }
  356. }
  357. }
  358. }
  359. }
  360. // Return the true/false result code
  361. return retval;
  362. }