/* ** Command & Conquer Renegade(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 . */ // OpacityVectorDialog.cpp : implementation file // #include "stdafx.h" #include "w3dview.h" #include "OpacityVectorDialog.h" #include "wwmath.h" #include "vector3.h" #include "sphereobj.h" #include "ringobj.h" #include "colorbar.h" #include "euler.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // // OpacityVectorDialogClass // ///////////////////////////////////////////////////////////////////////////// OpacityVectorDialogClass::OpacityVectorDialogClass(CWnd* pParent /*=NULL*/) : m_OpacityBar (NULL), m_RenderObj (NULL), m_KeyIndex (0), CDialog(OpacityVectorDialogClass::IDD, pParent) { //{{AFX_DATA_INIT(OpacityVectorDialogClass) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT return ; } ///////////////////////////////////////////////////////////////////////////// // // DoDataExchange // ///////////////////////////////////////////////////////////////////////////// void OpacityVectorDialogClass::DoDataExchange (CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(OpacityVectorDialogClass) DDX_Control(pDX, IDC_SLIDER_Z, m_SliderZ); DDX_Control(pDX, IDC_SLIDER_Y, m_SliderY); //}}AFX_DATA_MAP return ; } BEGIN_MESSAGE_MAP(OpacityVectorDialogClass, CDialog) //{{AFX_MSG_MAP(OpacityVectorDialogClass) ON_WM_HSCROLL() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // // OnInitDialog // ///////////////////////////////////////////////////////////////////////////// BOOL OpacityVectorDialogClass::OnInitDialog (void) { CDialog::OnInitDialog(); m_OpacityBar = ColorBarClass::Get_Color_Bar (::GetDlgItem (m_hWnd, IDC_OPACITY_BAR)); ASSERT (m_OpacityBar); // // Setup the opacity bar // m_OpacityBar->Set_Range (0, 10); m_OpacityBar->Modify_Point (0, 0, 255, 255, 255); m_OpacityBar->Insert_Point (1, 10, 0, 0, 0); float value = ::atan (((m_Value.intensity / 10.0F) * 11.0F)) / DEG_TO_RAD (84.5) * 10.0F; m_OpacityBar->Set_Selection_Pos (value); // // Setup the sliders // m_SliderY.SetRange (0, 179); m_SliderZ.SetRange (0, 179); float log_test = ::log (8.0F); float log_test2 = ::_logb (log_test); float log_test3 = ::exp (log_test); // // Convert the normalized vector to Euler angles... // /*Vector3 dir_vector (m_Value.X, m_Value.Y, m_Value.Z); float x_rot = ::acos (dir_vector * Vector3 (1, 0, 0)); float y_rot = ::acos (dir_vector * Vector3 (0, 1, 0)); float z_rot = ::acos (dir_vector * Vector3 (0, 0, 1)); x_rot = RAD_TO_DEG (x_rot); y_rot = RAD_TO_DEG (y_rot); z_rot = RAD_TO_DEG (z_rot); x_rot = WWMath::Wrap (x_rot, -180, 180); y_rot = WWMath::Wrap (y_rot, -180, 180); z_rot = WWMath::Wrap (z_rot, -180, 180);*/ /*Matrix3D rot_90 (1); rot_90.Rotate_Z (DEG_TO_RADF (90)); Vector3 x_axis (m_Value.X, m_Value.Y, m_Value.Z); x_axis.Normalize (); Vector3 y_axis = rot_90 * x_axis; Vector3 z_axis; Vector3::Cross_Product (x_axis, y_axis, &z_axis); Matrix3D orientation (x_axis, y_axis, z_axis, Vector3 (0, 0, 0)); EulerAnglesClass euler_angle (orientation, EulerOrderXYZr); float x_rot = RAD_TO_DEG (euler_angle.Get_Angle (0)); float y_rot = RAD_TO_DEG (euler_angle.Get_Angle (1)); float z_rot = RAD_TO_DEG (euler_angle.Get_Angle (2)); x_rot = WWMath::Wrap (x_rot, 0, 360); y_rot = WWMath::Wrap (y_rot, 0, 360); z_rot = WWMath::Wrap (z_rot, 0, 360);*/ Matrix3D rotation = Build_Matrix3D (m_Value.angle); //Vector3 point = m_Value.angle.Rotate_Vector (Vector3 (1, 0, 0)); EulerAnglesClass euler_angle (rotation, EulerOrderXYZr); //float x_rot = RAD_TO_DEG (euler_angle.Get_Angle (0)); float y_rot = RAD_TO_DEG (euler_angle.Get_Angle (1)); float z_rot = RAD_TO_DEG (euler_angle.Get_Angle (2)); //float y_rot = RAD_TO_DEG (rotation.Get_Y_Rotation ()); //float z_rot = RAD_TO_DEG (rotation.Get_Z_Rotation ()); y_rot = WWMath::Wrap (y_rot, 0, 360); z_rot = WWMath::Wrap (z_rot, 0, 360); m_SliderY.SetPos ((int)y_rot); m_SliderZ.SetPos ((int)z_rot); return TRUE; } ///////////////////////////////////////////////////////////////////////////// // // OnOK // ///////////////////////////////////////////////////////////////////////////// void OpacityVectorDialogClass::OnOK (void) { m_Value = Update_Value (); CDialog::OnOK (); return ; } ///////////////////////////////////////////////////////////////////////////// // // Update_Object // ///////////////////////////////////////////////////////////////////////////// void OpacityVectorDialogClass::Update_Object (void) { Update_Object (Update_Value ()); return ; } ///////////////////////////////////////////////////////////////////////////// // // Update_Value // ///////////////////////////////////////////////////////////////////////////// AlphaVectorStruct OpacityVectorDialogClass::Update_Value (void) { AlphaVectorStruct value; int y_pos = m_SliderY.GetPos (); int z_pos = m_SliderZ.GetPos (); //float x_rot = DEG_TO_RADF ((float)x_pos); float y_rot = DEG_TO_RADF ((float)y_pos); float z_rot = DEG_TO_RADF ((float)z_pos); Matrix3 rot_mat (true); //rot_mat.Rotate_X (x_rot); rot_mat.Rotate_Y (y_rot); rot_mat.Rotate_Z (z_rot); value.angle = ::Build_Quaternion (rot_mat); float percent = ::tan ((m_OpacityBar->Get_Selection_Pos () / 10.0F) * DEG_TO_RAD (84.5)) / 11.0F; percent = min (1.0F, percent); percent = max (0.0F, percent); value.intensity = 10.0F * percent; return value; } ///////////////////////////////////////////////////////////////////////////// // // Update_Object // ///////////////////////////////////////////////////////////////////////////// void OpacityVectorDialogClass::Update_Object (const AlphaVectorStruct &value) { if (m_RenderObj != NULL) { // // Determine what type of object this is // switch (m_RenderObj->Class_ID ()) { case RenderObjClass::CLASSID_SPHERE: { // // Update the key with the new vector // SphereVectorChannelClass &vector_channel = ((SphereRenderObjClass *)m_RenderObj)->Get_Vector_Channel (); vector_channel.Set_Key_Value (m_KeyIndex, value); // // Force the animation to restart // ((SphereRenderObjClass *)m_RenderObj)->Restart_Animation (); } break; } } return ; } ///////////////////////////////////////////////////////////////////////////// // // OnCancel // ///////////////////////////////////////////////////////////////////////////// void OpacityVectorDialogClass::OnCancel (void) { Update_Object (m_Value); CDialog::OnCancel (); return ; } ///////////////////////////////////////////////////////////////////////////// // // OnHScroll // ///////////////////////////////////////////////////////////////////////////// void OpacityVectorDialogClass::OnHScroll ( UINT nSBCode, UINT nPos, CScrollBar * pScrollBar ) { // // Update the object // Update_Object (); CDialog::OnHScroll(nSBCode, nPos, pScrollBar); return ; } ///////////////////////////////////////////////////////////// // // OnNotify // ///////////////////////////////////////////////////////////// BOOL OpacityVectorDialogClass::OnNotify ( WPARAM wParam, LPARAM lParam, LRESULT *pResult ) { CBR_NMHDR *color_bar_hdr = (CBR_NMHDR *)lParam; // // Which control sent the notification? // switch (color_bar_hdr->hdr.idFrom) { case IDC_OPACITY_BAR: { // // Update the object // if (color_bar_hdr->hdr.code == CBRN_SEL_CHANGED) { Update_Object (); } } break; } return CDialog::OnNotify (wParam, lParam, pResult); }