khanat-opennel-code/code/nel/tools/3d/object_viewer/attrib_dlg.cpp
2017-03-15 20:29:34 +01:00

1648 lines
52 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/>.
// attrib_dlg.cpp : implementation file
//
#include "std_afx.h"
#include "object_viewer.h"
#include "attrib_dlg.h"
#include "editable_range.h"
#include "color_edit.h"
#include "basis_edit.h"
#include "value_blender_dlg.h"
#include "value_gradient_dlg.h"
#include "value_from_emitter_dlg.h"
#include "bin_op_dlg.h"
#include "edit_user_param.h"
#include "edit_spinner.h"
#include "edit_follow_path.h"
#include "scheme_bank_dlg.h"
#include "scheme_manager.h"
#include "choose_name.h"
#include "curve_edit.h"
#include "nel/3d/ps_attrib_maker.h"
#include "nel/3d/ps_float.h"
#include "nel/3d/ps_int.h"
#include "nel/3d/ps_color.h"
#include "nel/3d/ps_plane_basis.h"
#include "nel/3d/ps_plane_basis_maker.h"
/*static char trace_buf[200];
#define NL_TRACE sprintf(trace_buf, "%d", __LINE__); \
::MessageBox(NULL, trace_buf, NULL, MB_OK);
*/
/////////////////////////////////////////////////////////////////////
// WRAPPERS to set / retrieve the NbCycles parameter of a scheme //
/////////////////////////////////////////////////////////////////////
static float NbCyclesReader(void *lParam) { return ((CAttribDlg *) lParam)->getSchemeNbCycles(); }
static void NbCyclesWriter(float value, void *lParam) { ((CAttribDlg *) lParam)->setSchemeNbCycles(value); }
///////////////////////////////////////////
// GENERAL INTERFACE FOR BLENDER EDITION //
///////////////////////////////////////////
/** T is the type to be edited (color, float, etc..),
* even if it is unused
*/
template <typename T>
class CValueBlenderDlgClientT : public IValueBlenderDlgClient
{
public:
std::string Id; // the Id of each of the dialog (it will be followed by %1 or %2)
// must be filled by the user
// the scheme being used. Must be set by the user
NL3D::CPSValueBlendFuncBase<T> *SchemeFunc;
protected:
virtual CEditAttribDlg *createDialog(uint index, CParticleWorkspace::CNode *ownerNode)
{
std::string id = Id;
if (index == 0) id += "%1"; else id += "%2";
_ValueInfos[index].ValueIndex = index;
_ValueInfos[index].SchemeFunc = SchemeFunc;
_ValueInfos[index].OwnerNode = ownerNode;
return newDialog(id, &_ValueInfos[index]);
}
// construct a dialog with the given wrapper and id
virtual CEditAttribDlg *newDialog(const std::string &id, IPSWrapper<T> *wrapper) = 0;
// inherited from IPSWrapper<T>
struct COneValueInfo : public IPSWrapper<T>
{
// value 0 or 1 being edited
uint ValueIndex;
// the scheme being edited
NL3D::CPSValueBlendFuncBase<T> *SchemeFunc;
virtual T get(void) const
{
T t1, t2;
SchemeFunc->getValues(t1, t2);
return ValueIndex == 0 ? t1 : t2;
}
virtual void set(const T &value)
{
T t1, t2;
SchemeFunc->getValues(t1, t2);
if (ValueIndex == 0 ) t1 = value; else t2 = value;
SchemeFunc->setValues(t1, t2);
}
};
COneValueInfo _ValueInfos[2];
};
////////////////////////////////////////////
// GENERAL INTERFACE FOR GRADIENT EDITION //
////////////////////////////////////////////
/** This template generate an interface that is used with the gradient edition dialog
* T is the type to be edited (color, floet, etc..)
*/
template <typename T>
class CValueGradientDlgClientT : public IValueGradientDlgClient, public IPSWrapper<T>
{
public:
std::string Id; // the Id of each of the dialog (it will be followed by %1 or %2)
// must be filled by the user
// the gradient being edited, must be filled by the instancier
NL3D::CPSValueGradientFunc<T> *Scheme;
// the gradient dialog, must be filled by the instancier
CValueGradientDlg *GradDlg;
// the difault value for new values creation. Must be filled by the instancier
T DefaultValue;
/// a function that can display a value in a gradient, with the given offset. Deriver must define this
virtual void displayValue(CDC *dc, uint index, sint x, sint y) = 0;
/// inherited from IPSWrapper
virtual T get(void) const { return Scheme->getValue(_CurrentEditedIndex); }
virtual void set(const T &v)
{
T *tab = new T[Scheme->getNumValues()];
Scheme->getValues(tab);
tab[_CurrentEditedIndex] = v;
Scheme->setValues(tab, Scheme->getNumValues(), Scheme->getNumStages());
delete[] tab;
GradDlg->invalidateGrad();
}
/** must provide a dialog for the edition of one value (only ONE exist at a time)
* \param index the index of the value in the dialog
* \grad the dlg that called this method (deriver can ask a redraw then)
*/
virtual CEditAttribDlg *createDialog(uint index, CValueGradientDlg *grad, CParticleWorkspace::CNode *ownerNode)
{
OwnerNode = ownerNode;
_CurrentEditedIndex = index;
return newDialog(Id, this);
}
/// create a new dialog with given id and wrapper
virtual CEditAttribDlg *newDialog(const std::string &id, IPSWrapper<T> *wrapper) = 0;
/// a function that can add, remove, or insert a new element in the gradient
virtual void modifyGradient(TAction action, uint index)
{
T *tab = new T[Scheme->getNumValues() + 1]; // +1 is for the add / insert case
Scheme->getValues(tab);
switch(action)
{
case IValueGradientDlgClient::Add:
tab[Scheme->getNumValues()] = DefaultValue;
Scheme->setValues(tab, Scheme->getNumValues() + 1, Scheme->getNumStages());
break;
case IValueGradientDlgClient::Insert:
::memmove(tab + (index + 1), tab + index, sizeof(T) * (Scheme->getNumValues() - index));
tab[index] = DefaultValue;
Scheme->setValues(tab, Scheme->getNumValues() + 1, Scheme->getNumStages());
break;
case IValueGradientDlgClient::Delete:
::memmove(tab + index, tab + index + 1, sizeof(T) * (Scheme->getNumValues() - index - 1));
Scheme->setValues(tab, Scheme->getNumValues() - 1, Scheme->getNumStages());
break;
case IValueGradientDlgClient::Up:
nlassert(index > 0);
std::swap(tab[index], tab[index - 1]);
Scheme->setValues(tab, Scheme->getNumValues(), Scheme->getNumStages());
break;
case IValueGradientDlgClient::Down:
nlassert(index < Scheme->getNumValues() - 1);
std::swap(tab[index], tab[index + 1]);
Scheme->setValues(tab, Scheme->getNumValues(), Scheme->getNumStages());
break;
}
delete[] tab;
}
virtual uint32 getSchemeSize(void) const { return Scheme->getNumValues(); }
// get the number of interpolation step
uint32 getNbSteps(void) const
{
return Scheme->getNumStages();
}
// set the number of interpolation steps
void setNbSteps(uint32 value)
{
Scheme->setNumStages(value);
}
protected:
// index of the value OF the current dialog that exist
uint32 _CurrentEditedIndex;
};
/////////////////////////////////////////////////////////////////////////////
// CAttribDlg dialog
//*************************************************************************************************************
CAttribDlg::CAttribDlg(const std::string &valueID, CParticleWorkspace::CNode *ownerNode, bool enableConstantValue /* = true*/)
: _CstValueDlg(NULL),
_Node(ownerNode),
_FirstDrawing(true),
_EnableConstantValue(enableConstantValue),
_DisableMemoryScheme(false),
_SchemeEditionDlg(NULL),
_NbCycleEnabled(true),
_NbCyclesDlg(NULL),
_ValueID(valueID),
_SrcInputEnabled(true)
{
//{{AFX_DATA_INIT(CAttribDlg)
m_AttribName = _T("");
m_Clamp = FALSE;
//}}AFX_DATA_INIT
}
//*************************************************************************************************************
void CAttribDlg::closeEditWindow()
{
childPopupClosed(NULL);
}
//*************************************************************************************************************
BOOL CAttribDlg::EnableWindow( BOOL bEnable)
{
if (_CstValueDlg)
{
_CstValueDlg->EnableWindow(bEnable);
}
if (_NbCyclesDlg)
{
_NbCyclesDlg->EnableWindow(bEnable);
}
m_UseScheme.EnableWindow(bEnable);
m_AttrBitmap.EnableWindow(bEnable);
if (useScheme())
{
m_Scheme.EnableWindow(bEnable);
m_SchemeInput.EnableWindow(hasSchemeCustomInput() ? bEnable : FALSE);
m_EditScheme.EnableWindow(bEnable);
m_GetScheme.EnableWindow(bEnable);
m_PutScheme.EnableWindow(bEnable);
m_ClampCtrl.EnableWindow(bEnable);
}
else
{
m_ClampCtrl.EnableWindow(FALSE);
}
UpdateData(FALSE);
return CDialog::EnableWindow(bEnable);
}
//*************************************************************************************************************
CAttribDlg::~CAttribDlg()
{
if (_NbCyclesDlg)
{
_NbCyclesDlg->DestroyWindow();
delete _NbCyclesDlg;
}
if (_CstValueDlg)
{
_CstValueDlg->DestroyWindow();
delete _CstValueDlg;
}
}
//*************************************************************************************************************
void CAttribDlg::update()
{
_FirstDrawing = true;
if (useScheme())
{
schemeValueUpdate();
}
else
{
nlassert(_EnableConstantValue);
cstValueUpdate();
}
}
//*************************************************************************************************************
void CAttribDlg::init(HBITMAP bitmap, sint x, sint y, CWnd *pParent)
{
Create(IDD_ATTRIB_DLG, pParent);
RECT r, ro;
GetClientRect(&r);
m_AttrBitmap.SendMessage(BM_SETIMAGE, IMAGE_BITMAP, (LPARAM) bitmap);
MoveWindow(x, y, r.right, r.bottom);
m_NbCyclePos.GetWindowRect(&r);
GetWindowRect(&ro);
if (_NbCycleEnabled)
{
_NbCyclesDlg = new CEditableRangeFloat(_ValueID + "%%NB_CYCLE_INFO", _Node, 0.1f, 10.1f);
_NbCyclesDlg->init(r.left - ro.left, r.top - ro.top, this);
}
// fill the combo box with the list of available scheme
m_Scheme.InitStorage(getNumScheme(), 32); // 32 char per string pre-allocated
for (uint k = 0; k < getNumScheme(); ++k)
{
m_Scheme.InsertString(k, getSchemeName(k).c_str());
}
update();
if (!_EnableConstantValue)
{
m_UseScheme.ShowWindow(SW_HIDE);
}
if (!_NbCyclesDlg)
{
GetDlgItem(IDC_INPUT_MULTIPLIER_TXT)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_CLAMP_ATTRIB)->ShowWindow(SW_HIDE);
}
if (!_SrcInputEnabled)
{
GetDlgItem(IDC_SRC_INPUT_TXT)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_EDIT_INPUT)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_SCHEME_INPUT)->ShowWindow(SW_HIDE);
}
inputValueUpdate();
ShowWindow(SW_SHOW);
}
//*************************************************************************************************************
void CAttribDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAttribDlg)
DDX_Control(pDX, IDC_PUT_SCHEME, m_PutScheme);
DDX_Control(pDX, IDC_GET_SCHEME, m_GetScheme);
DDX_Control(pDX, IDC_EDIT_INPUT, m_EditUserParam);
DDX_Control(pDX, IDC_SCHEME_INPUT, m_SchemeInput);
DDX_Control(pDX, IDC_CONSTANT_VALUE_POS, m_CstValuePos);
DDX_Control(pDX, IDC_ATTRIB_NB_CYCLES, m_NbCyclePos);
DDX_Control(pDX, IDC_ATTR_BITMAP, m_AttrBitmap);
DDX_Control(pDX, IDC_CLAMP_ATTRIB, m_ClampCtrl);
DDX_Control(pDX, IDC_EDIT_SCHEME, m_EditScheme);
DDX_Control(pDX, IDC_USE_SCHEME, m_UseScheme);
DDX_Control(pDX, IDC_SCHEME, m_Scheme);
DDX_Check(pDX, IDC_CLAMP_ATTRIB, m_Clamp);
//}}AFX_DATA_MAP
}
//*************************************************************************************************************
void CAttribDlg::inputValueUpdate(void)
{
if (useScheme() && getSchemeInput().InputType == NL3D::CPSInputType::attrUserParam)
{
m_EditUserParam.EnableWindow(TRUE);
}
else
{
m_EditUserParam.EnableWindow(FALSE);
}
}
//*************************************************************************************************************
void CAttribDlg::cstValueUpdate()
{
if (!_FirstDrawing && !useScheme()) return;
m_ClampCtrl.EnableWindow(FALSE);
if (_NbCyclesDlg)
{
_NbCyclesDlg->EnableWindow(FALSE);
_NbCyclesDlg->emptyDialog();
}
GetDlgItem(IDC_INPUT_MULTIPLIER_TXT)->EnableWindow(FALSE);
m_EditScheme.EnableWindow(FALSE);
m_PutScheme.EnableWindow(FALSE);
m_GetScheme.EnableWindow(FALSE);
m_EditScheme.ShowWindow(SW_HIDE);
m_GetScheme.ShowWindow(SW_HIDE);
m_PutScheme.ShowWindow(SW_HIDE);
m_Scheme.EnableWindow(FALSE);
m_Scheme.ShowWindow(SW_HIDE);
m_SchemeInput.EnableWindow(FALSE);
m_SchemeInput.ShowWindow(SW_HIDE);
if (!_FirstDrawing) resetCstValue();
m_UseScheme.SetCurSel(0);
_CstValueDlg = createConstantValueDlg();
CRect r, ro;
m_CstValuePos.GetWindowRect(&r);
GetWindowRect(&ro);
_CstValueDlg->init(r.left - ro.left, r.top - ro.top, this);
UpdateData(FALSE);
_FirstDrawing = false;
}
//*************************************************************************************************************
void CAttribDlg::schemeValueUpdate()
{
//if (!_FirstDrawing && useScheme()) return;
if (_CstValueDlg)
{
_CstValueDlg->DestroyWindow();
delete _CstValueDlg;
_CstValueDlg = NULL;
}
m_EditScheme.EnableWindow(TRUE);
m_GetScheme.EnableWindow(TRUE);
m_PutScheme.EnableWindow(TRUE);
m_EditScheme.ShowWindow(SW_SHOW);
m_GetScheme.ShowWindow(SW_SHOW);
m_PutScheme.ShowWindow(SW_SHOW);
m_Scheme.EnableWindow(TRUE);
m_Scheme.ShowWindow(SW_SHOW);
m_SchemeInput.EnableWindow(TRUE);
m_SchemeInput.ShowWindow(SW_SHOW);
m_UseScheme.SetCurSel(1);
sint k = getCurrentScheme();
if (k == -1) // unknow scheme ...
{
setCurrentScheme(0);
k = 0;
}
m_Scheme.SetCurSel(k);
if (hasSchemeCustomInput())
{
m_SchemeInput.EnableWindow();
m_SchemeInput.SetCurSel((uint) getSchemeInput().InputType);
inputValueUpdate();
if (_NbCyclesDlg)
{
_NbCyclesDlg->EnableWindow(TRUE);
}
m_ClampCtrl.EnableWindow(isClampingSupported());
GetDlgItem(IDC_INPUT_MULTIPLIER_TXT)->EnableWindow(isClampingSupported());
}
else
{
m_SchemeInput.EnableWindow(FALSE);
m_SchemeInput.SetCurSel(0);
if (_NbCyclesDlg)
{
_NbCyclesDlg->EnableWindow(FALSE);
}
m_ClampCtrl.EnableWindow(FALSE);
GetDlgItem(IDC_INPUT_MULTIPLIER_TXT)->EnableWindow(FALSE);
}
if (_NbCyclesDlg)
{
_NbCyclesWrapper.OwnerNode = _Node;
_NbCyclesDlg->setWrapper(&_NbCyclesWrapper);
_NbCyclesWrapper.Dlg = this;
_NbCyclesDlg->updateRange();
_NbCyclesDlg->updateValueFromReader();
}
if (isClampingSupported())
{
m_Clamp = isSchemeClamped();
}
UpdateData(FALSE);
_FirstDrawing = false;
}
//*************************************************************************************************************
void CAttribDlg::OnSelchangeUseScheme()
{
if (m_UseScheme.GetCurSel() == 0)
{
cstValueUpdate();
}
else
{
schemeValueUpdate();
}
}
//*************************************************************************************************************
void CAttribDlg::OnSelchangeScheme()
{
UpdateData();
setCurrentScheme(m_Scheme.GetCurSel());
schemeValueUpdate();
}
//*************************************************************************************************************
void CAttribDlg::OnEditScheme()
{
_SchemeEditionDlg = editScheme();
if (_SchemeEditionDlg)
{
EnableWindow(FALSE);
}
}
//*************************************************************************************************************
void CAttribDlg::childPopupClosed(CWnd *child)
{
EnableWindow(TRUE);
if (!_SchemeEditionDlg) return;
_SchemeEditionDlg->DestroyWindow();
delete _SchemeEditionDlg;
_SchemeEditionDlg = NULL;
}
//*************************************************************************************************************
void CAttribDlg::OnGetScheme()
{
CSchemeBankDlg sbd(getCurrentSchemePtr()->getType(), this);
if (sbd.DoModal() == IDOK && sbd.getSelectedScheme())
{
setCurrentSchemePtr(sbd.getSelectedScheme()->clone());
_FirstDrawing = true;
schemeValueUpdate();
}
}
//*************************************************************************************************************
void CAttribDlg::OnPutScheme()
{
CChooseName cn("new scheme", this);
if (cn.DoModal() == IDOK)
{
SchemeManager.insertScheme(cn.getName(), getCurrentSchemePtr()->clone());
}
}
//*************************************************************************************************************
void CAttribDlg::OnSelchangeSchemeInput()
{
UpdateData();
NL3D::CPSInputType it;
it.InputType = (NL3D::CPSInputType::TInputType) m_SchemeInput.GetCurSel();
if (it.InputType == NL3D::CPSInputType::attrUserParam)
{
it.UserParamNum = 0;
}
setSchemeInput(it);
inputValueUpdate();
}
//*************************************************************************************************************
void CAttribDlg::OnClampAttrib()
{
UpdateData();
clampScheme(m_Clamp ? true : false /* avoid performance warning */);
}
//*************************************************************************************************************
void CAttribDlg::OnEditInput()
{
switch (getSchemeInput().InputType)
{
case NL3D::CPSInputType::attrUserParam:
{
CEditUserParam ep(getSchemeInput().UserParamNum);
if (ep.DoModal() == IDOK)
{
NL3D::CPSInputType it = getSchemeInput();
it.UserParamNum = ep.getUserParamIndex();
setSchemeInput(it);
}
}
break;
}
}
BEGIN_MESSAGE_MAP(CAttribDlg, CDialog)
//{{AFX_MSG_MAP(CAttribDlg)
ON_CBN_SELCHANGE(IDC_USE_SCHEME, OnSelchangeUseScheme)
ON_CBN_SELCHANGE(IDC_SCHEME, OnSelchangeScheme)
ON_BN_CLICKED(IDC_EDIT_SCHEME, OnEditScheme)
ON_CBN_SELCHANGE(IDC_SCHEME_INPUT, OnSelchangeSchemeInput)
ON_BN_CLICKED(IDC_CLAMP_ATTRIB, OnClampAttrib)
ON_BN_CLICKED(IDC_EDIT_INPUT, OnEditInput)
ON_BN_CLICKED(IDC_GET_SCHEME, OnGetScheme)
ON_BN_CLICKED(IDC_PUT_SCHEME, OnPutScheme)
ON_WM_DESTROY()
ON_WM_CLOSE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAttribDlg message handlers
////////////////////////////////////
// CAttribDlgFloat implementation //
////////////////////////////////////
//////////////////////////////////////////////////////////
// FLOAT BLENDER EDITION INTERFACE //
//////////////////////////////////////////////////////////
class CFloatBlenderDlgClient : public CValueBlenderDlgClientT<float>
{
public:
CEditAttribDlg *newDialog(const std::string &id, IPSWrapperFloat *wrapper)
{
CEditableRangeFloat *erf = new CEditableRangeFloat(id, wrapper->OwnerNode, MinRange, MaxRange);
erf->setWrapper(wrapper);
BoundChecker.duplicateBoundChecker(*erf);
return erf;
}
CBoundCheckerFloat BoundChecker;
float MinRange, MaxRange;
};
//////////////////////////////////////////////////////////
// FLOAT GRADIENT EDITION INTERFACE //
//////////////////////////////////////////////////////////
//*************************************************************************************************************
class CFloatGradientDlgWrapper : public CValueGradientDlgClientT<float>
{
public:
/// a function that can display a value in a gradient, with the given offset. Deriver must define this
void displayValue(CDC *dc, uint index, sint x, sint y)
{
CString out;
out.Format("%g", Scheme->getValue(index) );
dc->TextOut(x + 10, y + 4, out);
}
CEditAttribDlg *newDialog(const std::string &id, IPSWrapperFloat *wrapper)
{
CEditableRangeFloat *erf = new CEditableRangeFloat(id, wrapper->OwnerNode, MinRange, MaxRange);
erf->setWrapper(wrapper);
BoundChecker.duplicateBoundChecker(*erf);
return erf;
}
CBoundCheckerFloat BoundChecker;
float MinRange, MaxRange;
};
//*************************************************************************************************************
CAttribDlgFloat::CAttribDlgFloat(const std::string &valueID, CParticleWorkspace::CNode *node, float minRange, float maxRange)
: CAttribDlgT<float>(valueID, node), _MinRange(minRange), _MaxRange(maxRange)
{
_CstValueId = valueID;
}
//*************************************************************************************************************
CEditAttribDlg *CAttribDlgFloat::createConstantValueDlg()
{
CEditableRangeFloat *erf = new CEditableRangeFloat(_CstValueId, _Node, _MinRange, _MaxRange);
erf->setWrapper(_Wrapper);
duplicateBoundChecker(*erf);
return erf;
}
//*************************************************************************************************************
uint CAttribDlgFloat::getNumScheme(void) const
{
return _DisableMemoryScheme ? 3 : 5;
}
//*************************************************************************************************************
std::string CAttribDlgFloat::getSchemeName(uint index) const
{
const char *types[] = { "value blender", "values gradient", "curve", "value computed from emitter", "binary operator"};
nlassert(index < 5);
return std::string(types[index]);
}
//*************************************************************************************************************
CWnd *CAttribDlgFloat::editScheme(void)
{
NL3D::CPSAttribMaker<float> *scheme = _SchemeWrapper->getScheme();
if (dynamic_cast<NL3D::CPSFloatBlender *>(scheme))
{
CFloatBlenderDlgClient *myInterface = new CFloatBlenderDlgClient;
this->duplicateBoundChecker(myInterface->BoundChecker);
myInterface->MinRange = _MinRange;
myInterface->MaxRange = _MaxRange;
myInterface->Id = _CstValueId+ std::string("%%FLOAT_BLENDER");
myInterface->SchemeFunc = & ((NL3D::CPSValueBlenderSample<float, 64> *) scheme)->_F;
CValueBlenderDlg *vb = new CValueBlenderDlg(myInterface, true, this, this, _Node);
vb->init(this);
return vb;
}
if (dynamic_cast<NL3D::CPSFloatGradient *>(scheme))
{
CFloatGradientDlgWrapper *wrapper = new CFloatGradientDlgWrapper;
this->duplicateBoundChecker(wrapper->BoundChecker);
wrapper->MinRange = _MinRange;
wrapper->MaxRange = _MaxRange;
wrapper->Scheme = &(((NL3D::CPSFloatGradient *) (_SchemeWrapper->getScheme()) )->_F);
CValueGradientDlg *gd = new CValueGradientDlg(wrapper, _Node, true, this, this);
wrapper->GradDlg = gd;
wrapper->DefaultValue = 0.f;
wrapper->Id = _CstValueId+ std::string("%%FLOAT GRADIENT");
gd->init(this);
return gd;
}
if (dynamic_cast<NL3D::CPSFloatMemory *>(scheme))
{
CAttribDlgFloat *adf = new CAttribDlgFloat(_CstValueId, _Node, _MinRange, _MaxRange);
this->duplicateBoundChecker(*adf);
CValueFromEmitterDlgT<float> *vfe = new CValueFromEmitterDlgT<float>( (NL3D::CPSFloatMemory *)(scheme),
adf,
this,
m_AttrBitmap.GetBitmap()
);
vfe->init(this);
return vfe;
}
if (dynamic_cast<NL3D::CPSFloatBinOp *>(scheme))
{
CAttribDlgFloat *ad[2] = { NULL, NULL};
for (uint k = 0; k <2; ++k)
{
ad[k] = new CAttribDlgFloat(_CstValueId, _Node, _MinRange, _MaxRange);
this->duplicateBoundChecker(*ad[k]);
}
CBinOpDlgT<float> *bod = new CBinOpDlgT<float>( (NL3D::CPSFloatBinOp *)(scheme),
(CAttribDlgT<float> **) ad,
this,
m_AttrBitmap.GetBitmap());
bod->init(this);
return bod;
}
if (dynamic_cast<NL3D::CPSFloatCurve *>(scheme))
{
CurveEdit *ce = new CurveEdit(&(dynamic_cast<NL3D::CPSFloatCurve *>(scheme)->_F), _Node, this, this);
ce->init(this);
return ce;
}
return NULL;
}
//*************************************************************************************************************
sint CAttribDlgFloat::getCurrentScheme(void) const
{
const NL3D::CPSAttribMaker<float> *scheme = _SchemeWrapper->getScheme();
if (dynamic_cast<const NL3D::CPSFloatBlender *>(scheme)) return 0;
if (dynamic_cast<const NL3D::CPSFloatGradient *>(scheme)) return 1;
if (dynamic_cast<const NL3D::CPSFloatCurve *>(scheme)) return 2;
if (dynamic_cast<const NL3D::CPSFloatMemory *>(scheme)) return 3;
if (dynamic_cast<const NL3D::CPSFloatBinOp *>(scheme)) return 4;
return -1;
}
//*************************************************************************************************************
void CAttribDlgFloat::setCurrentScheme(uint index)
{
nlassert(index < 5);
NL3D::CPSAttribMaker<float> *scheme = NULL;
switch (index)
{
case 0:
scheme = new NL3D::CPSFloatBlender(_MinRange, _MaxRange);
break;
case 1:
{
static const float values[2] = { 0.1f, 1.f };
scheme = new NL3D::CPSFloatGradient(values, 2, 16, 1.f);
}
break;
case 2:
{
NL3D::CPSFloatCurve *curve = new NL3D::CPSFloatCurve;
curve->_F.setNumSamples(128);
curve->_F.addControlPoint(NL3D::CPSFloatCurveFunctor::CCtrlPoint(0, 0.5f));
curve->_F.addControlPoint(NL3D::CPSFloatCurveFunctor::CCtrlPoint(1, 0.5f));
scheme = curve;
}
break;
case 3:
scheme = new NL3D::CPSFloatMemory;
((NL3D::CPSAttribMakerMemory<float> *) scheme)->setScheme(new NL3D::CPSFloatBlender(_MinRange, _MaxRange));
break;
case 4 :
scheme = new NL3D::CPSFloatBinOp;
((NL3D::CPSFloatBinOp *) scheme)->setArg(0, new NL3D::CPSFloatBlender);
((NL3D::CPSFloatBinOp *) scheme)->setArg(1, new NL3D::CPSFloatBlender);
break;
default:
break;
}
if (scheme)
{
_SchemeWrapper->setSchemeAndUpdateModifiedFlag(scheme);
}
}
////////////////////////////////////
// CAttribDlgUInt implementation //
////////////////////////////////////
class CUIntBlenderDlgClient : public CValueBlenderDlgClientT<uint32>
{
public:
CEditAttribDlg *newDialog(const std::string &id, IPSWrapperUInt *wrapper)
{
CEditableRangeUInt *eru = new CEditableRangeUInt(id, wrapper->OwnerNode, MinRange, MaxRange);
eru->setWrapper(wrapper);
BoundChecker.duplicateBoundChecker(*eru);
return eru;
}
CBoundCheckerUInt BoundChecker;
uint32 MinRange, MaxRange;
};
//////////////////////////////////////////////////////////
// UINT GRADIENT EDITION INTERFACE //
//////////////////////////////////////////////////////////
//*************************************************************************************************************
class CUIntGradientDlgWrapper : public CValueGradientDlgClientT<uint32>
{
public:
/// a function that can display a value in a gradient, with the given offset. Deriver must define this
void displayValue(CDC *dc, uint index, sint x, sint y)
{
CString out;
out.Format("%d", Scheme->getValue(index) );
dc->TextOut(x + 10, y + 4, out);
}
CEditAttribDlg *newDialog(const std::string &id, IPSWrapperUInt *wrapper)
{
CEditableRangeUInt *eru = new CEditableRangeUInt(id, wrapper->OwnerNode, MinRange, MaxRange);
eru->setWrapper(wrapper);
BoundChecker.duplicateBoundChecker(*eru);
return eru;
}
CBoundCheckerUInt BoundChecker;
uint32 MinRange, MaxRange;
};
//*************************************************************************************************************
CAttribDlgUInt::CAttribDlgUInt(const std::string &valueID, CParticleWorkspace::CNode *node, uint32 minRange, uint32 maxRange)
: CAttribDlgT<uint32>(valueID, node), _MinRange(minRange), _MaxRange(maxRange)
{
_CstValueId = valueID;
}
//*************************************************************************************************************
CEditAttribDlg *CAttribDlgUInt::createConstantValueDlg()
{
CEditableRangeUInt *erf = new CEditableRangeUInt(_CstValueId, _Node, _MinRange, _MaxRange);
erf->setWrapper(_Wrapper);
duplicateBoundChecker(*erf);
return erf;
}
//*************************************************************************************************************
uint CAttribDlgUInt::getNumScheme(void) const
{
return _DisableMemoryScheme ? 2 : 4;
}
//*************************************************************************************************************
std::string CAttribDlgUInt::getSchemeName(uint index) const
{
const char *types[] = { "value blender", "values gradient", "values computed from emitter", "binary operator" };
nlassert(index < 4);
return std::string(types[index]);
}
//*************************************************************************************************************
CWnd *CAttribDlgUInt::editScheme(void)
{
const NL3D::CPSAttribMaker<uint32> *scheme = _SchemeWrapper->getScheme();
if (dynamic_cast<const NL3D::CPSUIntBlender *>(scheme))
{
CUIntBlenderDlgClient *myInterface = new CUIntBlenderDlgClient ;
duplicateBoundChecker(myInterface->BoundChecker);
myInterface->MinRange = _MinRange;
myInterface->MaxRange = _MaxRange;
myInterface->Id = _CstValueId+ std::string("%%UINT_BLENDER");
myInterface->SchemeFunc = & ((NL3D::CPSValueBlenderSample<uint32, 64> *) scheme)->_F;
CValueBlenderDlg *vb = new CValueBlenderDlg(myInterface, true, this, this, _Node);
vb->init(this);
return vb;
}
if (dynamic_cast<const NL3D::CPSUIntGradient *>(scheme))
{
CUIntGradientDlgWrapper *wrapper = new CUIntGradientDlgWrapper;
this->duplicateBoundChecker(wrapper->BoundChecker);
wrapper->MinRange = _MinRange;
wrapper->MaxRange = _MaxRange;
wrapper->Scheme = &(((NL3D::CPSUIntGradient *) (_SchemeWrapper->getScheme()) )->_F);
CValueGradientDlg *gd = new CValueGradientDlg(wrapper, _Node, true, this, this);
wrapper->GradDlg = gd;
wrapper->DefaultValue = 0;
wrapper->Id = _CstValueId+ std::string("%%UINT GRADIENT");
gd->init(this);
return gd;
}
if (dynamic_cast<const NL3D::CPSUIntMemory *>(scheme))
{
CAttribDlgUInt *adu = new CAttribDlgUInt(_CstValueId, _Node, _MinRange, _MaxRange);
this->duplicateBoundChecker(*adu);
CValueFromEmitterDlgT<uint32> *vfe = new CValueFromEmitterDlgT<uint32>( (NL3D::CPSUIntMemory *)(scheme),
adu,
this,
m_AttrBitmap.GetBitmap());
vfe->init(this);
return vfe;
}
if (dynamic_cast<const NL3D::CPSUIntBinOp *>(scheme))
{
CAttribDlgUInt *ad[2] = { NULL, NULL};
for (uint k = 0; k <2; ++k)
{
ad[k] = new CAttribDlgUInt(_CstValueId, _Node, _MinRange, _MaxRange);
this->duplicateBoundChecker(*ad[k]);
}
CBinOpDlgT<uint32> *bod = new CBinOpDlgT<uint32>( (NL3D::CPSUIntBinOp *)(scheme),
(CAttribDlgT<uint32> **) ad,
this,
m_AttrBitmap.GetBitmap());
bod->init(this);
return bod;
}
return NULL;
}
//*************************************************************************************************************
sint CAttribDlgUInt::getCurrentScheme(void) const
{
const NL3D::CPSAttribMaker<uint32> *scheme = _SchemeWrapper->getScheme();
if (dynamic_cast<const NL3D::CPSUIntBlender *>(scheme)) return 0;
if (dynamic_cast<const NL3D::CPSUIntGradient *>(scheme)) return 1;
if (dynamic_cast<const NL3D::CPSUIntMemory *>(scheme)) return 2;
if (dynamic_cast<const NL3D::CPSUIntBinOp *>(scheme)) return 3;
return -1;
}
//*************************************************************************************************************
void CAttribDlgUInt::setCurrentScheme(uint index)
{
nlassert(index < 4);
NL3D::CPSAttribMaker<uint32> *scheme = NULL;
switch (index)
{
case 0 :
scheme = new NL3D::CPSUIntBlender(_MinRange, _MaxRange);
break;
case 1 :
scheme = new NL3D::CPSUIntGradient;
break;
case 2 :
scheme = new NL3D::CPSUIntMemory;
((NL3D::CPSAttribMakerMemory<uint32> *) scheme)->setScheme(new NL3D::CPSUIntBlender(_MinRange, _MaxRange) );
break;
case 3 :
scheme = new NL3D::CPSUIntBinOp;
((NL3D::CPSUIntBinOp *) scheme)->setArg(0, new NL3D::CPSUIntBlender);
((NL3D::CPSUIntBinOp *) scheme)->setArg(1, new NL3D::CPSUIntBlender);
break;
default:
break;
}
if (scheme)
{
_SchemeWrapper->setSchemeAndUpdateModifiedFlag(scheme);
}
}
////////////////////////////////////
// CAttribDlgInt implementation //
////////////////////////////////////
class CIntBlenderDlgClient : public CValueBlenderDlgClientT<sint32>
{
public:
CEditAttribDlg *newDialog(const std::string &id, IPSWrapper<sint32> *wrapper)
{
CEditableRangeInt *eri = new CEditableRangeInt(id, wrapper->OwnerNode, MinRange, MaxRange);
eri->setWrapper(wrapper);
BoundChecker.duplicateBoundChecker(*eri);
return eri;
}
CBoundCheckerInt BoundChecker;
sint32 MinRange, MaxRange;
};
//////////////////////////////////////////////////////////
// INT GRADIENT EDITION INTERFACE //
//////////////////////////////////////////////////////////
//*************************************************************************************************************
class CIntGradientDlgWrapper : public CValueGradientDlgClientT<sint32>
{
public:
/// a function that can display a value in a gradient, with the given offset. Deriver must define this
void displayValue(CDC *dc, uint index, sint x, sint y)
{
CString out;
out.Format("%d", Scheme->getValue(index) );
dc->TextOut(x + 10, y + 4, out);
}
CEditAttribDlg *newDialog(const std::string &id, IPSWrapper<sint32> *wrapper)
{
CEditableRangeInt *eri = new CEditableRangeInt(id, wrapper->OwnerNode, MinRange, MaxRange);
eri->setWrapper(wrapper);
BoundChecker.duplicateBoundChecker(*eri);
return eri;
}
CBoundCheckerInt BoundChecker;
sint32 MinRange, MaxRange;
};
//*************************************************************************************************************
CAttribDlgInt::CAttribDlgInt(const std::string &valueID, CParticleWorkspace::CNode *node, sint32 minRange, sint32 maxRange)
: CAttribDlgT<sint32>(valueID, node), _MinRange(minRange), _MaxRange(maxRange)
{
_CstValueId = valueID;
}
//*************************************************************************************************************
CEditAttribDlg *CAttribDlgInt::createConstantValueDlg()
{
CEditableRangeInt *erf = new CEditableRangeInt(_CstValueId, _Node, _MinRange, _MaxRange);
erf->setWrapper(_Wrapper);
duplicateBoundChecker(*erf);
return erf;
}
//*************************************************************************************************************
uint CAttribDlgInt::getNumScheme(void) const
{
return _DisableMemoryScheme ? 2 : 4;
}
//*************************************************************************************************************
std::string CAttribDlgInt::getSchemeName(uint index) const
{
const char *types[] = { "value exact blender", "values gradient", "values computed from emitter", "binary operator" };
nlassert(index < 4);
return std::string(types[index]);
}
//*************************************************************************************************************
CWnd *CAttribDlgInt::editScheme(void)
{
const NL3D::CPSAttribMaker<sint32> *scheme = _SchemeWrapper->getScheme();
if (dynamic_cast<const NL3D::CPSIntBlender *>(scheme))
{
CIntBlenderDlgClient *myInterface = new CIntBlenderDlgClient;
this->duplicateBoundChecker(myInterface->BoundChecker);
myInterface->MinRange = _MinRange;
myInterface->MaxRange = _MaxRange;
myInterface->Id = _CstValueId+ std::string("%%INT_BLENDER");
myInterface->SchemeFunc = & ((NL3D::CPSValueBlenderSample<sint32, 64> *) scheme)->_F;
CValueBlenderDlg *vb = new CValueBlenderDlg(myInterface, true, this, this, _Node);
vb->init(this);
return vb;
}
if (dynamic_cast<const NL3D::CPSIntGradient *>(scheme))
{
CIntGradientDlgWrapper *wrapper = new CIntGradientDlgWrapper;
this->duplicateBoundChecker(wrapper->BoundChecker);
wrapper->MinRange = _MinRange;
wrapper->MaxRange = _MaxRange;
wrapper->Scheme = &(((NL3D::CPSIntGradient *) (_SchemeWrapper->getScheme()) )->_F);
CValueGradientDlg *gd = new CValueGradientDlg(wrapper, _Node, true, this, this);
wrapper->GradDlg = gd;
wrapper->DefaultValue = 0;
wrapper->Id = _CstValueId+ std::string("%%INT GRADIENT");
gd->init(this);
return gd;
}
if (dynamic_cast<const NL3D::CPSIntMemory *>(scheme))
{
CAttribDlgInt *adi = new CAttribDlgInt(_CstValueId, _Node, _MinRange, _MaxRange);
this->duplicateBoundChecker(*adi);
CValueFromEmitterDlgT<sint32> *vfe = new CValueFromEmitterDlgT<sint32>((NL3D::CPSIntMemory *) _SchemeWrapper->getScheme(),
adi,
this,
m_AttrBitmap.GetBitmap() );
vfe->init(this);
return vfe;
}
/* if (dynamic_cast<const NL3D::CPSIntMemory *>(scheme))
{
CValueFromEmitterDlgT<float, CAttribDlgFloat> vfe( (NL3D::CPSFloatMemory *)(scheme), std::string("UINT SCHEME"), m_AttrBitmap.GetBitmap());
vfe.DoModal();
}*/
if (dynamic_cast<const NL3D::CPSIntBinOp *>(scheme))
{
CAttribDlgInt *ad[2] = { NULL, NULL};
for (uint k = 0; k <2; ++k)
{
ad[k] = new CAttribDlgInt(_CstValueId, _Node, _MinRange, _MaxRange);
this->duplicateBoundChecker(*ad[k]);
}
CBinOpDlgT<sint32> *bod = new CBinOpDlgT<sint32>( (NL3D::CPSIntBinOp *)(scheme),
(CAttribDlgT<sint32> **) ad,
this,
m_AttrBitmap.GetBitmap());
bod->init(this);
return bod;
}
return NULL;
}
//*************************************************************************************************************
sint CAttribDlgInt::getCurrentScheme(void) const
{
const NL3D::CPSAttribMaker<sint32> *scheme = _SchemeWrapper->getScheme();
if (dynamic_cast<const NL3D::CPSIntBlender *>(scheme)) return 0;
if (dynamic_cast<const NL3D::CPSIntGradient *>(scheme)) return 1;
if (dynamic_cast<const NL3D::CPSIntMemory *>(scheme)) return 2;
if (dynamic_cast<const NL3D::CPSIntBinOp *>(scheme)) return 3;
return -1;
}
//*************************************************************************************************************
void CAttribDlgInt::setCurrentScheme(uint index)
{
nlassert(index < 4);
NL3D::CPSAttribMaker<sint32> *scheme = NULL;
switch (index)
{
case 0 :
scheme = new NL3D::CPSIntBlender;
break;
case 1 :
scheme = new NL3D::CPSIntGradient;
break;
case 2 :
scheme = new NL3D::CPSIntMemory;
((NL3D::CPSAttribMakerMemory<sint32> *) scheme)->setScheme(new NL3D::CPSIntBlender(_MinRange, _MaxRange));
break;
case 3 :
scheme = new NL3D::CPSIntBinOp;
((NL3D::CPSIntBinOp *) scheme)->setArg(0, new NL3D::CPSIntBlender);
((NL3D::CPSIntBinOp *) scheme)->setArg(1, new NL3D::CPSIntBlender);
break;
default:
break;
}
if (scheme)
{
_SchemeWrapper->setSchemeAndUpdateModifiedFlag(scheme);
}
}
///////////////////////
// CRGBA attributes //
///////////////////////
class CRGBABlenderDlgClient : public CValueBlenderDlgClientT<NLMISC::CRGBA>
{
public:
CEditAttribDlg *newDialog(const std::string &id, IPSWrapper<NLMISC::CRGBA> *wrapper)
{
CColorEdit *ce = new CColorEdit;
ce->setWrapper(wrapper);
return ce;
}
};
//////////////////////////////////////////////////////////
// COLOR GRADIENT EDITION INTERFACE //
//////////////////////////////////////////////////////////
//*************************************************************************************************************
class CColorGradientDlgWrapper : public CValueGradientDlgClientT<CRGBA>
{
public:
/// a function that can display a value in a gradient, with the given offset. Deriver must define this
void displayValue(CDC *dc, uint index, sint x, sint y)
{
CRGBA col = Scheme->getValue(index);
RECT r;
r.left = x + 10;
r.top = y + 10;
r.right = x + 53;
r.bottom = y + 29;
CBrush b;
b.CreateSolidBrush(RGB(col.R, col.G, col.B));
dc->FillRect(&r, &b);
b.DeleteObject();
b.CreateSolidBrush(RGB(0, 0, 0));
CGdiObject *old = dc->SelectObject(&b);
r.top = y + 10; r. bottom = y + 29;
r.right = x + 53; r.left = x + 10;
dc->FrameRect(&r, &b);
dc->SelectObject(old);
b.DeleteObject();
}
CEditAttribDlg *newDialog(const std::string &id, IPSWrapper<NLMISC::CRGBA> *wrapper)
{
CColorEdit *ce = new CColorEdit;
ce->setWrapper(wrapper);
return ce;
}
};
////////////////////////////
//*************************************************************************************************************
CAttribDlgRGBA::CAttribDlgRGBA(const std::string &valueID, CParticleWorkspace::CNode *node) : CAttribDlgT<CRGBA>(valueID, node)
{
}
//*************************************************************************************************************
uint CAttribDlgRGBA::getNumScheme(void) const
{
return _DisableMemoryScheme ? 3 : 5;
}
//*************************************************************************************************************
std::string CAttribDlgRGBA::getSchemeName(uint index) const
{
const char *types[] = { "color sampled blender", "color gradient", "color exact blender", "values computed from emitter", "binary operator" };
nlassert(index < 5);
return std::string(types[index]);
}
//*************************************************************************************************************
CWnd *CAttribDlgRGBA::editScheme(void)
{
const NL3D::CPSAttribMaker<CRGBA> *scheme = _SchemeWrapper->getScheme();
if (dynamic_cast<const NL3D::CPSColorBlender *>(scheme))
{
CRGBABlenderDlgClient *myInterface = new CRGBABlenderDlgClient;
myInterface->Id = std::string("RGBA_BLENDER");
myInterface->SchemeFunc = & ((NL3D::CPSValueBlenderSample<CRGBA, 64> *) scheme)->_F;
CValueBlenderDlg *vb = new CValueBlenderDlg(myInterface, true, this, this, _Node);
vb->init(this);
return vb;
}
if (dynamic_cast<const NL3D::CPSColorGradient *>(scheme))
{
CColorGradientDlgWrapper *wrapper = new CColorGradientDlgWrapper;
wrapper->Scheme = &(((NL3D::CPSColorGradient *) (_SchemeWrapper->getScheme()) )->_F);
CValueGradientDlg *gd = new CValueGradientDlg(wrapper, _Node, true, this, this);
wrapper->GradDlg = gd;
wrapper->DefaultValue = CRGBA::White;
wrapper->Id = std::string("RGBA_GRADIENT");
gd->init(this);
return gd;
}
if (dynamic_cast<const NL3D::CPSColorBlenderExact *>(scheme))
{
return NULL;
}
if (dynamic_cast<const NL3D::CPSColorMemory *>(scheme))
{
CAttribDlgRGBA *ad = new CAttribDlgRGBA(_CstValueId, _Node);
CValueFromEmitterDlgT<CRGBA> *vfe = new CValueFromEmitterDlgT<CRGBA>( (NL3D::CPSColorMemory *)(scheme),
ad,
this,
m_AttrBitmap.GetBitmap());
vfe->init(this);
return vfe;
}
if (dynamic_cast<const NL3D::CPSColorBinOp *>(scheme))
{
CAttribDlgRGBA *ad[2] = { NULL, NULL};
for (uint k = 0; k <2; ++k)
{
ad[k] = new CAttribDlgRGBA(_CstValueId, _Node);
}
CBinOpDlgT<CRGBA> *bod = new CBinOpDlgT<CRGBA>( (NL3D::CPSColorBinOp *)(scheme),
(CAttribDlgT<CRGBA> **) ad,
this,
m_AttrBitmap.GetBitmap());
bod->init(this);
return bod;
}
return NULL;
}
//*************************************************************************************************************
void CAttribDlgRGBA::setCurrentScheme(uint index)
{
nlassert(index < 5);
NL3D::CPSAttribMaker<CRGBA> *scheme = NULL;
switch (index)
{
case 0 :
scheme = new NL3D::CPSColorBlender;
break;
case 1 :
scheme = new NL3D::CPSColorGradient(NL3D::CPSColorGradient::_DefaultGradient, 2, 16, 1.f);
break;
case 2 :
scheme = new NL3D::CPSColorBlenderExact;
break;
case 3 :
scheme = new NL3D::CPSColorMemory;
((NL3D::CPSAttribMakerMemory<CRGBA> *) scheme)->setScheme(new NL3D::CPSColorBlender);
break;
case 4 :
scheme = new NL3D::CPSColorBinOp;
((NL3D::CPSColorBinOp *) scheme)->setArg(0, new NL3D::CPSColorBlender);
((NL3D::CPSColorBinOp *) scheme)->setArg(1, new NL3D::CPSColorBlender);
break;
default:
break;
}
if (scheme)
{
_SchemeWrapper->setSchemeAndUpdateModifiedFlag(scheme);
}
}
//*************************************************************************************************************
sint CAttribDlgRGBA::getCurrentScheme(void) const
{
const NL3D::CPSAttribMaker<CRGBA> *scheme = _SchemeWrapper->getScheme();
if (dynamic_cast<const NL3D::CPSColorBlender *>(scheme)) return 0;
if (dynamic_cast<const NL3D::CPSColorGradient *>(scheme)) return 1;
if (dynamic_cast<const NL3D::CPSColorBlenderExact *>(scheme)) return 2;
if (dynamic_cast<const NL3D::CPSColorMemory *>(scheme)) return 3;
if (dynamic_cast<const NL3D::CPSColorBinOp *>(scheme)) return 4;
return -1;
}
//*************************************************************************************************************
CEditAttribDlg *CAttribDlgRGBA::createConstantValueDlg()
{
CColorEdit *ce = new CColorEdit;
ce->setWrapper(_Wrapper);
return ce;
}
/////////////////////////////
// plane basis attributes //
/////////////////////////////
//////////////////////////////////////////////////////////
// PLANE BASIS GRADIENT EDITION INTERFACE //
//////////////////////////////////////////////////////////
class CPlaneBasisGradientDlgWrapper : public CValueGradientDlgClientT<NL3D::CPlaneBasis>
{
public:
/// a function that can display a value in a gradient, with the given offset. Deriver must define this
void displayValue(CDC *dc, uint index, sint x, sint y)
{
NLMISC::CRGBA c1[] ={ NLMISC::CRGBA::Black, NLMISC::CRGBA::Black, NLMISC::CRGBA::Black };
NLMISC::CRGBA c2[] ={ NLMISC::CRGBA::Green, NLMISC::CRGBA::Green, NLMISC::CRGBA::Red };
// read plane basis
NL3D::CPlaneBasis pb = Scheme->getValue(index);
CPoint center(x + 20, y + 25);
NLMISC::CMatrix m;
m.setRot(pb.X, pb.Y, pb.X ^ pb.Y);
DrawBasisInDC(center, 12, m, *dc, c2);
}
CEditAttribDlg *newDialog(const std::string &id, IPSWrapper<NL3D::CPlaneBasis> *wrapper)
{
CBasisEdit *be = new CBasisEdit;
be->setWrapper(wrapper);
return be;
}
};
//*************************************************************************************************************
CAttribDlgPlaneBasis::CAttribDlgPlaneBasis(const std::string &valueID, CParticleWorkspace::CNode *node) : CAttribDlgT<NL3D::CPlaneBasis>(valueID, node)
{
}
uint CAttribDlgPlaneBasis::getNumScheme(void) const
{
return _DisableMemoryScheme ? 3 : 5;
}
std::string CAttribDlgPlaneBasis::getSchemeName(uint index) const
{
const char *types[] = { "basis gradient", "follow path", "spinner", "values computed from emitter", "binary operator" };
nlassert(index < 5);
return std::string(types[index]);
}
//*************************************************************************************************************
CWnd *CAttribDlgPlaneBasis::editScheme(void)
{
NL3D::CPSAttribMaker<NL3D::CPlaneBasis> *scheme = _SchemeWrapper->getScheme();
if (dynamic_cast<NL3D::CPSPlaneBasisGradient *>(scheme))
{
CPlaneBasisGradientDlgWrapper *wrapper = new CPlaneBasisGradientDlgWrapper;
wrapper->Scheme = &(((NL3D::CPSPlaneBasisGradient *) (_SchemeWrapper->getScheme()) )->_F);
CValueGradientDlg *gd = new CValueGradientDlg(wrapper, _Node, true, this, this);
wrapper->GradDlg = gd;
wrapper->DefaultValue = NL3D::CPlaneBasis(NLMISC::CVector::K);
wrapper->Id = std::string("PLANE_BASIS_GRADIENT");
gd->init(this);
return gd;
}
if (dynamic_cast<NL3D::CPSPlaneBasisFollowSpeed *>(scheme))
{
CEditFollowPath *efp = new CEditFollowPath((NL3D::CPSPlaneBasisFollowSpeed *) scheme, _Node, this, this);
efp->init(this);
return efp;
}
if (dynamic_cast<NL3D::CPSPlaneBasisMemory *>(scheme))
{
CAttribDlgPlaneBasis *ad = new CAttribDlgPlaneBasis(_CstValueId, _Node);
CValueFromEmitterDlgT<NL3D::CPlaneBasis> *vfe = new CValueFromEmitterDlgT<NL3D::CPlaneBasis>
( (NL3D::CPSPlaneBasisMemory *)(scheme),
ad,
this,
m_AttrBitmap.GetBitmap());
vfe->init(this);
return vfe;
}
if (dynamic_cast<NL3D::CPSPlaneBasisBinOp *>(scheme))
{
CAttribDlgPlaneBasis *ad[2] = { NULL, NULL};
for (uint k = 0; k <2; ++k)
{
ad[k] = new CAttribDlgPlaneBasis(_CstValueId, _Node);
}
CBinOpDlgT<NL3D::CPlaneBasis> *bod = new CBinOpDlgT<NL3D::CPlaneBasis>( (NL3D::CPSPlaneBasisBinOp *)(scheme),
(CAttribDlgT<NL3D::CPlaneBasis> **) ad,
this,
m_AttrBitmap.GetBitmap());
bod->init(this);
return bod;
}
if (dynamic_cast<NL3D::CPSBasisSpinner *>(scheme))
{
CEditSpinner *es = new CEditSpinner(static_cast<NL3D::CPSBasisSpinner *>(scheme), _Node, this, this);
es->init(this);
return es;
}
return NULL;
}
//*************************************************************************************************************
void CAttribDlgPlaneBasis::setCurrentScheme(uint index)
{
nlassert(index < 5);
NL3D::CPSAttribMaker<NL3D::CPlaneBasis> *scheme = NULL;
switch (index)
{
case 0:
scheme = new NL3D::CPSPlaneBasisGradient;
break;
case 1:
scheme = new NL3D::CPSPlaneBasisFollowSpeed;
break;
case 2:
scheme = new NL3D::CPSBasisSpinner;
static_cast<NL3D::CPSBasisSpinner *>(scheme)->_F.setNumSamples(16);
break;
case 3:
scheme = new NL3D::CPSPlaneBasisMemory;
((NL3D::CPSAttribMakerMemory<NL3D::CPlaneBasis> *) scheme)->setScheme(new NL3D::CPSPlaneBasisFollowSpeed);
if (_Node)
{
_Node->setModified(true);
}
break;
case 4 :
scheme = new NL3D::CPSPlaneBasisBinOp;
((NL3D::CPSPlaneBasisBinOp *) scheme)->setArg(0, new NL3D::CPSPlaneBasisFollowSpeed);
((NL3D::CPSPlaneBasisBinOp *) scheme)->setArg(1, new NL3D::CPSPlaneBasisFollowSpeed);
break;
default:
break;
}
if (scheme)
{
_SchemeWrapper->setSchemeAndUpdateModifiedFlag(scheme);
}
}
//*************************************************************************************************************
sint CAttribDlgPlaneBasis::getCurrentScheme(void) const
{
const NL3D::CPSAttribMaker<NL3D::CPlaneBasis> *scheme = _SchemeWrapper->getScheme();
if (dynamic_cast<const NL3D::CPSPlaneBasisGradient *>(scheme)) return 0;
if (dynamic_cast<const NL3D::CPSPlaneBasisFollowSpeed *>(scheme)) return 1;
if (dynamic_cast<const NL3D::CPSBasisSpinner *>(scheme)) return 2;
if (dynamic_cast<const NL3D::CPSPlaneBasisMemory *>(scheme)) return 3;
if (dynamic_cast<const NL3D::CPSPlaneBasisBinOp *>(scheme)) return 4;
return -1;
}
//*************************************************************************************************************
CEditAttribDlg *CAttribDlgPlaneBasis::createConstantValueDlg()
{
CBasisEdit *ce = new CBasisEdit;
ce->setWrapper(_Wrapper);
return ce;
}
//*************************************************************************************************************
void CAttribDlg::OnDestroy()
{
if (_SchemeEditionDlg)
{
CWnd *wnd = _SchemeEditionDlg;
_SchemeEditionDlg = NULL;
wnd ->DestroyWindow();
delete wnd ;
}
CDialog::OnDestroy();
}
//*************************************************************************************************************
void CAttribDlg::OnClose()
{
CDialog::OnClose();
}