// 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); }