2013-10-23 17:08:09 +00:00
|
|
|
// 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/>.
|
|
|
|
|
|
|
|
#include "std_afx.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "nel/3d/particle_system.h"
|
|
|
|
#include "object_viewer.h"
|
|
|
|
#include "located_target_dlg.h"
|
|
|
|
#include "collision_zone_dlg.h"
|
|
|
|
#include "editable_range.h"
|
|
|
|
#include "attrib_dlg.h"
|
|
|
|
#include "direction_attr.h"
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// CLocatedTargetDlg dialog
|
|
|
|
|
|
|
|
|
|
|
|
CLocatedTargetDlg::CLocatedTargetDlg(CParticleWorkspace::CNode *ownerNode,
|
|
|
|
NL3D::CPSTargetLocatedBindable *lbTarget,
|
|
|
|
CParticleDlg *particleDlg) : _Node(ownerNode), _LBTarget(lbTarget), _ParticleDlg(particleDlg)
|
|
|
|
{
|
|
|
|
nlassert(particleDlg);
|
|
|
|
//{{AFX_DATA_INIT(CLocatedTargetDlg)
|
|
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
|
|
//}}AFX_DATA_INIT
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CLocatedTargetDlg::DoDataExchange(CDataExchange* pDX)
|
|
|
|
{
|
|
|
|
CDialog::DoDataExchange(pDX);
|
|
|
|
//{{AFX_DATA_MAP(CLocatedTargetDlg)
|
|
|
|
DDX_Control(pDX, IDC_AVAILABLE_TARGET, m_AvailableTargets);
|
|
|
|
DDX_Control(pDX, IDC_TARGET, m_Targets);
|
|
|
|
//}}AFX_DATA_MAP
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CLocatedTargetDlg, CDialog)
|
|
|
|
//{{AFX_MSG_MAP(CLocatedTargetDlg)
|
|
|
|
ON_BN_CLICKED(IDC_ADD_TARGET, OnAddTarget)
|
|
|
|
ON_BN_CLICKED(IDC_REMOVE_TARGET, OnRemoveTarget)
|
|
|
|
//}}AFX_MSG_MAP
|
|
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// CLocatedTargetDlg message handlers
|
|
|
|
|
|
|
|
|
|
|
|
void CLocatedTargetDlg::init(CWnd* pParent)
|
|
|
|
{
|
|
|
|
Create(IDD_LOCATED_TARGET_DLG, pParent);
|
|
|
|
ShowWindow(SW_SHOW);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CLocatedTargetDlg::OnAddTarget()
|
|
|
|
{
|
|
|
|
UpdateData();
|
|
|
|
int totalCount = m_AvailableTargets.GetCount();
|
|
|
|
nlassert(totalCount);
|
|
|
|
std::vector<int> indexs;
|
|
|
|
indexs.resize(totalCount);
|
|
|
|
int selCount = m_AvailableTargets.GetSelItems(totalCount, &indexs[0]);
|
|
|
|
|
|
|
|
std::sort(indexs.begin(), indexs.begin() + selCount); // we never know ...
|
|
|
|
|
|
|
|
// check that force isn't applied on a forever lasting object
|
|
|
|
if (dynamic_cast<NL3D::CPSForce *>(_LBTarget))
|
|
|
|
{
|
|
|
|
bool forEverLastingTarget = false;
|
|
|
|
for (int k = 0; k < selCount; ++k)
|
|
|
|
{
|
|
|
|
NL3D::CPSLocated *loc = (NL3D::CPSLocated *) m_AvailableTargets.GetItemData(indexs[k] - k);
|
|
|
|
nlassert(loc);
|
|
|
|
if (loc->getLastForever())
|
|
|
|
{
|
|
|
|
forEverLastingTarget = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (forEverLastingTarget)
|
|
|
|
{
|
|
|
|
CString warningStr;
|
|
|
|
CString messStr;
|
|
|
|
warningStr.LoadString(IDS_WARNING);
|
|
|
|
messStr.LoadString(IDS_FORCE_APPLIED_ON_OBJECT_THAT_LAST_FOREVER);
|
|
|
|
if (MessageBox((LPCTSTR) messStr, (LPCTSTR) warningStr, MB_OKCANCEL) != IDOK)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
|
|
for (int k = 0; k < selCount; ++k)
|
|
|
|
{
|
|
|
|
NL3D::CPSLocated *loc = (NL3D::CPSLocated *) m_AvailableTargets.GetItemData(indexs[k] - k);
|
|
|
|
nlassert(loc);
|
|
|
|
_LBTarget->attachTarget(loc);
|
|
|
|
m_AvailableTargets.DeleteString(indexs[k] - k);
|
|
|
|
int l = m_Targets.AddString(loc->getName().c_str());
|
|
|
|
m_Targets.SetItemData(l, (DWORD) loc);
|
|
|
|
}
|
|
|
|
UpdateData(FALSE);
|
|
|
|
//
|
|
|
|
updateModifiedFlag();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CLocatedTargetDlg::OnRemoveTarget()
|
|
|
|
{
|
|
|
|
UpdateData();
|
|
|
|
int totalCount = m_Targets.GetCount();
|
|
|
|
nlassert(totalCount);
|
|
|
|
std::vector<int> indexs;
|
|
|
|
indexs.resize(totalCount);
|
|
|
|
int selCount = m_Targets.GetSelItems(totalCount, &indexs[0]);
|
|
|
|
std::sort(indexs.begin(), indexs.begin() + selCount); // we never know ...
|
|
|
|
for (int k = 0; k < selCount; ++k)
|
|
|
|
{
|
|
|
|
NL3D::CPSLocated *loc = (NL3D::CPSLocated *) m_Targets.GetItemData(indexs[k] - k);
|
|
|
|
nlassert(loc);
|
|
|
|
_LBTarget->detachTarget(loc);
|
|
|
|
m_Targets.DeleteString(indexs[k] - k);
|
|
|
|
int l = m_AvailableTargets.AddString(loc->getName().c_str());
|
|
|
|
|
|
|
|
m_AvailableTargets.SetItemData(l, (DWORD) loc);
|
|
|
|
}
|
|
|
|
UpdateData(FALSE);
|
|
|
|
updateModifiedFlag();
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL CLocatedTargetDlg::OnInitDialog()
|
|
|
|
{
|
|
|
|
CDialog::OnInitDialog();
|
|
|
|
|
|
|
|
RECT r;
|
|
|
|
|
|
|
|
uint k;
|
|
|
|
uint nbTarg = _LBTarget->getNbTargets();
|
|
|
|
|
|
|
|
m_Targets.InitStorage(nbTarg, 128);
|
|
|
|
|
|
|
|
std::set<NL3D::CPSLocated *> targetSet;
|
|
|
|
|
|
|
|
// fill the box thta tells us what the target are
|
|
|
|
for(k = 0; k < nbTarg; ++k)
|
|
|
|
{
|
|
|
|
m_Targets.AddString(_LBTarget->getTarget(k)->getName().c_str() );
|
|
|
|
m_Targets.SetItemData(k, (DWORD) _LBTarget->getTarget(k) );
|
|
|
|
targetSet.insert(_LBTarget->getTarget(k));
|
|
|
|
};
|
|
|
|
|
|
|
|
// fill abox with the available targets
|
|
|
|
NL3D::CParticleSystem *ps = _LBTarget->getOwner()->getOwner();
|
|
|
|
|
|
|
|
uint nbLocated = ps->getNbProcess();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_AvailableTargets.InitStorage(nbTarg, 128);
|
|
|
|
for (k = 0; k < nbLocated; ++k)
|
|
|
|
{
|
|
|
|
NL3D::CPSLocated *loc = dynamic_cast<NL3D::CPSLocated *>(ps->getProcess(k));
|
|
|
|
if (loc)
|
|
|
|
{
|
|
|
|
if (targetSet.find(loc) == targetSet.end())
|
|
|
|
{
|
|
|
|
int l = m_AvailableTargets.AddString(loc->getName().c_str() );
|
|
|
|
m_AvailableTargets.SetItemData(l, (DWORD) loc );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const sint posX = 5;
|
|
|
|
sint posY = 180;
|
|
|
|
|
|
|
|
// collision zone case
|
|
|
|
|
|
|
|
if (dynamic_cast<NL3D::CPSZone *>(_LBTarget))
|
|
|
|
{
|
|
|
|
CCollisionZoneDlg *czd = new CCollisionZoneDlg(_Node, dynamic_cast<NL3D::CPSZone *>(_LBTarget), _ParticleDlg);
|
|
|
|
pushWnd(czd);
|
|
|
|
czd->init(posX, posY, this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// force with intensity case
|
|
|
|
|
|
|
|
if (dynamic_cast<NL3D::CPSForceIntensity *>(_LBTarget))
|
|
|
|
{
|
|
|
|
_ForceIntensityWrapper.F = dynamic_cast<NL3D::CPSForceIntensity *>(_LBTarget);
|
|
|
|
CAttribDlgFloat *fi = new CAttribDlgFloat(std::string("FORCE INTENSITY"), _Node, 0, 100);
|
|
|
|
pushWnd(fi);
|
|
|
|
fi->setWrapper(&_ForceIntensityWrapper);
|
|
|
|
fi->setSchemeWrapper(&_ForceIntensityWrapper);
|
|
|
|
|
|
|
|
HBITMAP bmh = LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_FORCE_INTENSITY));
|
|
|
|
fi->init(bmh, posX, posY, this);
|
|
|
|
|
|
|
|
|
|
|
|
fi->GetClientRect(&r);
|
|
|
|
posY += r.bottom + 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
// vortex (to tune viscosity)
|
|
|
|
if (dynamic_cast<NL3D::CPSCylindricVortex *>(_LBTarget))
|
|
|
|
{
|
|
|
|
CEditableRangeFloat *rv = new CEditableRangeFloat(std::string("RADIAL_VISCOSITY"), _Node, 0, 1);
|
|
|
|
pushWnd(rv);
|
|
|
|
_RadialViscosityWrapper.V = dynamic_cast<NL3D::CPSCylindricVortex *>(_LBTarget);
|
|
|
|
rv->setWrapper(&_RadialViscosityWrapper);
|
|
|
|
rv->init(posX + 140, posY, this);
|
|
|
|
CStatic *s = new CStatic;
|
|
|
|
pushWnd(s);
|
|
|
|
s->Create("Radial viscosity : ", SS_LEFT, CRect(posX, posY, posX + 139, posY + 32), this);
|
|
|
|
s->SetFont(CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)));
|
|
|
|
s->ShowWindow(SW_SHOW);
|
|
|
|
|
|
|
|
|
|
|
|
rv->GetClientRect(&r);
|
|
|
|
posY += r.bottom + 3;
|
|
|
|
|
|
|
|
CEditableRangeFloat *tv = new CEditableRangeFloat(std::string("TANGENTIAL_VISCOSITY"), _Node, 0, 1);
|
|
|
|
pushWnd(tv);
|
|
|
|
_TangentialViscosityWrapper.V = dynamic_cast<NL3D::CPSCylindricVortex *>(_LBTarget);
|
|
|
|
tv->setWrapper(&_TangentialViscosityWrapper);
|
|
|
|
tv->init(posX + 140, posY, this);
|
|
|
|
|
|
|
|
s = new CStatic;
|
|
|
|
pushWnd(s);
|
|
|
|
s->Create("Tangential Viscosity : ", SS_LEFT, CRect(posX, posY, posX + 139, posY + 32), this);
|
|
|
|
s->ShowWindow(SW_SHOW);
|
|
|
|
|
|
|
|
tv->GetClientRect(&r);
|
|
|
|
posY += r.bottom + 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
// deals with emitters that have a direction
|
|
|
|
if (dynamic_cast<NL3D::CPSDirection *>(_LBTarget))
|
|
|
|
{
|
|
|
|
CDirectionAttr *da = new CDirectionAttr(std::string("DIRECTION"));
|
|
|
|
pushWnd(da);
|
|
|
|
_DirectionWrapper.E = dynamic_cast<NL3D::CPSDirection *>(_LBTarget);
|
|
|
|
da->setWrapper(&_DirectionWrapper);
|
|
|
|
da->setDirectionWrapper(dynamic_cast<NL3D::CPSDirection *>(_LBTarget));
|
|
|
|
da->init(posX, posY, this);
|
|
|
|
da->GetClientRect(&r);
|
|
|
|
posY += r.bottom;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Brownian (to tune parametric factor)
|
|
|
|
if (dynamic_cast<NL3D::CPSBrownianForce *>(_LBTarget))
|
|
|
|
{
|
|
|
|
CEditableRangeFloat *rv = new CEditableRangeFloat(std::string("PARAMETRIC_FACTOR"), _Node, 0, 64);
|
|
|
|
pushWnd(rv);
|
|
|
|
_ParamFactorWrapper.F = static_cast<NL3D::CPSBrownianForce *>(_LBTarget);
|
|
|
|
rv->setWrapper(&_ParamFactorWrapper);
|
|
|
|
rv->init(posX + 140, posY, this);
|
|
|
|
CStatic *s = new CStatic;
|
|
|
|
pushWnd(s);
|
|
|
|
s->Create("Parametric factor : ", SS_LEFT, CRect(posX, posY, posX + 139, posY + 40), this);
|
|
|
|
s->SetFont(CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)));
|
|
|
|
s->ShowWindow(SW_SHOW);
|
|
|
|
|
|
|
|
rv->GetClientRect(&r);
|
|
|
|
posY += r.bottom + 3;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
|
|
}
|