340 lines
8.2 KiB
C++
340 lines
8.2 KiB
C++
/*
|
|
** 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
// 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);
|
|
}
|