6f1197d633
HG : Enter commit message. Lines beginning with 'HG:' are removed.
353 lines
11 KiB
C++
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(utf8ToTStr(NLMISC::toString(_Located->getSize())));
|
|
}
|
|
|
|
//****************************************************************************************************************
|
|
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);
|
|
}
|
|
|
|
|