khanat-opennel-code/code/nel/tools/3d/object_viewer/located_bindable_dialog.cpp
2014-03-23 15:16:20 +05:30

811 lines
27 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/>.
#include "std_afx.h"
#include "object_viewer.h"
#include "located_bindable_dialog.h"
#include "nel/3d/ps_located.h"
#include "nel/3d/ps_particle.h"
#include "nel/3d/ps_mesh.h"
#include "nel/3d/ps_force.h"
#include "nel/3d/ps_emitter.h"
#include "nel/3d/ps_zone.h"
#include "nel/3d/particle_system_model.h"
#include "texture_chooser.h"
#include "attrib_dlg.h"
#include "precomputed_rotations_dlg.h"
#include "tail_particle_dlg.h"
#include "mesh_dlg.h"
#include "texture_anim_dlg.h"
#include "particle_dlg.h"
#include "constraint_mesh_dlg.h"
#include "constraint_mesh_tex_dlg.h"
#include "ribbon_dlg.h"
using NL3D::CPSLocatedBindable;
/////////////////////////////////////////////////////////////////////////////
// CLocatedBindableDialog dialog
//***********************************************************************************
CLocatedBindableDialog::CLocatedBindableDialog(CParticleWorkspace::CNode *ownerNode, NL3D::CPSLocatedBindable *bindable)
: _Node(ownerNode), _Bindable(bindable), _SizeCtrl(NULL)
{
//{{AFX_DATA_INIT(CLocatedBindableDialog)
m_IndependantSizes = FALSE;
//}}AFX_DATA_INIT
}
/// dtor
//***********************************************************************************
CLocatedBindableDialog::~CLocatedBindableDialog()
{
if (_SizeCtrl)
{
_SizeCtrl->DestroyWindow();
delete _SizeCtrl;
}
}
//***********************************************************************************
void CLocatedBindableDialog::init(CParticleDlg* pParent)
{
Create(IDD_LOCATED_BINDABLE, pParent);
ShowWindow(SW_SHOW);
_ParticleDlg = pParent;
NL3D::CParticleSystem *ps = _Bindable->getOwner()->getOwner();
if (ps->isSharingEnabled())
{
GetDlgItem(IDC_NO_AUTO_LOD)->ShowWindow(TRUE);
if (ps->isAutoLODEnabled() == false)
{
GetDlgItem(IDC_NO_AUTO_LOD)->EnableWindow(FALSE);
}
else
{
((CButton *) GetDlgItem(IDC_NO_AUTO_LOD))->SetCheck(NLMISC::safe_cast<NL3D::CPSParticle *>(_Bindable)->isAutoLODDisabled());
}
}
else
{
GetDlgItem(IDC_NO_AUTO_LOD)->ShowWindow(FALSE);
}
uint yPos = 60;
const uint xPos = 5;
RECT rect;
// control at the top of the sheet are not available for meshs & constraint meshes, so use that extra space
if (dynamic_cast<NL3D::CPSMesh *>(_Bindable) || dynamic_cast<NL3D::CPSConstraintMesh *>(_Bindable))
{
yPos = 0;
}
// has the particle a material ?
if (dynamic_cast<NL3D::CPSMaterial *>(_Bindable))
{
NL3D::CPSMaterial *material = dynamic_cast<NL3D::CPSMaterial *>(_Bindable);
// blending mode
m_BlendingMode.SetCurSel((uint) material->getBlendingMode() );
// z-test
((CButton *) GetDlgItem(IDC_ZTEST))->SetCheck(material->isZTestEnabled() ? BST_CHECKED : BST_UNCHECKED);
// z-bias
GetDlgItem(IDC_ZBIAS)->SetWindowText(NLMISC::toString("%.2f", -material->getZBias()).c_str());
}
else
{
m_BlendingMode.ShowWindow(SW_HIDE);
GetDlgItem(IDC_BLENDING_MODE_STATIC)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_ZTEST)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_ZBIAS)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_ZBIAS_TEXT)->ShowWindow(SW_HIDE);
}
GetDlgItem(IDC_ALIGN_ON_MOTION)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_ZALIGN)->ShowWindow(SW_HIDE);
// enable disable z-test
//
if (dynamic_cast<NL3D::CPSParticle *>(_Bindable))
{
NL3D::CPSParticle *p = (NL3D::CPSParticle *) _Bindable;
// check support for lighting
if (p->supportGlobalColorLighting())
{
GetDlgItem(ID_GLOBAL_COLOR_LIGHTING)->ShowWindow(SW_SHOW);
// if global color lighting is forced for all objects, don't allow to modify
GetDlgItem(ID_GLOBAL_COLOR_LIGHTING)->EnableWindow(ps->getForceGlobalColorLightingFlag() ? FALSE : TRUE);
((CButton *) GetDlgItem(ID_GLOBAL_COLOR_LIGHTING))->SetCheck(p->usesGlobalColorLighting() ? 1 : 0);
}
else
{
GetDlgItem(ID_GLOBAL_COLOR_LIGHTING)->ShowWindow(SW_HIDE);
}
// check support for color
if (dynamic_cast<NL3D::CPSColoredParticle *>(_Bindable))
{
CAttribDlgRGBA *ad = new CAttribDlgRGBA("PARTICLE_COLOR", _Node);
pushWnd(ad);
_ColorWrapper.S = dynamic_cast<NL3D::CPSColoredParticle *>(_Bindable);
ad->setWrapper(&_ColorWrapper);
ad->setSchemeWrapper(&_ColorWrapper);
HBITMAP bmh = LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_PARTICLE_COLOR));
ad->init(bmh, xPos, yPos, this);
ad->GetClientRect(&rect);
yPos += rect.bottom + 3;
}
// init size ctrl
_SizeCtrlX = xPos;
_SizeCtrlY = yPos;
yPos += updateSizeControl();
// check support for angle 2D
if (dynamic_cast<NL3D::CPSRotated2DParticle *>(_Bindable))
{
CAttribDlgFloat *ad = new CAttribDlgFloat("PARTICLE_ANGLE2D", _Node, 0.f, 256.f);
pushWnd(ad);
_Angle2DWrapper.S = dynamic_cast<NL3D::CPSRotated2DParticle *>(_Bindable);
ad->setWrapper(&_Angle2DWrapper);
ad->setSchemeWrapper(&_Angle2DWrapper);
HBITMAP bmh = LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_PARTICLE_ANGLE));
ad->init(bmh, xPos, yPos, this);
ad->GetClientRect(&rect);
yPos += rect.bottom + 3;
}
CAttribDlgPlaneBasis *pb = NULL;
// check support for plane basis
if (dynamic_cast<NL3D::CPSRotated3DPlaneParticle *>(_Bindable))
{
pb = new CAttribDlgPlaneBasis("PARTICLE_PLANE_BASIS", _Node);
pushWnd(pb);
_PlaneBasisWrapper.S = dynamic_cast<NL3D::CPSRotated3DPlaneParticle *>(_Bindable);
pb->setWrapper(&_PlaneBasisWrapper);
pb->setSchemeWrapper(&_PlaneBasisWrapper);
HBITMAP bmh = LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BASIS));
pb->init(bmh, xPos, yPos, this);
pb->GetClientRect(&rect);
yPos += rect.bottom + 3;
}
// check support for precomputed rotations
if (dynamic_cast<NL3D::CPSHintParticleRotateTheSame *>(_Bindable))
{
CPrecomputedRotationsDlg *pr = new CPrecomputedRotationsDlg(_Node, dynamic_cast<NL3D::CPSHintParticleRotateTheSame *>(_Bindable), pb);
pushWnd(pr);
pr->init(this, xPos, yPos);
pr->GetClientRect(&rect);
yPos += rect.bottom + 3;
}
// if we're dealing with a face look at, motion blur can be tuned
if (dynamic_cast<NL3D::CPSFaceLookAt *>(_Bindable))
{
NL3D::CPSFaceLookAt *fla = static_cast<NL3D::CPSFaceLookAt *>(_Bindable);
CEditableRangeFloat *mbc = new CEditableRangeFloat(std::string("MOTION_BLUR_COEFF"), _Node, 0, 5);
pushWnd(mbc);
_MotionBlurWnd.push_back(mbc);
_MotionBlurCoeffWrapper.P = fla;
mbc->setWrapper(&_MotionBlurCoeffWrapper);
mbc->init(xPos + 140, yPos, this);
CStatic *s = new CStatic;
pushWnd(s);
_MotionBlurWnd.push_back(s);
s->Create("Fake motion blur coeff.", SS_LEFT, CRect(xPos, yPos + 16, xPos + 139, yPos + 48), this);
s->SetFont(CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)));
s->ShowWindow(SW_SHOW);
mbc->GetClientRect(&rect);
yPos += rect.bottom + 3;
mbc = new CEditableRangeFloat(std::string("MOTION_BLUR_THRESHOLD"), _Node, 0, 5);
pushWnd(mbc);
_MotionBlurWnd.push_back(mbc);
_MotionBlurThresholdWrapper.P = fla;
mbc->setWrapper(&_MotionBlurThresholdWrapper);
mbc->init(xPos + 140, yPos, this);
s = new CStatic;
pushWnd(s);
_MotionBlurWnd.push_back(s);
s->Create("Fake motion blur threshold.", SS_LEFT, CRect(xPos, yPos + 16, xPos + 139, yPos + 48), this);
s->SetFont(CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)));
s->ShowWindow(SW_SHOW);
mbc->GetClientRect(&rect);
yPos += rect.bottom + 3;
GetDlgItem(IDC_ALIGN_ON_MOTION)->ShowWindow(SW_SHOW);
GetDlgItem(IDC_ZALIGN)->ShowWindow(SW_SHOW);
((CButton *) GetDlgItem(IDC_ALIGN_ON_MOTION))->SetCheck(fla->getAlignOnMotion());
((CButton *) GetDlgItem(IDC_ZALIGN))->SetCheck(fla->getAlignOnZAxis());
updateValidWndForAlignOnMotion(fla->getAlignOnMotion());
}
// if we're dealing with a shockwave, we add dlg for the radius cut, and the number of segments
if (dynamic_cast<NL3D::CPSShockWave *>(_Bindable))
{
NL3D::CPSShockWave *sw = static_cast<NL3D::CPSShockWave *>(_Bindable);
CEditableRangeFloat *rc = new CEditableRangeFloat(std::string("RADIUS CUT"), _Node, 0, 1);
pushWnd(rc);
_RadiusCutWrapper.S = sw;
rc->setWrapper(&_RadiusCutWrapper);
rc->init(xPos + 140, yPos, this);
CStatic *s = new CStatic;
pushWnd(s);
s->Create("Radius cut.", SS_LEFT, CRect(xPos, yPos + 16, xPos + 139, yPos + 48), this);
s->SetFont(CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)));
s->ShowWindow(SW_SHOW);
rc->GetClientRect(&rect);
yPos += rect.bottom + 3;
CEditableRangeUInt *snbs = new CEditableRangeUInt(std::string("SHOCK WAVE NB SEG"), _Node, 3, 24);
pushWnd(snbs);
_ShockWaveNbSegWrapper.S = sw;
snbs->enableLowerBound(3, false);
snbs->setWrapper(&_ShockWaveNbSegWrapper);
snbs->init(xPos + 140, yPos, this);
s = new CStatic;
pushWnd(s);
s->Create("Nb segs", SS_LEFT, CRect(xPos, yPos + 16, xPos + 139, yPos + 48), this);
s->ShowWindow(SW_SHOW);
snbs->GetClientRect(&rect);
yPos += rect.bottom + 3;
CEditableRangeFloat *uvd = new CEditableRangeFloat(std::string("TEX UFACTOR"), _Node, 0, 5);
pushWnd(uvd);
_ShockWaveUFactorWrapper.S = sw;
uvd->setWrapper(&_ShockWaveUFactorWrapper);
uvd->init(xPos + 140, yPos, this);
s = new CStatic;
pushWnd(s);
s->Create("Texture U factor :", SS_LEFT, CRect(xPos, yPos + 16, xPos + 139, yPos + 48), this);
s->ShowWindow(SW_SHOW);
uvd->GetClientRect(&rect);
yPos += rect.bottom + 3;
}
// fanlight
if (dynamic_cast<NL3D::CPSFanLight *>(_Bindable))
{
CEditableRangeUInt *nbf = new CEditableRangeUInt(std::string("NB_FANS"), _Node, 3, 127);
pushWnd(nbf);
nbf->enableLowerBound(3, false);
nbf->enableUpperBound(128, true);
_FanLightWrapper.P = dynamic_cast<NL3D::CPSFanLight *>(_Bindable);
nbf->setWrapper(&_FanLightWrapper);
nbf->init(xPos + 140, yPos, this);
CStatic *s = new CStatic;
pushWnd(s);
s->Create("Nb fan lights :", SS_LEFT, CRect(xPos, yPos + 16, xPos + 139, yPos + 48), this);
s->SetFont(CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)));
s->ShowWindow(SW_SHOW);
nbf->GetClientRect(&rect);
yPos += rect.bottom + 3;
nbf = new CEditableRangeUInt(std::string("PHASE_SMOOTHNESS"), _Node, 0, 31);
pushWnd(nbf);
nbf->enableUpperBound(32, true);
_FanLightSmoothnessWrapper.P = static_cast<NL3D::CPSFanLight *>(_Bindable);
nbf->setWrapper(&_FanLightSmoothnessWrapper);
nbf->init(xPos + 140, yPos, this);
s = new CStatic;
pushWnd(s);
s->Create("Phase smoothnes:", SS_LEFT, CRect(xPos, yPos + 16, xPos + 139, yPos + 48), this);
s->ShowWindow(SW_SHOW);
nbf->GetClientRect(&rect);
yPos += rect.bottom + 3;
CEditableRangeFloat *nbfp = new CEditableRangeFloat(std::string("FAN_LIGHT_PHASE"), _Node, 0, 4.f);
pushWnd(nbfp);
_FanLightPhaseWrapper.P = static_cast<NL3D::CPSFanLight *>(_Bindable);
nbfp->setWrapper(&_FanLightPhaseWrapper);
nbfp->init(xPos + 140, yPos, this);
s = new CStatic;
pushWnd(s);
s->Create("Fan light speed :", SS_LEFT, CRect(xPos, yPos + 16, xPos + 139, yPos + 48), this);
s->ShowWindow(SW_SHOW);
nbf->GetClientRect(&rect);
yPos += rect.bottom + 3;
nbfp = new CEditableRangeFloat(std::string("FAN_LIGHT_INTENSITY"), _Node, 0, 4.f);
pushWnd(nbfp);
_FanLightIntensityWrapper.P = static_cast<NL3D::CPSFanLight *>(_Bindable);
nbfp->setWrapper(&_FanLightIntensityWrapper);
nbfp->init(xPos + 140, yPos, this);
s = new CStatic;
pushWnd(s);
s->Create("Fan light intensity:", SS_LEFT, CRect(xPos, yPos + 16, xPos + 139, yPos + 48), this);
s->ShowWindow(SW_SHOW);
nbf->GetClientRect(&rect);
yPos += rect.bottom + 3;
}
// tail particle
if (dynamic_cast<NL3D::CPSTailParticle *>(_Bindable))
{
CEditableRangeUInt *nbs;
if (!dynamic_cast<NL3D::CPSRibbonLookAt *>(_Bindable))
{
nbs = new CEditableRangeUInt(std::string("TAIL_NB_SEGS_"), _Node, 2, 16);
nbs->enableLowerBound(1, true);
}
else
{
nbs = new CEditableRangeUInt(std::string("LOOKAT_RIBBON_TAIL_NB_SEGS_"), _Node, 2, 16);
nbs->enableLowerBound(1, true);
}
pushWnd(nbs);
if (dynamic_cast<NL3D::CPSTailDot *>(_Bindable))
{
nbs->enableUpperBound(256, true);
}
_TailParticleWrapper.P = dynamic_cast<NL3D::CPSTailParticle *>(_Bindable);
nbs->setWrapper(&_TailParticleWrapper);
nbs->init(xPos + 140, yPos, this);
CStatic *s = new CStatic;
pushWnd(s);
s->Create("Nb segs :", SS_LEFT, CRect(xPos, yPos + 16, xPos + 139, yPos + 48), this);
s->SetFont(CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)));
s->ShowWindow(SW_SHOW);
nbs->GetClientRect(&rect);
yPos += rect.bottom + 3;
CTailParticleDlg *tpd = new CTailParticleDlg(_Node, dynamic_cast<NL3D::CPSTailParticle *>(_Bindable));
pushWnd(tpd);
tpd->init(this, xPos, yPos);
tpd->GetClientRect(&rect);
yPos += rect.bottom + 3;
}
// shape particle
if (dynamic_cast<NL3D::CPSShapeParticle *>(_Bindable))
{
CMeshDlg *md = new CMeshDlg(_Node, dynamic_cast<NL3D::CPSShapeParticle *>(_Bindable), _ParticleDlg);
md->init(this, xPos, yPos);
md->GetClientRect(&rect);
yPos += rect.bottom + 3;
pushWnd(md);
}
// constraint mesh particle
if (dynamic_cast<NL3D::CPSConstraintMesh *>(_Bindable))
{
CConstraintMeshDlg *cmd = new CConstraintMeshDlg(static_cast<NL3D::CPSConstraintMesh *>(_Bindable));
cmd->init(xPos, yPos, this);
cmd->GetClientRect(&rect);
yPos += rect.bottom + 3;
CConstraintMeshTexDlg *cmtd = new CConstraintMeshTexDlg(static_cast<NL3D::CPSConstraintMesh *>(_Bindable),
this);
cmtd->init(xPos, yPos, this);
cmtd->GetClientRect(&rect);
yPos += rect.bottom + 3;
pushWnd(cmd);
pushWnd(cmtd);
}
// check support for animated texture
if (dynamic_cast<NL3D::CPSTexturedParticle *>(_Bindable))
{
CTextureAnimDlg *td = new CTextureAnimDlg(_Node,
dynamic_cast<NL3D::CPSTexturedParticle *>(_Bindable),
dynamic_cast<NL3D::CPSMultiTexturedParticle *>(_Bindable)
);
pushWnd(td);
td->init(xPos, yPos, this);
td->GetClientRect(&rect);
yPos += rect.bottom + 3;
}
// unanimated texture
if (dynamic_cast<NL3D::CPSTexturedParticleNoAnim *>(_Bindable))
{
NL3D::CPSTexturedParticleNoAnim *tp = dynamic_cast<NL3D::CPSTexturedParticleNoAnim *>(_Bindable);
_TextureNoAnimWrapper.TP = tp;
CTextureChooser *tc = new CTextureChooser(dynamic_cast<NL3D::CPSMultiTexturedParticle *>(_Bindable), _Node);
tc->enableRemoveButton();
tc->setWrapper(&_TextureNoAnimWrapper);
pushWnd(tc);
tc->init(xPos, yPos, this);
tc->GetClientRect(&rect);
yPos += rect.bottom + 3;
}
// ribbon texture (doesn't support texture animation for now)
if (dynamic_cast<NL3D::CPSRibbon *>(_Bindable))
{
// add dialog for uv tuning with ribbon
CEditableRangeFloat *uvd = new CEditableRangeFloat(std::string("RIBBON UFACTOR"), _Node, 0, 5);
pushWnd(uvd);
_RibbonUFactorWrapper.R = static_cast<NL3D::CPSRibbon *>(_Bindable);
uvd->setWrapper(&_RibbonUFactorWrapper);
uvd->init(xPos + 140, yPos, this);
CStatic *s = new CStatic;
pushWnd(s);
s->Create("Texture U factor :", SS_LEFT, CRect(xPos, yPos + 16, xPos + 139, yPos + 48), this);
s->SetFont(CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)));
s->ShowWindow(SW_SHOW);
uvd->GetClientRect(&rect);
yPos += rect.bottom + 3;
uvd = new CEditableRangeFloat(std::string("RIBBON VFACTOR"), _Node, 0, 5);
pushWnd(uvd);
_RibbonVFactorWrapper.R = static_cast<NL3D::CPSRibbon *>(_Bindable);
uvd->setWrapper(&_RibbonVFactorWrapper);
uvd->init(xPos + 140, yPos, this);
s = new CStatic;
pushWnd(s);
s->Create("Texture V factor :", SS_LEFT, CRect(xPos, yPos + 16, xPos + 139, yPos + 48), this);
s->SetFont(CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)));
s->ShowWindow(SW_SHOW);
uvd->GetClientRect(&rect);
yPos += rect.bottom + 3;
}
if (dynamic_cast<NL3D::CPSRibbonBase *>(_Bindable))
{
// add dialog for uv tuning with ribbon
CEditableRangeFloat *sd = new CEditableRangeFloat(std::string("SEGMENT DURATION"), _Node, 0.05f, 0.5f);
sd->enableLowerBound(0, true);
pushWnd(sd);
_SegDurationWrapper.R = static_cast<NL3D::CPSRibbonLookAt *>(_Bindable);
sd->setWrapper(&_SegDurationWrapper);
sd->init(xPos + 140, yPos, this);
CStatic *s = new CStatic;
pushWnd(s);
s->Create("Seg Duration :", SS_LEFT, CRect(xPos, yPos + 16, xPos + 139, yPos + 48), this);
s->SetFont(CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)));
s->ShowWindow(SW_SHOW);
sd->GetClientRect(&rect);
yPos += rect.bottom + 3;
}
// 'look at' independant sizes
bool isLookAt = dynamic_cast<NL3D::CPSFaceLookAt *>(_Bindable) != NULL;
GetDlgItem(IDC_INDE_SIZES)->ShowWindow(isLookAt ? SW_SHOW : SW_HIDE);
GetDlgItem(IDC_SIZE_WIDTH)->ShowWindow(isLookAt ? SW_SHOW : SW_HIDE);
GetDlgItem(IDC_SIZE_HEIGHT)->ShowWindow(isLookAt ? SW_SHOW : SW_HIDE);
GetDlgItem(IDC_WIDTH_HEIGHT_BOX)->ShowWindow(isLookAt ? SW_SHOW : SW_HIDE);
((CButton *) GetDlgItem(IDC_SIZE_WIDTH))->SetCheck(1);
if (isLookAt)
{
NL3D::CPSFaceLookAt *la = static_cast<NL3D::CPSFaceLookAt *>(_Bindable);
m_IndependantSizes = la->hasIndependantSizes();
((CButton *) GetDlgItem(IDC_INDE_SIZES))->SetCheck(m_IndependantSizes);
updateIndependantSizes();
}
/// new ribbon base class
if (dynamic_cast<NL3D::CPSRibbonBase *>(_Bindable))
{
CRibbonDlg *rd = new CRibbonDlg(_Node, static_cast<NL3D::CPSRibbonBase *>(_Bindable),
this);
rd->init(this, xPos, yPos);
pushWnd(rd);
rd->GetClientRect(&rect);
yPos += rect.bottom + 3;
}
}
UpdateData();
}
//***********************************************************************************
void CLocatedBindableDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CLocatedBindableDialog)
DDX_Control(pDX, IDC_ZBIAS, m_ZBias);
DDX_Control(pDX, IDC_BLENDING_MODE, m_BlendingMode);
DDX_Check(pDX, IDC_INDE_SIZES, m_IndependantSizes);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CLocatedBindableDialog, CDialog)
//{{AFX_MSG_MAP(CLocatedBindableDialog)
ON_CBN_SELCHANGE(IDC_BLENDING_MODE, OnSelchangeBlendingMode)
ON_BN_CLICKED(IDC_INDE_SIZES, OnIndeSizes)
ON_BN_CLICKED(IDC_SIZE_WIDTH, OnSizeWidth)
ON_BN_CLICKED(IDC_SIZE_HEIGHT, OnSizeHeight)
ON_BN_CLICKED(IDC_NO_AUTO_LOD, OnNoAutoLod)
ON_BN_CLICKED(ID_GLOBAL_COLOR_LIGHTING, OnGlobalColorLighting)
ON_BN_CLICKED(IDC_ALIGN_ON_MOTION, OnAlignOnMotion)
ON_BN_CLICKED(IDC_ZTEST, OnZtest)
ON_EN_CHANGE(IDC_ZBIAS, OnChangeZbias)
ON_EN_KILLFOCUS(IDC_ZBIAS, OnKillfocusZbias)
ON_BN_CLICKED(IDC_ZALIGN, OnZalign)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLocatedBindableDialog message handlers
//====================================================================
void CLocatedBindableDialog::touchPSState()
{
if (_Node && _Node->getPSModel())
{
_Node->getPSModel()->touchTransparencyState();
_Node->getPSModel()->touchLightableState();
}
}
//***********************************************************************************
void CLocatedBindableDialog::OnSelchangeBlendingMode()
{
UpdateData();
NL3D::CPSMaterial *m = dynamic_cast<NL3D::CPSMaterial *>(_Bindable);
nlassert(m);
m->setBlendingMode( (NL3D::CPSMaterial::TBlendingMode) m_BlendingMode.GetCurSel());
touchPSState();
updateModifiedFlag();
}
//***********************************************************************************
void CLocatedBindableDialog::updateIndependantSizes()
{
UpdateData();
// make sure we are dealing with 'LookAt' for now
nlassert(dynamic_cast<NL3D::CPSFaceLookAt *>(_Bindable));
GetDlgItem(IDC_SIZE_WIDTH)->EnableWindow(m_IndependantSizes);
GetDlgItem(IDC_SIZE_HEIGHT)->EnableWindow(m_IndependantSizes);
}
//***********************************************************************************
// user asked for independant sizes
void CLocatedBindableDialog::OnIndeSizes()
{
UpdateData();
// make sure we are dealing with 'LookAt' for now
nlassert(dynamic_cast<NL3D::CPSFaceLookAt *>(_Bindable));
NL3D::CPSFaceLookAt *la = static_cast<NL3D::CPSFaceLookAt *>(_Bindable);
la->setIndependantSizes(m_IndependantSizes ? true : false /* VCC warning*/);
updateIndependantSizes();
updateSizeControl();
updateModifiedFlag();
}
//***********************************************************************************
uint CLocatedBindableDialog::updateSizeControl()
{
HBITMAP bmh;
if (!dynamic_cast<NL3D::CPSSizedParticle *>(_Bindable)) return 0;
// if a previous control was there, remove it
if (_SizeCtrl)
{
_SizeCtrl->DestroyWindow();
delete _SizeCtrl;
_SizeCtrl = NULL;
}
NL3D::CPSFaceLookAt *fla = dynamic_cast<NL3D::CPSFaceLookAt *>(_Bindable);
// LookAt case
if (fla && fla->hasIndependantSizes())
{
int editWidth = (((CButton *) GetDlgItem(IDC_SIZE_WIDTH))->GetCheck());
_SizeCtrl = new CAttribDlgFloat(editWidth ? "PARTICLE_WIDTH" : "PARTICLE_HEIGHT", _Node, 0.f, 1.f);
if (editWidth) // wrap to the wanted size
{
_SizeWrapper.S = fla;
}
else
{
_SizeWrapper.S = &fla->getSecondSize();
}
_SizeCtrl->setWrapper(&_SizeWrapper);
_SizeCtrl->setSchemeWrapper(&_SizeWrapper);
bmh = LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(editWidth ? IDB_PARTICLE_WIDTH : IDB_PARTICLE_HEIGHT));
}
else // general case. Wrap to the size interface and the appropriate dialog
{
_SizeCtrl = new CAttribDlgFloat("PARTICLE_SIZE", _Node, 0.f, 1.f);
_SizeWrapper.S = dynamic_cast<NL3D::CPSSizedParticle *>(_Bindable);
_SizeCtrl->setWrapper(&_SizeWrapper);
_SizeCtrl->setSchemeWrapper(&_SizeWrapper);
bmh = LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_PARTICLE_SIZE));
}
RECT rect;
_SizeCtrl->init(bmh, _SizeCtrlX, _SizeCtrlY, this);
_SizeCtrl->GetClientRect(&rect);
return rect.bottom + 3;
}
//***********************************************************************************
void CLocatedBindableDialog::OnSizeWidth()
{
updateSizeControl();
}
//***********************************************************************************
void CLocatedBindableDialog::OnSizeHeight()
{
updateSizeControl();
}
//***********************************************************************************
void CLocatedBindableDialog::OnNoAutoLod()
{
NL3D::CPSParticle *p = NLMISC::safe_cast<NL3D::CPSParticle *>(_Bindable);
p->disableAutoLOD(((CButton *) GetDlgItem(IDC_NO_AUTO_LOD))->GetCheck() != 0);
updateModifiedFlag();
}
//***********************************************************************************
void CLocatedBindableDialog::OnGlobalColorLighting()
{
NL3D::CPSParticle *p = NLMISC::safe_cast<NL3D::CPSParticle *>(_Bindable);
p->enableGlobalColorLighting(((CButton *) GetDlgItem(ID_GLOBAL_COLOR_LIGHTING))->GetCheck() == 1);
touchPSState();
updateModifiedFlag();
}
//***********************************************************************************
void CLocatedBindableDialog::OnAlignOnMotion()
{
bool align = ((CButton *) GetDlgItem(IDC_ALIGN_ON_MOTION))->GetCheck() != 0;
NL3D::CPSFaceLookAt *fla = NLMISC::safe_cast<NL3D::CPSFaceLookAt *>(_Bindable);
fla->setAlignOnMotion(align);
updateValidWndForAlignOnMotion(align);
updateModifiedFlag();
}
//***********************************************************************************
void CLocatedBindableDialog::updateValidWndForAlignOnMotion(bool align)
{
BOOL enable = align ? FALSE : TRUE;
for(uint k = 0; k < _MotionBlurWnd.size(); ++k)
{
CEditAttribDlg *ead = dynamic_cast<CEditAttribDlg *>(_MotionBlurWnd[k]);
if (ead)
{
ead->EnableWindow(enable); // enable window not virtual in CWnd ...
}
else
{
_MotionBlurWnd[k]->EnableWindow(enable);
}
}
GetDlgItem(IDC_ZALIGN)->EnableWindow(enable);
}
//***********************************************************************************
void CLocatedBindableDialog::OnZtest()
{
UpdateData();
NL3D::CPSMaterial *mat = dynamic_cast<NL3D::CPSMaterial *>(_Bindable);
nlassert(mat);
mat->enableZTest(((CButton *) GetDlgItem(IDC_ZTEST))->GetCheck() != BST_UNCHECKED);
updateModifiedFlag();
}
// TODO: factor this code
static void concatEdit2Lines(CEdit &edit)
{
const uint lineLen= 1000;
uint n;
// retrieve the 2 lines.
char tmp0[2*lineLen];
char tmp1[lineLen];
n= edit.GetLine(0, tmp0, lineLen); tmp0[n]= 0;
n= edit.GetLine(1, tmp1, lineLen); tmp1[n]= 0;
// concat and update the CEdit.
edit.SetWindowText(strcat(tmp0, tmp1));
}
//***************************************************************************************************************************
void CLocatedBindableDialog::updateZBias()
{
CString value;
m_ZBias.GetWindowText(value);
float zbias = 0.f;
int dummy; // to test if end of string as no not wanted extra characters
if (sscanf((LPCTSTR) (value + "\n0"), "%f\n%d", &zbias, &dummy) == 2)
{
NLMISC::safe_cast<NL3D::CPSParticle *>(_Bindable)->setZBias(-zbias);
}
else
{
CString caption;
CString mess;
caption.LoadString(IDS_CAPTION_ERROR);
mess.LoadString(IDS_BAD_ZBIAS);
m_ZBias.SetWindowText("0.00");
MessageBox((LPCTSTR) mess, (LPCTSTR) caption, MB_ICONERROR);
NLMISC::safe_cast<NL3D::CPSParticle *>(_Bindable)->setZBias(0);
updateModifiedFlag();
}
}
//***************************************************************************************************************************
void CLocatedBindableDialog::OnChangeZbias()
{
UpdateData();
// Trick to track "Enter" keypress: CEdit are multiline. If GetLineCount()>1, then
// user has press enter.
if(m_ZBias.GetLineCount()>1)
{
// must ccat 2 lines of the CEdit.
concatEdit2Lines(m_ZBias);
updateZBias();
}
}
//***************************************************************************************************************************
void CLocatedBindableDialog::OnKillfocusZbias()
{
updateZBias();
}
//***************************************************************************************************************************
void CLocatedBindableDialog::OnZalign()
{
bool align = ((CButton *) GetDlgItem(IDC_ZALIGN))->GetCheck() != 0;
NL3D::CPSFaceLookAt *fla = NLMISC::safe_cast<NL3D::CPSFaceLookAt *>(_Bindable);
fla->setAlignOnZAxis(align);
updateModifiedFlag();
}