505 lines
15 KiB
C++
505 lines
15 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/>.
|
||
|
*/
|
||
|
|
||
|
// EditLODDialog.cpp : implementation file
|
||
|
//
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "W3DView.h"
|
||
|
#include "EditLODDialog.h"
|
||
|
#include "DistLod.H"
|
||
|
#include "Utils.H"
|
||
|
#include "RendObj.H"
|
||
|
#include "W3DViewDoc.H"
|
||
|
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#define new DEBUG_NEW
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Local Constants
|
||
|
//
|
||
|
const int COL_NAME = 0;
|
||
|
const int COL_SWITCH_UP = 1;
|
||
|
const int COL_SWITCH_DN = 2;
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CEditLODDialog
|
||
|
//
|
||
|
CEditLODDialog::CEditLODDialog(CWnd* pParent /*=NULL*/)
|
||
|
: m_spinIncrement (0.5F),
|
||
|
CDialog(CEditLODDialog::IDD, pParent)
|
||
|
{
|
||
|
//{{AFX_DATA_INIT(CEditLODDialog)
|
||
|
//}}AFX_DATA_INIT
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// DoDataExchange
|
||
|
//
|
||
|
void
|
||
|
CEditLODDialog::DoDataExchange (CDataExchange* pDX)
|
||
|
{
|
||
|
// Allow the base class to process this message
|
||
|
CDialog::DoDataExchange(pDX);
|
||
|
|
||
|
//{{AFX_DATA_MAP(CEditLODDialog)
|
||
|
DDX_Control(pDX, IDC_SWITCH_UP_SPIN, m_switchUpSpin);
|
||
|
DDX_Control(pDX, IDC_SWITCH_DN_SPIN, m_switchDownSpin);
|
||
|
DDX_Control(pDX, IDC_HIERARCHY_LIST, m_hierarchyListCtrl);
|
||
|
//}}AFX_DATA_MAP
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CEditLODDialog, CDialog)
|
||
|
//{{AFX_MSG_MAP(CEditLODDialog)
|
||
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SWITCH_UP_SPIN, OnDeltaposSwitchUpSpin)
|
||
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SWITCH_DN_SPIN, OnDeltaposSwitchDnSpin)
|
||
|
ON_NOTIFY(LVN_ITEMCHANGED, IDC_HIERARCHY_LIST, OnItemChangedHierarchyList)
|
||
|
ON_EN_UPDATE(IDC_SWITCH_DN_EDIT, OnUpdateSwitchDnEdit)
|
||
|
ON_EN_UPDATE(IDC_SWITCH_UP_EDIT, OnUpdateSwitchUpEdit)
|
||
|
ON_BN_CLICKED(IDC_RECALC, OnRecalc)
|
||
|
//}}AFX_MSG_MAP
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// OnInitDialog
|
||
|
//
|
||
|
BOOL
|
||
|
CEditLODDialog::OnInitDialog (void)
|
||
|
{
|
||
|
// Allow the base class to process this message
|
||
|
CDialog::OnInitDialog ();
|
||
|
|
||
|
// Center the dialog around the data tree view instead
|
||
|
// of the direct center of the screen
|
||
|
::CenterDialogAroundTreeView (m_hWnd);
|
||
|
|
||
|
// Get a pointer to the doc
|
||
|
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||
|
if (pCDoc)
|
||
|
{
|
||
|
// Get the current LOD from the doc
|
||
|
DistLODClass *pLOD = (DistLODClass *)pCDoc->GetDisplayedObject ();
|
||
|
ASSERT (pLOD);
|
||
|
if (pLOD)
|
||
|
{
|
||
|
int iSubObjects = pLOD->Get_Num_Sub_Objects ();
|
||
|
|
||
|
// Add the columns to the list control
|
||
|
m_hierarchyListCtrl.InsertColumn (COL_NAME, "Name");
|
||
|
m_hierarchyListCtrl.InsertColumn (COL_SWITCH_UP, "Switch Up");
|
||
|
m_hierarchyListCtrl.InsertColumn (COL_SWITCH_DN, "Switch Down");
|
||
|
|
||
|
RenderObjClass *pfirst_subobj = pLOD->Get_Sub_Object (0);
|
||
|
if (pfirst_subobj != NULL) {
|
||
|
m_spinIncrement = pfirst_subobj->Get_Bounding_Sphere ().Radius / 5.0F;
|
||
|
MEMBER_RELEASE (pfirst_subobj);
|
||
|
}
|
||
|
|
||
|
// Loop through all the subobjects
|
||
|
for (int iObject = 0;
|
||
|
(iObject < iSubObjects);
|
||
|
iObject ++)
|
||
|
{
|
||
|
// Get this subobject
|
||
|
RenderObjClass *pCSubObject = pLOD->Get_Sub_Object (iObject);
|
||
|
if (pCSubObject)
|
||
|
{
|
||
|
// Add this object to the list
|
||
|
int iIndex = m_hierarchyListCtrl.InsertItem (COL_NAME, pCSubObject->Get_Name ());
|
||
|
|
||
|
CString stringTemp;
|
||
|
stringTemp.Format ("%.2f", pLOD->Get_Switch_Up_Dist (iObject));
|
||
|
m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_UP, stringTemp);
|
||
|
|
||
|
stringTemp.Format ("%.2f", pLOD->Get_Switch_Down_Dist (iObject));
|
||
|
m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_DN, stringTemp);
|
||
|
|
||
|
// Free this object
|
||
|
MEMBER_RELEASE (pCSubObject);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_switchUpSpin.SetRange (-20, UD_MAXVAL-20);
|
||
|
m_switchDownSpin.SetRange (-20, UD_MAXVAL-20);
|
||
|
|
||
|
// Resize the columns so they are wide enough to display the largest string
|
||
|
m_hierarchyListCtrl.SetColumnWidth (COL_NAME, LVSCW_AUTOSIZE);
|
||
|
m_hierarchyListCtrl.SetColumnWidth (COL_SWITCH_UP, LVSCW_AUTOSIZE_USEHEADER);
|
||
|
m_hierarchyListCtrl.SetColumnWidth (COL_SWITCH_DN, LVSCW_AUTOSIZE_USEHEADER);
|
||
|
|
||
|
// Select the first item in the list
|
||
|
m_hierarchyListCtrl.SetItemState (0, LVIS_SELECTED, LVIS_SELECTED);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// OnOK
|
||
|
//
|
||
|
void
|
||
|
CEditLODDialog::OnOK (void)
|
||
|
{
|
||
|
|
||
|
// Get a pointer to the doc
|
||
|
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||
|
if (pCDoc)
|
||
|
{
|
||
|
// Get the current LOD from the doc
|
||
|
DistLODClass *pLOD = (DistLODClass *)pCDoc->GetDisplayedObject ();
|
||
|
ASSERT (pLOD);
|
||
|
if (pLOD)
|
||
|
{
|
||
|
int iSubObjects = pLOD->Get_Num_Sub_Objects ();
|
||
|
|
||
|
// Loop through all the subobjects and add them to the list control
|
||
|
for (int iObject = 0;
|
||
|
(iObject < iSubObjects);
|
||
|
iObject ++)
|
||
|
{
|
||
|
// Get the switch up distance from the list control
|
||
|
CString stringTemp = m_hierarchyListCtrl.GetItemText (iObject, COL_SWITCH_UP);
|
||
|
|
||
|
// Convert the string to a float and pass this value
|
||
|
// onto the LOD manager
|
||
|
float switchDistance = ::atof (stringTemp);
|
||
|
pLOD->Set_Switch_Up_Dist (iObject, switchDistance);
|
||
|
|
||
|
// Get the switch down distance from the list control
|
||
|
stringTemp = m_hierarchyListCtrl.GetItemText (iObject, COL_SWITCH_DN);
|
||
|
|
||
|
// Convert the string to a float and pass this value
|
||
|
// onto the LOD manager
|
||
|
switchDistance = ::atof (stringTemp);
|
||
|
pLOD->Set_Switch_Down_Dist (iObject, switchDistance);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Allow the base class to process this message
|
||
|
CDialog::OnOK ();
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// OnCancel
|
||
|
//
|
||
|
void
|
||
|
CEditLODDialog::OnCancel (void)
|
||
|
{
|
||
|
// Allow the base class to process this message
|
||
|
CDialog::OnCancel ();
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// OnDeltaposSwitchUpSpin
|
||
|
//
|
||
|
void
|
||
|
CEditLODDialog::OnDeltaposSwitchUpSpin
|
||
|
(
|
||
|
NMHDR* pNMHDR,
|
||
|
LRESULT* pResult
|
||
|
)
|
||
|
{
|
||
|
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
|
||
|
if (pNMUpDown)
|
||
|
{
|
||
|
float newVal = float(pNMUpDown->iPos) / 10.00F;
|
||
|
|
||
|
// Change the switching distance in the edit control
|
||
|
CString stringTemp;
|
||
|
stringTemp.Format ("%.2f", newVal);
|
||
|
SetDlgItemText (IDC_SWITCH_UP_EDIT, stringTemp);
|
||
|
|
||
|
// Find the selected item in the list control
|
||
|
int iIndex = m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
|
||
|
if (iIndex != -1)
|
||
|
{
|
||
|
// Change the switching distance in the list control
|
||
|
m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_UP, stringTemp);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*pResult = 0;
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// OnDeltaposSwitchDnSpin
|
||
|
//
|
||
|
void
|
||
|
CEditLODDialog::OnDeltaposSwitchDnSpin
|
||
|
(
|
||
|
NMHDR* pNMHDR,
|
||
|
LRESULT* pResult
|
||
|
)
|
||
|
{
|
||
|
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
|
||
|
if (pNMUpDown)
|
||
|
{
|
||
|
float newVal = float(pNMUpDown->iPos) / 10.00F;
|
||
|
|
||
|
// Change the switching distance in the edit control
|
||
|
CString stringTemp;
|
||
|
stringTemp.Format ("%.2f", newVal);
|
||
|
SetDlgItemText (IDC_SWITCH_DN_EDIT, stringTemp);
|
||
|
|
||
|
// Find the selected item in the list control
|
||
|
int iIndex = m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
|
||
|
if (iIndex != -1)
|
||
|
{
|
||
|
// Change the switching distance in the list control
|
||
|
m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_DN, stringTemp);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*pResult = 0;
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// OnItemChangedHierarchyList
|
||
|
//
|
||
|
void
|
||
|
CEditLODDialog::OnItemChangedHierarchyList
|
||
|
(
|
||
|
NMHDR* pNMHDR,
|
||
|
LRESULT* pResult
|
||
|
)
|
||
|
{
|
||
|
// Did the 'state' of the entry change?
|
||
|
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
|
||
|
if (pNMListView &&
|
||
|
(pNMListView->uChanged & LVIF_STATE) == LVIF_STATE)
|
||
|
{
|
||
|
|
||
|
if ((pNMListView->uNewState & LVIS_SELECTED) != LVIS_SELECTED)
|
||
|
{
|
||
|
// Is there a selected item in the list control?
|
||
|
if (m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED) == -1)
|
||
|
{
|
||
|
// Disabled the edit and spin controls
|
||
|
EnableControls (FALSE);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Enable the edit and spin controls
|
||
|
EnableControls (TRUE);
|
||
|
|
||
|
// Load the control with data for the selected item.
|
||
|
ResetControls (pNMListView->iItem);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*pResult = 0;
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// ResetControls
|
||
|
//
|
||
|
void
|
||
|
CEditLODDialog::ResetControls (int iIndex)
|
||
|
{
|
||
|
//
|
||
|
// Set the text of the group box
|
||
|
//
|
||
|
CString stringTemp = m_hierarchyListCtrl.GetItemText (iIndex, COL_NAME);
|
||
|
|
||
|
// Set the text of the group box
|
||
|
CString stringTitle;
|
||
|
stringTitle.Format ("Settings (%s)", (LPCTSTR)stringTemp);
|
||
|
SetDlgItemText (IDC_SETTINGS_GROUP, stringTitle);
|
||
|
|
||
|
//
|
||
|
// Reset the switch up controls
|
||
|
//
|
||
|
|
||
|
// Get the switch up distance from the list control
|
||
|
stringTemp = m_hierarchyListCtrl.GetItemText (iIndex, COL_SWITCH_UP);
|
||
|
|
||
|
// Set the text of the edit control to reflect the switching distance
|
||
|
SetDlgItemText (IDC_SWITCH_UP_EDIT, stringTemp);
|
||
|
|
||
|
// Set the current position of the spin control
|
||
|
float switchDistance = ::atof (stringTemp);
|
||
|
m_switchUpSpin.SetPos (int(switchDistance * 10.00F));
|
||
|
|
||
|
//
|
||
|
// Reset the switch down controls
|
||
|
//
|
||
|
|
||
|
// Get the switch down distance from the list control
|
||
|
stringTemp = m_hierarchyListCtrl.GetItemText (iIndex, COL_SWITCH_DN);
|
||
|
|
||
|
// Set the text of the edit control to reflect the switching distance
|
||
|
SetDlgItemText (IDC_SWITCH_DN_EDIT, stringTemp);
|
||
|
|
||
|
// Set the current position of the spin control
|
||
|
switchDistance = ::atof (stringTemp);
|
||
|
m_switchDownSpin.SetPos (int(switchDistance * 10.00F));
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// EnableControls
|
||
|
//
|
||
|
void
|
||
|
CEditLODDialog::EnableControls (BOOL bEnable)
|
||
|
{
|
||
|
// Enable or disable the windows
|
||
|
::EnableWindow (::GetDlgItem (m_hWnd, IDC_SETTINGS_GROUP), bEnable);
|
||
|
::EnableWindow (::GetDlgItem (m_hWnd, IDC_SWITCH_UP_SPIN), bEnable);
|
||
|
::EnableWindow (::GetDlgItem (m_hWnd, IDC_SWITCH_UP_EDIT), bEnable);
|
||
|
::EnableWindow (::GetDlgItem (m_hWnd, IDC_SWITCH_DN_SPIN), bEnable);
|
||
|
::EnableWindow (::GetDlgItem (m_hWnd, IDC_SWITCH_DN_EDIT), bEnable);
|
||
|
::EnableWindow (::GetDlgItem (m_hWnd, IDC_RECALC), bEnable);
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// OnUpdateSwitchDnEdit
|
||
|
//
|
||
|
void
|
||
|
CEditLODDialog::OnUpdateSwitchDnEdit (void)
|
||
|
{
|
||
|
// Get the switching distance from the edit control
|
||
|
CString stringTemp;
|
||
|
GetDlgItemText (IDC_SWITCH_DN_EDIT, stringTemp);
|
||
|
float newVal = ::atof (stringTemp);
|
||
|
|
||
|
// Change the switching distance in the spin control
|
||
|
m_switchDownSpin.SetPos (int(newVal * 10.00F));
|
||
|
|
||
|
// Find the selected item in the list control
|
||
|
int iIndex = m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
|
||
|
if (iIndex != -1)
|
||
|
{
|
||
|
// Change the switching distance in the list control
|
||
|
m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_DN, stringTemp);
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// OnUpdateSwitchUpEdit
|
||
|
//
|
||
|
void CEditLODDialog::OnUpdateSwitchUpEdit (void)
|
||
|
{
|
||
|
// Get the switching distance from the edit control
|
||
|
CString stringTemp;
|
||
|
GetDlgItemText (IDC_SWITCH_UP_EDIT, stringTemp);
|
||
|
float newVal = ::atof (stringTemp);
|
||
|
|
||
|
// Change the switching distance in the spin control
|
||
|
m_switchUpSpin.SetPos (int(newVal * 10.00F));
|
||
|
|
||
|
// Find the selected item in the list control
|
||
|
int iIndex = m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
|
||
|
if (iIndex != -1)
|
||
|
{
|
||
|
// Change the switching distance in the list control
|
||
|
m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_UP, stringTemp);
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// OnRecalc
|
||
|
//
|
||
|
void CEditLODDialog::OnRecalc (void)
|
||
|
{
|
||
|
// Get the up switching distance from the edit control
|
||
|
CString stringTemp;
|
||
|
GetDlgItemText (IDC_SWITCH_UP_EDIT, stringTemp);
|
||
|
float switchUp = ::atof (stringTemp);
|
||
|
|
||
|
// Get the down switching distance from the edit control
|
||
|
stringTemp;
|
||
|
GetDlgItemText (IDC_SWITCH_DN_EDIT, stringTemp);
|
||
|
float switchDown = ::atof (stringTemp);
|
||
|
|
||
|
if (switchUp < switchDown)
|
||
|
{
|
||
|
// Calculate the current range
|
||
|
float switchDelta = switchDown - switchUp;
|
||
|
float switchOverlap = switchDelta * 0.1F;
|
||
|
|
||
|
// Get a pointer to the doc
|
||
|
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||
|
if (pCDoc)
|
||
|
{
|
||
|
// Get the current LOD from the doc
|
||
|
DistLODClass *pLOD = (DistLODClass *)pCDoc->GetDisplayedObject ();
|
||
|
ASSERT (pLOD);
|
||
|
if (pLOD)
|
||
|
{
|
||
|
int iSubObjects = pLOD->Get_Num_Sub_Objects ();
|
||
|
switchUp = switchDown - switchOverlap;
|
||
|
|
||
|
// Loop through all the subobjects (following the highlighted one)
|
||
|
for (int iObject = m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED) + 1;
|
||
|
(iObject < iSubObjects);
|
||
|
iObject ++)
|
||
|
{
|
||
|
// Set the text of the switch up column
|
||
|
CString stringTemp;
|
||
|
stringTemp.Format ("%.2f", switchUp);
|
||
|
m_hierarchyListCtrl.SetItemText (iObject, COL_SWITCH_UP, stringTemp);
|
||
|
|
||
|
// Set the text of the switch dn column
|
||
|
stringTemp.Format ("%.2f", switchUp+switchDelta);
|
||
|
m_hierarchyListCtrl.SetItemText (iObject, COL_SWITCH_DN, stringTemp);
|
||
|
|
||
|
// Add the range to the switch up distance
|
||
|
switchUp += switchDelta-switchOverlap;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|