/* ** 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 : MeshDeformPanel.cpp * * * * Programmer : Patrick Smith * * * * Start Date : 04/22/99 * * * * Last Update : * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "MeshDeformPanel.H" #include "Resource.H" #include "Util.H" #include "MeshDeform.H" /////////////////////////////////////////////////////////////////////////// // // Local constants // /////////////////////////////////////////////////////////////////////////// const char * const PANEL_OBJ_PROP = "WWPANELOBJ"; /////////////////////////////////////////////////////////////////////////// // // Message_Proc // /////////////////////////////////////////////////////////////////////////// BOOL WINAPI MeshDeformPanelClass::Message_Proc ( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) { // Lookup the controlling object for this panel MeshDeformPanelClass *panel_obj = MeshDeformPanelClass::Get_Object (hwnd); BOOL result = FALSE; switch (message) { // Create the controlling panel-object case WM_INITDIALOG: panel_obj = new MeshDeformPanelClass (hwnd); SetProp (hwnd, PANEL_OBJ_PROP, (HANDLE)panel_obj); break; case WM_DESTROY: result = panel_obj->On_Message (message, wparam, lparam); RemoveProp (hwnd, PANEL_OBJ_PROP); SAFE_DELETE (panel_obj); break; } // Pass the message onto the controlling panel-object if (panel_obj != NULL) { result = panel_obj->On_Message (message, wparam, lparam); } // Return the TRUE/FALSE result code return result; } /////////////////////////////////////////////////////////////////////////// // // Get_Object // /////////////////////////////////////////////////////////////////////////// MeshDeformPanelClass * MeshDeformPanelClass::Get_Object (HWND hwnd) { return (MeshDeformPanelClass *)::GetProp (hwnd, PANEL_OBJ_PROP); } /////////////////////////////////////////////////////////////////////////// // // On_Message // /////////////////////////////////////////////////////////////////////////// BOOL MeshDeformPanelClass::On_Message ( UINT message, WPARAM wparam, LPARAM lparam ) { switch (message) { case WM_INITDIALOG: m_pColorSwatch = ::GetIColorSwatch (::GetDlgItem (m_hWnd, IDC_VERTEX_COLOR), RGB (0, 0, 0), "Vertex Color"); m_pMaxSetsEdit = ::GetICustEdit (::GetDlgItem (m_hWnd, IDC_MAX_SETS_EDIT)); m_pMaxSetsSpin = ::GetISpinner (::GetDlgItem (m_hWnd, IDC_MAX_SETS_SPIN)); m_pLockSetsButton = ::GetICustButton (::GetDlgItem (m_hWnd, IDC_LOCK_SETS)); // // Setup the 'max-sets' controls // m_pMaxSetsSpin->LinkToEdit (::GetDlgItem (m_hWnd, IDC_MAX_SETS_EDIT), EDITTYPE_INT); m_pMaxSetsSpin->SetLimits (1, 20); m_pMaxSetsEdit->SetText (1); m_pMaxSetsSpin->SetValue (1, FALSE); ::SetDlgItemInt (m_hWnd, IDC_CURRENT_SET_STATIC, 1, FALSE); // // Setup the edit button // m_pLockSetsButton->SetType (CBT_CHECK); m_pLockSetsButton->SetCheck (FALSE); m_pLockSetsButton->SetHighlightColor (GREEN_WASH); //m_pEditButton->SetType (CBT_CHECK); //m_pEditButton->SetCheck (FALSE); //m_pEditButton->SetHighlightColor (GREEN_WASH); // // Setup the sliders // ::SendDlgItemMessage (m_hWnd, IDC_CURRENT_SET_SLIDER, TBM_SETRANGE, (WPARAM)TRUE, MAKELONG (1, 1)); ::SendDlgItemMessage (m_hWnd, IDC_CURRENT_SET_SLIDER, TBM_SETPOS, (WPARAM)TRUE, 0L); ::SendDlgItemMessage (m_hWnd, IDC_STATE_SLIDER, TBM_SETRANGE, (WPARAM)FALSE, MAKELONG (0, 10)); ::SendDlgItemMessage (m_hWnd, IDC_STATE_SLIDER, TBM_SETPOS, (WPARAM)FALSE, 9L); // // Ensure the sliders are repainted // //::InvalidateRect (::GetDlgItem (m_hWnd, IDC_STATE_SLIDER), NULL, TRUE); //::InvalidateRect (::GetDlgItem (m_hWnd, IDC_CURRENT_SET_SLIDER), NULL, TRUE); break; case WM_DESTROY: ::ReleaseIColorSwatch (m_pColorSwatch); ::ReleaseICustEdit (m_pMaxSetsEdit); ::ReleaseISpinner (m_pMaxSetsSpin); //::ReleaseICustButton (m_pEditButton); m_pColorSwatch = NULL; m_pMaxSetsEdit = NULL; m_pMaxSetsSpin = NULL; //m_pEditButton = NULL; break; case WM_COMMAND: On_Command (wparam, lparam); break; case CC_COLOR_CHANGE: { // Pass the new color onto the mesh deformer COLORREF color_ref = m_pColorSwatch->GetColor (); VertColor color; color.x = GetRValue (color_ref) / 255.0F; color.y = GetGValue (color_ref) / 255.0F; color.z = GetBValue (color_ref) / 255.0F; m_pMeshDeformer->Set_Vertex_Color (color, HIWORD (wparam) != 0); } break; case WM_CUSTEDIT_ENTER: case CC_SPINNER_CHANGE: { Set_Max_Sets (m_pMaxSetsEdit->GetInt (), true); } break; case WM_HSCROLL: if ((HWND)lparam == ::GetDlgItem (m_hWnd, IDC_CURRENT_SET_SLIDER)) { int pos = ::SendDlgItemMessage (m_hWnd, IDC_CURRENT_SET_SLIDER, TBM_GETPOS, 0, 0L); Set_Current_Set (pos - 1, true); } else { int pos = ::SendDlgItemMessage (m_hWnd, IDC_STATE_SLIDER, TBM_GETPOS, 0, 0L); m_pMeshDeformer->Set_Deform_State (((float)pos) / 10.0F); if (pos > 0) { m_pColorSwatch->Enable (); } else { m_pColorSwatch->Disable (); } } break; } return FALSE; } /////////////////////////////////////////////////////////////////////////// // // On_Command // /////////////////////////////////////////////////////////////////////////// void MeshDeformPanelClass::On_Command ( WPARAM wparam, LPARAM lparam ) { switch (LOWORD (wparam)) { case IDC_MANUALAPPLY: { m_pMeshDeformer->Auto_Apply (Get_Auto_Apply_Check ()); } break; //case IDC_EDIT_BUTTON: /*if (m_pEditButton->IsChecked ()) { ::SendDlgItemMessage (m_hWnd, IDC_STATE_SLIDER, TBM_SETPOS, (WPARAM)TRUE, 100L); ::EnableWindow (::GetDlgItem (m_hWnd, IDC_STATE_SLIDER), FALSE); m_pColorSwatch->Enable (); m_pMeshDeformer->Set_Deform_State (1.0F); } else { ::EnableWindow (::GetDlgItem (m_hWnd, IDC_STATE_SLIDER), TRUE); m_pColorSwatch->Disable (); }*/ //break; case IDC_MAX_SETS_EDIT: break; } return ; } /////////////////////////////////////////////////////////////////////////// // // Set_Deformer // /////////////////////////////////////////////////////////////////////////// void MeshDeformPanelClass::Set_Deformer (MeshDeformClass *obj) { if (m_pMeshDeformer != obj) { m_pMeshDeformer = obj; // Set the slider position based on the current state of the deformer float state = m_pMeshDeformer->Get_Deform_State (); ::SendDlgItemMessage (m_hWnd, IDC_STATE_SLIDER, TBM_SETPOS, (WPARAM)TRUE, LPARAM(state * 10.0F)); // Now update the current vertex color Update_Vertex_Color (); } return ; } /////////////////////////////////////////////////////////////////////////// // // Update_Vertex_Color // /////////////////////////////////////////////////////////////////////////// void MeshDeformPanelClass::Update_Vertex_Color (void) { if (m_pMeshDeformer != NULL) { // Update the color swatch with data from the deformer Point3 color; m_pMeshDeformer->Get_Vertex_Color (color); m_pColorSwatch->SetColor (RGB (int(color.x * 255.0F), int(color.y * 255.0F), int(color.z * 255.0F)), FALSE); } return ; } /////////////////////////////////////////////////////////////////////////// // // Set_Max_Sets // /////////////////////////////////////////////////////////////////////////// void MeshDeformPanelClass::Set_Max_Sets ( int max, bool notify ) { // Update the UI ::SendDlgItemMessage (m_hWnd, IDC_CURRENT_SET_SLIDER, TBM_SETRANGE, (WPARAM)TRUE, MAKELONG (1, max)); ::SetDlgItemInt (m_hWnd, IDC_CURRENT_SET_STATIC, max, TRUE); if (notify == false) { m_pMaxSetsSpin->SetValue (max, TRUE); } else if (m_pMeshDeformer != NULL) { // Update the deformer m_pMeshDeformer->Set_Max_Deform_Sets (max); } return ; } /////////////////////////////////////////////////////////////////////////// // // Set_Current_Set // /////////////////////////////////////////////////////////////////////////// void MeshDeformPanelClass::Set_Current_Set ( int set, bool notify ) { // Update the UI ::SetDlgItemInt (m_hWnd, IDC_CURRENT_SET_STATIC, set + 1, TRUE); if (notify == false) { ::SendDlgItemMessage (m_hWnd, IDC_CURRENT_SET_SLIDER, TBM_SETPOS, (WPARAM)TRUE, set + 1); } else if (m_pMeshDeformer != NULL) { // Update the deformer m_pMeshDeformer->Set_Current_Set (set, true); } return ; } /////////////////////////////////////////////////////////////////////////// // // Set_Current_State // /////////////////////////////////////////////////////////////////////////// void MeshDeformPanelClass::Set_Current_State (float state) { ::SendDlgItemMessage (m_hWnd, IDC_STATE_SLIDER, TBM_SETPOS, (WPARAM)TRUE, LPARAM(state * 10.0F)); return ; }