khanat-opennel-code/code/nel/tools/3d/object_viewer/located_properties.cpp

353 lines
11 KiB
C++

// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// located_properties.cpp : implementation file
//
#include "std_afx.h"
#include "object_viewer.h"
#include "located_properties.h"
#include "particle_dlg.h"
#include "particle_tree_ctrl.h"
#include "attrib_dlg.h"
#include "lb_extern_id_dlg.h"
#include "object_viewer.h"
//
#include "nel/3d/ps_located.h"
#include "nel/3d/particle_system.h"
using NL3D::CPSLocated;
//****************************************************************************************************************
/////////////////////////////////////////////////////////////////////////////
// CLocatedProperties dialog
CLocatedProperties::CLocatedProperties(CParticleWorkspace::CNode *node, NL3D::CPSLocated *loc, CParticleDlg *pdlg)
: CDialog(CLocatedProperties::IDD, pdlg), _Node(node), _Located(loc), _ParticleDlg(pdlg), _MassDialog(NULL), _LifeDialog(NULL)
{
//{{AFX_DATA_INIT(CLocatedProperties)
m_LimitedLifeTime = FALSE;
m_MatrixMode = 0;
m_DisgradeWithLOD = FALSE;
m_ParametricIntegration = FALSE;
m_ParametricMotion = FALSE;
m_TriggerOnDeath = FALSE;
m_MatrixMode = -1;
//}}AFX_DATA_INIT
nlassert(pdlg->getObjectViewer());
pdlg->getObjectViewer()->registerMainLoopCallBack(this);
_MaxNbParticles = new CEditableRangeUInt("MAX_NB_PARTICLES", _Node, 1, 501);
_MaxNbParticles->enableUpperBound(30000, false);
}
//****************************************************************************************************************
CLocatedProperties::~CLocatedProperties()
{
nlassert(_ParticleDlg && _ParticleDlg->getObjectViewer());
_ParticleDlg->getObjectViewer()->removeMainLoopCallBack(this);
_MassDialog->DestroyWindow();
_LifeDialog->DestroyWindow();
_MaxNbParticles->DestroyWindow();
delete _LifeDialog;
delete _MassDialog;
delete _MaxNbParticles;
}
//****************************************************************************************************************
void CLocatedProperties::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CLocatedProperties)
DDX_Control(pDX, IDC_EDIT_TRIGGER_ON_DEATH, m_EditTriggerOnDeath);
DDX_Control(pDX, IDC_TRIGGER_ON_DEATH, m_TriggerOnDeathCtrl);
DDX_Control(pDX, IDC_PARAMETRIC_MOTION, m_ParametricMotionCtrl);
DDX_Control(pDX, IDC_PARTICLE_NUMBER_POS, m_MaxNbParticles);
DDX_Check(pDX, IDC_LIMITED_LIFE_TIME, m_LimitedLifeTime);
DDX_Check(pDX, IDC_DISGRADE_WITH_LOD, m_DisgradeWithLOD);
DDX_Check(pDX, IDC_PARAMETRIC_MOTION, m_ParametricMotion);
DDX_Check(pDX, IDC_TRIGGER_ON_DEATH, m_TriggerOnDeath);
DDX_CBIndex(pDX, IDC_MATRIX_MODE, m_MatrixMode);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CLocatedProperties, CDialog)
//{{AFX_MSG_MAP(CLocatedProperties)
ON_BN_CLICKED(IDC_LIMITED_LIFE_TIME, OnLimitedLifeTime)
ON_BN_CLICKED(IDC_DISGRADE_WITH_LOD, OnDisgradeWithLod)
ON_BN_CLICKED(IDC_PARAMETRIC_MOTION, OnParametricMotion)
ON_BN_CLICKED(IDC_EDIT_TRIGGER_ON_DEATH, OnEditTriggerOnDeath)
ON_BN_CLICKED(IDC_TRIGGER_ON_DEATH, OnTriggerOnDeath)
ON_BN_CLICKED(IDC_ASSIGN_COUNT, OnAssignCount)
ON_CBN_SELCHANGE(IDC_MATRIX_MODE, OnSelchangeMatrixMode)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//****************************************************************************************************************
/////////////////////////////////////////////////////////////////////////////
// CLocatedProperties message handlers
BOOL CLocatedProperties::OnInitDialog()
{
CDialog::OnInitDialog();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
///////////////////////////////////////////
//****************************************************************************************************************
void CLocatedProperties::init(uint32 x, uint32 y)
{
Create(IDD_LOCATED_PROPERTIES, (CWnd *) _ParticleDlg);
RECT r, pr;
GetClientRect(&r);
MoveWindow(x, y, r.right, r.bottom);
GetWindowRect(&pr);
const sint xPos = 0;
sint yPos = 100;
_LifeDialog = new CAttribDlgFloat("LIFETIME", _Node);
_LifeDialog->enableMemoryScheme(false);
_LifeWrapper.Located = _Located;
_LifeWrapper.Node = _Node;
_LifeWrapper.SSPS = _ParticleDlg->StartStopDlg;
_LifeDialog->setWrapper(&_LifeWrapper);
_LifeDialog->setSchemeWrapper(&_LifeWrapper);
HBITMAP bmh = LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_LIFE_TIME));
_LifeDialog->init(bmh, xPos, yPos, this);
_LifeDialog->GetClientRect(&r);
yPos += r.bottom + 3;
if (_Located->getLastForever())
{
_LifeDialog->EnableWindow(FALSE);
}
_MassDialog = new CAttribDlgFloat("PARTICLE_MASS", _Node, 0.001f, 10);
_MassDialog->enableLowerBound(0, true); // 0 is disallowed
_MassDialog->enableMemoryScheme(false);
_MassWrapper.Located = _Located;
_MassDialog->setWrapper(&_MassWrapper);
_MassDialog->setSchemeWrapper(&_MassWrapper);
bmh = LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_WEIGHT));
_MassDialog->init(bmh, xPos, yPos, this);
_MassDialog->GetClientRect(&r);
yPos += r.bottom + 3;
m_MaxNbParticles.GetWindowRect(&r);
_MaxNbParticlesWrapper.TreeCtrl = _ParticleDlg->ParticleTreeCtrl;
_MaxNbParticlesWrapper.Located = _Located;
_MaxNbParticlesWrapper.Node = _Node;
_MaxNbParticles->setWrapper(&_MaxNbParticlesWrapper);
_MaxNbParticles->init(r.left - pr.left, r.top - pr.top, this);
if (_Located->getOwner())
{
_MaxNbParticles->EnableWindow(_Located->getOwner()->getAutoCountFlag() ? FALSE : TRUE);
}
m_MatrixMode = (int) _Located->getMatrixMode();
m_LimitedLifeTime = _Located->getLastForever() ? FALSE : TRUE;
m_TriggerOnDeath = _Located->isTriggerOnDeathEnabled();
updateTriggerOnDeath();
m_DisgradeWithLOD = _Located->hasLODDegradation();
updateIntegrable();
updateTriggerOnDeath();
UpdateData(FALSE);
ShowWindow(SW_SHOW);
}
//****************************************************************************************************************
void CLocatedProperties::updateTriggerOnDeath(void)
{
nlassert(_Located);
BOOL enable = !_Located->getLastForever();
m_TriggerOnDeathCtrl.EnableWindow(enable);
m_EditTriggerOnDeath.EnableWindow(( (enable ? true : false /* MSVC6 warning */ )
&& _Located->isTriggerOnDeathEnabled())
);
}
//****************************************************************************************************************
void CLocatedProperties::updateIntegrable(void)
{
m_ParametricMotion = _Located->isParametricMotionEnabled();
m_ParametricMotionCtrl.EnableWindow(_Located->supportParametricMotion());
}
//****************************************************************************************************************
void CLocatedProperties::OnLimitedLifeTime()
{
UpdateData();
if (!m_LimitedLifeTime)
{
bool forceApplied = false;
// check that no force are applied on the located
std::vector<NL3D::CPSTargetLocatedBindable *> targeters;
_Located->getOwner()->getTargeters(_Located, targeters);
for(uint k = 0; k < targeters.size(); ++k)
{
if (targeters[k]->getType() == NL3D::PSForce)
{
forceApplied = true;
break;
}
}
if (forceApplied)
{
CString caption;
CString mess;
caption.LoadString(IDS_WARNING);
mess.LoadString(IDS_HAS_FORCE_APPLIED);
if (MessageBox((LPCTSTR) mess, (LPCTSTR) caption, MB_OKCANCEL) != IDOK)
{
m_LimitedLifeTime = true;
UpdateData(FALSE);
return;
}
}
if (_Located->setLastForever())
{
_LifeDialog->EnableWindow(FALSE);
}
else
{
CString mess;
mess.LoadString(IDS_PS_NO_FINITE_DURATION);
CString errorStr;
errorStr.LoadString(IDS_ERROR);
MessageBox((LPCTSTR) mess, (LPCTSTR) errorStr, MB_ICONEXCLAMATION);
m_LimitedLifeTime = TRUE;
UpdateData(FALSE);
}
}
else
{
_Located->setInitialLife(_Located->getInitialLife());
_LifeDialog->EnableWindow(TRUE);
}
updateTriggerOnDeath();
_ParticleDlg->StartStopDlg->resetAutoCount(_Node);
touchPSState();
}
//****************************************************************************************************************
void CLocatedProperties::OnDisgradeWithLod()
{
UpdateData();
_Located->forceLODDegradation(m_DisgradeWithLOD ? true : false /* to avoid warning from MSVC */);
touchPSState();
}
//****************************************************************************************************************
void CLocatedProperties::OnParametricMotion()
{
UpdateData();
_Located->enableParametricMotion(m_ParametricMotion ? true : false);
touchPSState();
}
//****************************************************************************************************************
void CLocatedProperties::OnEditTriggerOnDeath()
{
UpdateData();
CLBExternIDDlg dlg(_Located->getTriggerEmitterID());
INT_PTR res = dlg.DoModal();
if ( res == IDOK )
{
if (dlg.getNewID() != _Located->getTriggerEmitterID())
{
_Located->setTriggerEmitterID( dlg.getNewID() );
touchPSState();
}
}
}
//****************************************************************************************************************
void CLocatedProperties::OnTriggerOnDeath()
{
UpdateData();
_Located->enableTriggerOnDeath(m_TriggerOnDeath ? true : false /* MSVC6 wraning */);
updateTriggerOnDeath();
touchPSState();
}
//****************************************************************************************************************
void CLocatedProperties::goPostRender()
{
nlassert(_ParticleDlg);
if (_Located->getOwner()->getAutoCountFlag())
{
// update number of particle from ps
_MaxNbParticles->update();
}
// in all cases, show the current number of particles being used
GetDlgItem(IDC_CURR_NUM_PARTS)->SetWindowText(NLMISC::toString(_Located->getSize()).c_str());
}
//****************************************************************************************************************
void CLocatedProperties::OnAssignCount()
{
_Located->resize(_Located->getSize()); // set new max size
_MaxNbParticles->update();
touchPSState();
}
//****************************************************************************************************************
void CLocatedProperties::OnSelchangeMatrixMode()
{
UpdateData();
nlassert(_Located);
_Located->setMatrixMode((NL3D::TPSMatrixMode) m_MatrixMode);
updateIntegrable();
UpdateData(FALSE);
touchPSState();
}
//****************************************************************************************************************
void CLocatedProperties::touchPSState()
{
if (_Node) _Node->setModified(true);
}