/* ** Command & Conquer Generals Zero Hour(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** Confidential - Westwood Studios *** *********************************************************************************************** * * * Project Name : Commando / G 3D engine * * * * File Name : MeshDeformData.cpp * * * * Programmer : Patrick Smith * * * * Start Date : 04/26/99 * * * * Last Update : * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "MeshDeformData.H" #include "Util.H" #include "MeshDeformSaveDefs.H" /////////////////////////////////////////////////////////////////////////// // // ~MeshDeformModData // /////////////////////////////////////////////////////////////////////////// MeshDeformModData::~MeshDeformModData (void) { Free_Sets_List (); return ; } /////////////////////////////////////////////////////////////////////////// // // Record_Mesh_State // /////////////////////////////////////////////////////////////////////////// void MeshDeformModData::Record_Mesh_State (TriObject &tri_obj, float state, bool update_all) { // // Ask each set to update its state // for (int index = 0; index < m_SetsList.Count (); index ++) { if (index != m_CurrentSet) { if (update_all) { m_SetsList[index]->Set_State (state); } m_SetsList[index]->Update_Mesh (tri_obj); } } if (m_CurrentSet < m_SetsList.Count ()) { m_SetsList[m_CurrentSet]->Set_State (state); m_SetsList[m_CurrentSet]->Update_Mesh (tri_obj); } return ; } /////////////////////////////////////////////////////////////////////////// // // Free_Sets_List // /////////////////////////////////////////////////////////////////////////// void MeshDeformModData::Free_Sets_List (void) { // // Delete all the object pointers in the set list // for (int index = 0; index < m_SetsList.Count (); index ++) { MeshDeformSetClass *set = m_SetsList[index]; SAFE_DELETE (set); } // Remove all the entries from the list m_SetsList.Delete_All (); return ; } /////////////////////////////////////////////////////////////////////////// // // Set_Max_Deform_Sets // /////////////////////////////////////////////////////////////////////////// void MeshDeformModData::Set_Max_Deform_Sets (int max) { int current_max = m_SetsList.Count (); if (max > current_max) { // // Add the new sets to the list // int sets_to_add = max - current_max; for (int index = 0; index < sets_to_add; index ++) { MeshDeformSetClass *set = new MeshDeformSetClass; m_SetsList.Add (set); } } else if (max < current_max) { // // Remove the obsolete sets from the list // int sets_to_remove = current_max - max; for (int index = 0; index < sets_to_remove; index ++) { // Restore the set before we delete it Restore_Set (max); // Delete the set MeshDeformSetClass *set = m_SetsList[max]; SAFE_DELETE (set); m_SetsList.Delete (max); } } return ; } /////////////////////////////////////////////////////////////////////////// // // Restore_Set // /////////////////////////////////////////////////////////////////////////// void MeshDeformModData::Restore_Set (int set_index) { if (set_index == -1) { // Restore ALL the set for (int index = 0; index < m_SetsList.Count (); index ++) { m_SetsList[index]->Restore_Members (); } } else { m_SetsList[set_index]->Restore_Members (); } return ; } /////////////////////////////////////////////////////////////////////////// // // Save // /////////////////////////////////////////////////////////////////////////// IOResult MeshDeformModData::Save (ISave *save_obj) { DWORD bytes = 0L; save_obj->BeginChunk (DEFORM_CHUNK_INFO); // // Write the set count info to the chunk // DeformChunk info = { 0 }; info.SetCount = m_SetsList.Count (); IOResult result = save_obj->Write (&info, sizeof (info), &bytes); save_obj->EndChunk (); // // Now write a chunk for each set // for (int index = 0; (index < m_SetsList.Count ()) && (result == IO_OK); index ++) { result = m_SetsList[index]->Save (save_obj); } // Return IO_OK on success IO_ERROR on failure return result; } /////////////////////////////////////////////////////////////////////////// // // Load // /////////////////////////////////////////////////////////////////////////// IOResult MeshDeformModData::Load (ILoad *load_obj) { Free_Sets_List (); DWORD bytes = 0L; // // Is this the chunk we were expecting? // IOResult result = load_obj->OpenChunk (); if ( (result == IO_OK) && (load_obj->CurChunkID () == DEFORM_CHUNK_INFO)) { DeformChunk info = { 0 }; result = load_obj->Read (&info, sizeof (info), &bytes); load_obj->CloseChunk (); // // Read the set information from the chunk // for (unsigned int index = 0; (index < info.SetCount) && (result == IO_OK); index ++) { MeshDeformSetClass *set = new MeshDeformSetClass; m_SetsList.Add (set); result = set->Load (load_obj); } } // Return IO_OK on success IO_ERROR on failure return result; }