1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "object_viewer.h"
22 #include "located_bindable_dialog.h"
26 #include "nel/3d/ps_located.h"
27 #include "nel/3d/ps_particle.h"
28 #include "nel/3d/ps_mesh.h"
29 #include "nel/3d/ps_force.h"
30 #include "nel/3d/ps_emitter.h"
31 #include "nel/3d/ps_zone.h"
32 #include "nel/3d/particle_system_model.h"
36 #include "texture_chooser.h"
37 #include "attrib_dlg.h"
38 #include "precomputed_rotations_dlg.h"
39 #include "tail_particle_dlg.h"
41 #include "texture_anim_dlg.h"
42 #include "particle_dlg.h"
43 #include "constraint_mesh_dlg.h"
44 #include "constraint_mesh_tex_dlg.h"
45 #include "ribbon_dlg.h"
48 using NL3D::CPSLocatedBindable
;
51 /////////////////////////////////////////////////////////////////////////////
52 // CLocatedBindableDialog dialog
55 //***********************************************************************************
56 CLocatedBindableDialog::CLocatedBindableDialog(CParticleWorkspace::CNode
*ownerNode
, NL3D::CPSLocatedBindable
*bindable
)
57 : _Node(ownerNode
), _Bindable(bindable
), _SizeCtrl(NULL
)
59 //{{AFX_DATA_INIT(CLocatedBindableDialog)
60 m_IndependantSizes
= FALSE
;
65 //***********************************************************************************
66 CLocatedBindableDialog::~CLocatedBindableDialog()
70 _SizeCtrl
->DestroyWindow();
75 //***********************************************************************************
76 void CLocatedBindableDialog::init(CParticleDlg
* pParent
)
78 Create(IDD_LOCATED_BINDABLE
, pParent
);
80 _ParticleDlg
= pParent
;
82 NL3D::CParticleSystem
*ps
= _Bindable
->getOwner()->getOwner();
83 if (ps
->isSharingEnabled())
85 GetDlgItem(IDC_NO_AUTO_LOD
)->ShowWindow(TRUE
);
86 if (ps
->isAutoLODEnabled() == false)
88 GetDlgItem(IDC_NO_AUTO_LOD
)->EnableWindow(FALSE
);
92 ((CButton
*) GetDlgItem(IDC_NO_AUTO_LOD
))->SetCheck(NLMISC::safe_cast
<NL3D::CPSParticle
*>(_Bindable
)->isAutoLODDisabled());
97 GetDlgItem(IDC_NO_AUTO_LOD
)->ShowWindow(FALSE
);
105 // control at the top of the sheet are not available for meshs & constraint meshes, so use that extra space
106 if (dynamic_cast<NL3D::CPSMesh
*>(_Bindable
) || dynamic_cast<NL3D::CPSConstraintMesh
*>(_Bindable
))
111 // has the particle a material ?
112 if (dynamic_cast<NL3D::CPSMaterial
*>(_Bindable
))
114 NL3D::CPSMaterial
*material
= dynamic_cast<NL3D::CPSMaterial
*>(_Bindable
);
116 m_BlendingMode
.SetCurSel((uint
) material
->getBlendingMode() );
118 ((CButton
*) GetDlgItem(IDC_ZTEST
))->SetCheck(material
->isZTestEnabled() ? BST_CHECKED
: BST_UNCHECKED
);
120 GetDlgItem(IDC_ZBIAS
)->SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.2f", -material
->getZBias())));
124 m_BlendingMode
.ShowWindow(SW_HIDE
);
125 GetDlgItem(IDC_BLENDING_MODE_STATIC
)->ShowWindow(SW_HIDE
);
126 GetDlgItem(IDC_ZTEST
)->ShowWindow(SW_HIDE
);
127 GetDlgItem(IDC_ZBIAS
)->ShowWindow(SW_HIDE
);
128 GetDlgItem(IDC_ZBIAS_TEXT
)->ShowWindow(SW_HIDE
);
130 GetDlgItem(IDC_ALIGN_ON_MOTION
)->ShowWindow(SW_HIDE
);
131 GetDlgItem(IDC_ZALIGN
)->ShowWindow(SW_HIDE
);
132 // enable disable z-test
134 if (dynamic_cast<NL3D::CPSParticle
*>(_Bindable
))
136 NL3D::CPSParticle
*p
= (NL3D::CPSParticle
*) _Bindable
;
138 // check support for lighting
139 if (p
->supportGlobalColorLighting())
141 GetDlgItem(ID_GLOBAL_COLOR_LIGHTING
)->ShowWindow(SW_SHOW
);
142 // if global color lighting is forced for all objects, don't allow to modify
143 GetDlgItem(ID_GLOBAL_COLOR_LIGHTING
)->EnableWindow(ps
->getForceGlobalColorLightingFlag() ? FALSE
: TRUE
);
144 ((CButton
*) GetDlgItem(ID_GLOBAL_COLOR_LIGHTING
))->SetCheck(p
->usesGlobalColorLighting() ? 1 : 0);
148 GetDlgItem(ID_GLOBAL_COLOR_LIGHTING
)->ShowWindow(SW_HIDE
);
150 // check support for color
151 if (dynamic_cast<NL3D::CPSColoredParticle
*>(_Bindable
))
154 CAttribDlgRGBA
*ad
= new CAttribDlgRGBA("PARTICLE_COLOR", _Node
);
157 _ColorWrapper
.S
= dynamic_cast<NL3D::CPSColoredParticle
*>(_Bindable
);
158 ad
->setWrapper(&_ColorWrapper
);
159 ad
->setSchemeWrapper(&_ColorWrapper
);
161 HBITMAP bmh
= LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_PARTICLE_COLOR
));
162 ad
->init(bmh
, xPos
, yPos
, this);
163 ad
->GetClientRect(&rect
);
164 yPos
+= rect
.bottom
+ 3;
170 yPos
+= updateSizeControl();
172 // check support for angle 2D
173 if (dynamic_cast<NL3D::CPSRotated2DParticle
*>(_Bindable
))
176 CAttribDlgFloat
*ad
= new CAttribDlgFloat("PARTICLE_ANGLE2D", _Node
, 0.f
, 256.f
);
179 _Angle2DWrapper
.S
= dynamic_cast<NL3D::CPSRotated2DParticle
*>(_Bindable
);
180 ad
->setWrapper(&_Angle2DWrapper
);
181 ad
->setSchemeWrapper(&_Angle2DWrapper
);
183 HBITMAP bmh
= LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_PARTICLE_ANGLE
));
184 ad
->init(bmh
, xPos
, yPos
, this);
185 ad
->GetClientRect(&rect
);
186 yPos
+= rect
.bottom
+ 3;
191 CAttribDlgPlaneBasis
*pb
= NULL
;
193 // check support for plane basis
194 if (dynamic_cast<NL3D::CPSRotated3DPlaneParticle
*>(_Bindable
))
196 pb
= new CAttribDlgPlaneBasis("PARTICLE_PLANE_BASIS", _Node
);
198 _PlaneBasisWrapper
.S
= dynamic_cast<NL3D::CPSRotated3DPlaneParticle
*>(_Bindable
);
199 pb
->setWrapper(&_PlaneBasisWrapper
);
200 pb
->setSchemeWrapper(&_PlaneBasisWrapper
);
201 HBITMAP bmh
= LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BASIS
));
202 pb
->init(bmh
, xPos
, yPos
, this);
203 pb
->GetClientRect(&rect
);
204 yPos
+= rect
.bottom
+ 3;
208 // check support for precomputed rotations
209 if (dynamic_cast<NL3D::CPSHintParticleRotateTheSame
*>(_Bindable
))
211 CPrecomputedRotationsDlg
*pr
= new CPrecomputedRotationsDlg(_Node
, dynamic_cast<NL3D::CPSHintParticleRotateTheSame
*>(_Bindable
), pb
);
213 pr
->init(this, xPos
, yPos
);
214 pr
->GetClientRect(&rect
);
215 yPos
+= rect
.bottom
+ 3;
218 // if we're dealing with a face look at, motion blur can be tuned
219 if (dynamic_cast<NL3D::CPSFaceLookAt
*>(_Bindable
))
221 NL3D::CPSFaceLookAt
*fla
= static_cast<NL3D::CPSFaceLookAt
*>(_Bindable
);
222 CEditableRangeFloat
*mbc
= new CEditableRangeFloat(std::string("MOTION_BLUR_COEFF"), _Node
, 0, 5);
224 _MotionBlurWnd
.push_back(mbc
);
225 _MotionBlurCoeffWrapper
.P
= fla
;
226 mbc
->setWrapper(&_MotionBlurCoeffWrapper
);
227 mbc
->init(xPos
+ 140, yPos
, this);
228 CStatic
*s
= new CStatic
;
230 _MotionBlurWnd
.push_back(s
);
231 s
->Create(_T("Fake motion blur coeff."), SS_LEFT
, CRect(xPos
, yPos
+ 16, xPos
+ 139, yPos
+ 48), this);
232 s
->SetFont(CFont::FromHandle((HFONT
) GetStockObject(DEFAULT_GUI_FONT
)));
233 s
->ShowWindow(SW_SHOW
);
234 mbc
->GetClientRect(&rect
);
235 yPos
+= rect
.bottom
+ 3;
236 mbc
= new CEditableRangeFloat(std::string("MOTION_BLUR_THRESHOLD"), _Node
, 0, 5);
238 _MotionBlurWnd
.push_back(mbc
);
239 _MotionBlurThresholdWrapper
.P
= fla
;
240 mbc
->setWrapper(&_MotionBlurThresholdWrapper
);
241 mbc
->init(xPos
+ 140, yPos
, this);
244 _MotionBlurWnd
.push_back(s
);
245 s
->Create(_T("Fake motion blur threshold."), SS_LEFT
, CRect(xPos
, yPos
+ 16, xPos
+ 139, yPos
+ 48), this);
246 s
->SetFont(CFont::FromHandle((HFONT
) GetStockObject(DEFAULT_GUI_FONT
)));
247 s
->ShowWindow(SW_SHOW
);
248 mbc
->GetClientRect(&rect
);
249 yPos
+= rect
.bottom
+ 3;
250 GetDlgItem(IDC_ALIGN_ON_MOTION
)->ShowWindow(SW_SHOW
);
251 GetDlgItem(IDC_ZALIGN
)->ShowWindow(SW_SHOW
);
252 ((CButton
*) GetDlgItem(IDC_ALIGN_ON_MOTION
))->SetCheck(fla
->getAlignOnMotion());
253 ((CButton
*) GetDlgItem(IDC_ZALIGN
))->SetCheck(fla
->getAlignOnZAxis());
254 updateValidWndForAlignOnMotion(fla
->getAlignOnMotion());
257 // if we're dealing with a shockwave, we add dlg for the radius cut, and the number of segments
258 if (dynamic_cast<NL3D::CPSShockWave
*>(_Bindable
))
260 NL3D::CPSShockWave
*sw
= static_cast<NL3D::CPSShockWave
*>(_Bindable
);
261 CEditableRangeFloat
*rc
= new CEditableRangeFloat(std::string("RADIUS CUT"), _Node
, 0, 1);
263 _RadiusCutWrapper
.S
= sw
;
264 rc
->setWrapper(&_RadiusCutWrapper
);
265 rc
->init(xPos
+ 140, yPos
, this);
266 CStatic
*s
= new CStatic
;
268 s
->Create(_T("Radius cut."), SS_LEFT
, CRect(xPos
, yPos
+ 16, xPos
+ 139, yPos
+ 48), this);
269 s
->SetFont(CFont::FromHandle((HFONT
) GetStockObject(DEFAULT_GUI_FONT
)));
270 s
->ShowWindow(SW_SHOW
);
273 rc
->GetClientRect(&rect
);
274 yPos
+= rect
.bottom
+ 3;
276 CEditableRangeUInt
*snbs
= new CEditableRangeUInt(std::string("SHOCK WAVE NB SEG"), _Node
, 3, 24);
278 _ShockWaveNbSegWrapper
.S
= sw
;
279 snbs
->enableLowerBound(3, false);
280 snbs
->setWrapper(&_ShockWaveNbSegWrapper
);
281 snbs
->init(xPos
+ 140, yPos
, this);
285 s
->Create(_T("Nb segs"), SS_LEFT
, CRect(xPos
, yPos
+ 16, xPos
+ 139, yPos
+ 48), this);
286 s
->ShowWindow(SW_SHOW
);
288 snbs
->GetClientRect(&rect
);
289 yPos
+= rect
.bottom
+ 3;
292 CEditableRangeFloat
*uvd
= new CEditableRangeFloat(std::string("TEX UFACTOR"), _Node
, 0, 5);
294 _ShockWaveUFactorWrapper
.S
= sw
;
295 uvd
->setWrapper(&_ShockWaveUFactorWrapper
);
296 uvd
->init(xPos
+ 140, yPos
, this);
299 s
->Create(_T("Texture U factor :"), SS_LEFT
, CRect(xPos
, yPos
+ 16, xPos
+ 139, yPos
+ 48), this);
300 s
->ShowWindow(SW_SHOW
);
301 uvd
->GetClientRect(&rect
);
302 yPos
+= rect
.bottom
+ 3;
307 if (dynamic_cast<NL3D::CPSFanLight
*>(_Bindable
))
309 CEditableRangeUInt
*nbf
= new CEditableRangeUInt(std::string("NB_FANS"), _Node
, 3, 127);
311 nbf
->enableLowerBound(3, false);
312 nbf
->enableUpperBound(128, true);
313 _FanLightWrapper
.P
= dynamic_cast<NL3D::CPSFanLight
*>(_Bindable
);
314 nbf
->setWrapper(&_FanLightWrapper
);
315 nbf
->init(xPos
+ 140, yPos
, this);
316 CStatic
*s
= new CStatic
;
318 s
->Create(_T("Nb fan lights :"), SS_LEFT
, CRect(xPos
, yPos
+ 16, xPos
+ 139, yPos
+ 48), this);
319 s
->SetFont(CFont::FromHandle((HFONT
) GetStockObject(DEFAULT_GUI_FONT
)));
320 s
->ShowWindow(SW_SHOW
);
322 nbf
->GetClientRect(&rect
);
323 yPos
+= rect
.bottom
+ 3;
325 nbf
= new CEditableRangeUInt(std::string("PHASE_SMOOTHNESS"), _Node
, 0, 31);
327 nbf
->enableUpperBound(32, true);
328 _FanLightSmoothnessWrapper
.P
= static_cast<NL3D::CPSFanLight
*>(_Bindable
);
329 nbf
->setWrapper(&_FanLightSmoothnessWrapper
);
330 nbf
->init(xPos
+ 140, yPos
, this);
333 s
->Create(_T("Phase smoothnes:"), SS_LEFT
, CRect(xPos
, yPos
+ 16, xPos
+ 139, yPos
+ 48), this);
334 s
->ShowWindow(SW_SHOW
);
336 nbf
->GetClientRect(&rect
);
337 yPos
+= rect
.bottom
+ 3;
339 CEditableRangeFloat
*nbfp
= new CEditableRangeFloat(std::string("FAN_LIGHT_PHASE"), _Node
, 0, 4.f
);
341 _FanLightPhaseWrapper
.P
= static_cast<NL3D::CPSFanLight
*>(_Bindable
);
342 nbfp
->setWrapper(&_FanLightPhaseWrapper
);
343 nbfp
->init(xPos
+ 140, yPos
, this);
346 s
->Create(_T("Fan light speed :"), SS_LEFT
, CRect(xPos
, yPos
+ 16, xPos
+ 139, yPos
+ 48), this);
347 s
->ShowWindow(SW_SHOW
);
349 nbf
->GetClientRect(&rect
);
350 yPos
+= rect
.bottom
+ 3;
352 nbfp
= new CEditableRangeFloat(std::string("FAN_LIGHT_INTENSITY"), _Node
, 0, 4.f
);
354 _FanLightIntensityWrapper
.P
= static_cast<NL3D::CPSFanLight
*>(_Bindable
);
355 nbfp
->setWrapper(&_FanLightIntensityWrapper
);
356 nbfp
->init(xPos
+ 140, yPos
, this);
359 s
->Create(_T("Fan light intensity:"), SS_LEFT
, CRect(xPos
, yPos
+ 16, xPos
+ 139, yPos
+ 48), this);
360 s
->ShowWindow(SW_SHOW
);
362 nbf
->GetClientRect(&rect
);
363 yPos
+= rect
.bottom
+ 3;
369 if (dynamic_cast<NL3D::CPSTailParticle
*>(_Bindable
))
371 CEditableRangeUInt
*nbs
;
372 if (!dynamic_cast<NL3D::CPSRibbonLookAt
*>(_Bindable
))
374 nbs
= new CEditableRangeUInt(std::string("TAIL_NB_SEGS_"), _Node
, 2, 16);
375 nbs
->enableLowerBound(1, true);
379 nbs
= new CEditableRangeUInt(std::string("LOOKAT_RIBBON_TAIL_NB_SEGS_"), _Node
, 2, 16);
380 nbs
->enableLowerBound(1, true);
385 if (dynamic_cast<NL3D::CPSTailDot
*>(_Bindable
))
387 nbs
->enableUpperBound(256, true);
391 _TailParticleWrapper
.P
= dynamic_cast<NL3D::CPSTailParticle
*>(_Bindable
);
392 nbs
->setWrapper(&_TailParticleWrapper
);
393 nbs
->init(xPos
+ 140, yPos
, this);
394 CStatic
*s
= new CStatic
;
396 s
->Create(_T("Nb segs :"), SS_LEFT
, CRect(xPos
, yPos
+ 16, xPos
+ 139, yPos
+ 48), this);
397 s
->SetFont(CFont::FromHandle((HFONT
) GetStockObject(DEFAULT_GUI_FONT
)));
398 s
->ShowWindow(SW_SHOW
);
400 nbs
->GetClientRect(&rect
);
401 yPos
+= rect
.bottom
+ 3;
403 CTailParticleDlg
*tpd
= new CTailParticleDlg(_Node
, dynamic_cast<NL3D::CPSTailParticle
*>(_Bindable
));
405 tpd
->init(this, xPos
, yPos
);
407 tpd
->GetClientRect(&rect
);
408 yPos
+= rect
.bottom
+ 3;
413 if (dynamic_cast<NL3D::CPSShapeParticle
*>(_Bindable
))
415 CMeshDlg
*md
= new CMeshDlg(_Node
, dynamic_cast<NL3D::CPSShapeParticle
*>(_Bindable
), _ParticleDlg
);
416 md
->init(this, xPos
, yPos
);
417 md
->GetClientRect(&rect
);
418 yPos
+= rect
.bottom
+ 3;
422 // constraint mesh particle
423 if (dynamic_cast<NL3D::CPSConstraintMesh
*>(_Bindable
))
425 CConstraintMeshDlg
*cmd
= new CConstraintMeshDlg(static_cast<NL3D::CPSConstraintMesh
*>(_Bindable
));
426 cmd
->init(xPos
, yPos
, this);
427 cmd
->GetClientRect(&rect
);
428 yPos
+= rect
.bottom
+ 3;
429 CConstraintMeshTexDlg
*cmtd
= new CConstraintMeshTexDlg(static_cast<NL3D::CPSConstraintMesh
*>(_Bindable
),
431 cmtd
->init(xPos
, yPos
, this);
432 cmtd
->GetClientRect(&rect
);
433 yPos
+= rect
.bottom
+ 3;
440 // check support for animated texture
441 if (dynamic_cast<NL3D::CPSTexturedParticle
*>(_Bindable
))
443 CTextureAnimDlg
*td
= new CTextureAnimDlg(_Node
,
444 dynamic_cast<NL3D::CPSTexturedParticle
*>(_Bindable
),
445 dynamic_cast<NL3D::CPSMultiTexturedParticle
*>(_Bindable
)
449 td
->init(xPos
, yPos
, this);
450 td
->GetClientRect(&rect
);
451 yPos
+= rect
.bottom
+ 3;
454 // unanimated texture
455 if (dynamic_cast<NL3D::CPSTexturedParticleNoAnim
*>(_Bindable
))
457 NL3D::CPSTexturedParticleNoAnim
*tp
= dynamic_cast<NL3D::CPSTexturedParticleNoAnim
*>(_Bindable
);
458 _TextureNoAnimWrapper
.TP
= tp
;
459 CTextureChooser
*tc
= new CTextureChooser(dynamic_cast<NL3D::CPSMultiTexturedParticle
*>(_Bindable
), _Node
);
460 tc
->enableRemoveButton();
461 tc
->setWrapper(&_TextureNoAnimWrapper
);
464 tc
->init(xPos
, yPos
, this);
465 tc
->GetClientRect(&rect
);
466 yPos
+= rect
.bottom
+ 3;
469 // ribbon texture (doesn't support texture animation for now)
470 if (dynamic_cast<NL3D::CPSRibbon
*>(_Bindable
))
473 // add dialog for uv tuning with ribbon
474 CEditableRangeFloat
*uvd
= new CEditableRangeFloat(std::string("RIBBON UFACTOR"), _Node
, 0, 5);
476 _RibbonUFactorWrapper
.R
= static_cast<NL3D::CPSRibbon
*>(_Bindable
);
477 uvd
->setWrapper(&_RibbonUFactorWrapper
);
478 uvd
->init(xPos
+ 140, yPos
, this);
479 CStatic
*s
= new CStatic
;
481 s
->Create(_T("Texture U factor :"), SS_LEFT
, CRect(xPos
, yPos
+ 16, xPos
+ 139, yPos
+ 48), this);
482 s
->SetFont(CFont::FromHandle((HFONT
) GetStockObject(DEFAULT_GUI_FONT
)));
483 s
->ShowWindow(SW_SHOW
);
484 uvd
->GetClientRect(&rect
);
485 yPos
+= rect
.bottom
+ 3;
487 uvd
= new CEditableRangeFloat(std::string("RIBBON VFACTOR"), _Node
, 0, 5);
489 _RibbonVFactorWrapper
.R
= static_cast<NL3D::CPSRibbon
*>(_Bindable
);
490 uvd
->setWrapper(&_RibbonVFactorWrapper
);
491 uvd
->init(xPos
+ 140, yPos
, this);
494 s
->Create(_T("Texture V factor :"), SS_LEFT
, CRect(xPos
, yPos
+ 16, xPos
+ 139, yPos
+ 48), this);
495 s
->SetFont(CFont::FromHandle((HFONT
) GetStockObject(DEFAULT_GUI_FONT
)));
496 s
->ShowWindow(SW_SHOW
);
497 uvd
->GetClientRect(&rect
);
498 yPos
+= rect
.bottom
+ 3;
502 if (dynamic_cast<NL3D::CPSRibbonBase
*>(_Bindable
))
505 // add dialog for uv tuning with ribbon
506 CEditableRangeFloat
*sd
= new CEditableRangeFloat(std::string("SEGMENT DURATION"), _Node
, 0.05f
, 0.5f
);
507 sd
->enableLowerBound(0, true);
509 _SegDurationWrapper
.R
= static_cast<NL3D::CPSRibbonLookAt
*>(_Bindable
);
510 sd
->setWrapper(&_SegDurationWrapper
);
511 sd
->init(xPos
+ 140, yPos
, this);
512 CStatic
*s
= new CStatic
;
514 s
->Create(_T("Seg Duration :"), SS_LEFT
, CRect(xPos
, yPos
+ 16, xPos
+ 139, yPos
+ 48), this);
515 s
->SetFont(CFont::FromHandle((HFONT
) GetStockObject(DEFAULT_GUI_FONT
)));
516 s
->ShowWindow(SW_SHOW
);
517 sd
->GetClientRect(&rect
);
518 yPos
+= rect
.bottom
+ 3;
521 // 'look at' independant sizes
522 bool isLookAt
= dynamic_cast<NL3D::CPSFaceLookAt
*>(_Bindable
) != NULL
;
523 GetDlgItem(IDC_INDE_SIZES
)->ShowWindow(isLookAt
? SW_SHOW
: SW_HIDE
);
524 GetDlgItem(IDC_SIZE_WIDTH
)->ShowWindow(isLookAt
? SW_SHOW
: SW_HIDE
);
525 GetDlgItem(IDC_SIZE_HEIGHT
)->ShowWindow(isLookAt
? SW_SHOW
: SW_HIDE
);
526 GetDlgItem(IDC_WIDTH_HEIGHT_BOX
)->ShowWindow(isLookAt
? SW_SHOW
: SW_HIDE
);
527 ((CButton
*) GetDlgItem(IDC_SIZE_WIDTH
))->SetCheck(1);
530 NL3D::CPSFaceLookAt
*la
= static_cast<NL3D::CPSFaceLookAt
*>(_Bindable
);
531 m_IndependantSizes
= la
->hasIndependantSizes();
532 ((CButton
*) GetDlgItem(IDC_INDE_SIZES
))->SetCheck(m_IndependantSizes
);
533 updateIndependantSizes();
536 /// new ribbon base class
537 if (dynamic_cast<NL3D::CPSRibbonBase
*>(_Bindable
))
539 CRibbonDlg
*rd
= new CRibbonDlg(_Node
, static_cast<NL3D::CPSRibbonBase
*>(_Bindable
),
541 rd
->init(this, xPos
, yPos
);
543 rd
->GetClientRect(&rect
);
544 yPos
+= rect
.bottom
+ 3;
551 //***********************************************************************************
552 void CLocatedBindableDialog::DoDataExchange(CDataExchange
* pDX
)
554 CDialog::DoDataExchange(pDX
);
555 //{{AFX_DATA_MAP(CLocatedBindableDialog)
556 DDX_Control(pDX
, IDC_ZBIAS
, m_ZBias
);
557 DDX_Control(pDX
, IDC_BLENDING_MODE
, m_BlendingMode
);
558 DDX_Check(pDX
, IDC_INDE_SIZES
, m_IndependantSizes
);
563 BEGIN_MESSAGE_MAP(CLocatedBindableDialog
, CDialog
)
564 //{{AFX_MSG_MAP(CLocatedBindableDialog)
565 ON_CBN_SELCHANGE(IDC_BLENDING_MODE
, OnSelchangeBlendingMode
)
566 ON_BN_CLICKED(IDC_INDE_SIZES
, OnIndeSizes
)
567 ON_BN_CLICKED(IDC_SIZE_WIDTH
, OnSizeWidth
)
568 ON_BN_CLICKED(IDC_SIZE_HEIGHT
, OnSizeHeight
)
569 ON_BN_CLICKED(IDC_NO_AUTO_LOD
, OnNoAutoLod
)
570 ON_BN_CLICKED(ID_GLOBAL_COLOR_LIGHTING
, OnGlobalColorLighting
)
571 ON_BN_CLICKED(IDC_ALIGN_ON_MOTION
, OnAlignOnMotion
)
572 ON_BN_CLICKED(IDC_ZTEST
, OnZtest
)
573 ON_EN_CHANGE(IDC_ZBIAS
, OnChangeZbias
)
574 ON_EN_KILLFOCUS(IDC_ZBIAS
, OnKillfocusZbias
)
575 ON_BN_CLICKED(IDC_ZALIGN
, OnZalign
)
579 /////////////////////////////////////////////////////////////////////////////
580 // CLocatedBindableDialog message handlers
582 //====================================================================
583 void CLocatedBindableDialog::touchPSState()
585 if (_Node
&& _Node
->getPSModel())
587 _Node
->getPSModel()->touchTransparencyState();
588 _Node
->getPSModel()->touchLightableState();
593 //***********************************************************************************
594 void CLocatedBindableDialog::OnSelchangeBlendingMode()
597 NL3D::CPSMaterial
*m
= dynamic_cast<NL3D::CPSMaterial
*>(_Bindable
);
599 m
->setBlendingMode( (NL3D::CPSMaterial::TBlendingMode
) m_BlendingMode
.GetCurSel());
601 updateModifiedFlag();
605 //***********************************************************************************
606 void CLocatedBindableDialog::updateIndependantSizes()
609 // make sure we are dealing with 'LookAt' for now
610 nlassert(dynamic_cast<NL3D::CPSFaceLookAt
*>(_Bindable
));
612 GetDlgItem(IDC_SIZE_WIDTH
)->EnableWindow(m_IndependantSizes
);
613 GetDlgItem(IDC_SIZE_HEIGHT
)->EnableWindow(m_IndependantSizes
);
617 //***********************************************************************************
618 // user asked for independant sizes
619 void CLocatedBindableDialog::OnIndeSizes()
622 // make sure we are dealing with 'LookAt' for now
623 nlassert(dynamic_cast<NL3D::CPSFaceLookAt
*>(_Bindable
));
624 NL3D::CPSFaceLookAt
*la
= static_cast<NL3D::CPSFaceLookAt
*>(_Bindable
);
625 la
->setIndependantSizes(m_IndependantSizes
? true : false /* VCC warning*/);
626 updateIndependantSizes();
628 updateModifiedFlag();
631 //***********************************************************************************
632 uint
CLocatedBindableDialog::updateSizeControl()
635 if (!dynamic_cast<NL3D::CPSSizedParticle
*>(_Bindable
)) return 0;
636 // if a previous control was there, remove it
639 _SizeCtrl
->DestroyWindow();
644 NL3D::CPSFaceLookAt
*fla
= dynamic_cast<NL3D::CPSFaceLookAt
*>(_Bindable
);
646 if (fla
&& fla
->hasIndependantSizes())
648 int editWidth
= (((CButton
*) GetDlgItem(IDC_SIZE_WIDTH
))->GetCheck());
649 _SizeCtrl
= new CAttribDlgFloat(editWidth
? "PARTICLE_WIDTH" : "PARTICLE_HEIGHT", _Node
, 0.f
, 1.f
);
652 if (editWidth
) // wrap to the wanted size
654 _SizeWrapper
.S
= fla
;
658 _SizeWrapper
.S
= &fla
->getSecondSize();
660 _SizeCtrl
->setWrapper(&_SizeWrapper
);
661 _SizeCtrl
->setSchemeWrapper(&_SizeWrapper
);
663 bmh
= LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(editWidth
? IDB_PARTICLE_WIDTH
: IDB_PARTICLE_HEIGHT
));
665 else // general case. Wrap to the size interface and the appropriate dialog
667 _SizeCtrl
= new CAttribDlgFloat("PARTICLE_SIZE", _Node
, 0.f
, 1.f
);
669 _SizeWrapper
.S
= dynamic_cast<NL3D::CPSSizedParticle
*>(_Bindable
);
670 _SizeCtrl
->setWrapper(&_SizeWrapper
);
671 _SizeCtrl
->setSchemeWrapper(&_SizeWrapper
);
673 bmh
= LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_PARTICLE_SIZE
));
676 _SizeCtrl
->init(bmh
, _SizeCtrlX
, _SizeCtrlY
, this);
677 _SizeCtrl
->GetClientRect(&rect
);
678 return rect
.bottom
+ 3;
681 //***********************************************************************************
682 void CLocatedBindableDialog::OnSizeWidth()
687 //***********************************************************************************
688 void CLocatedBindableDialog::OnSizeHeight()
693 //***********************************************************************************
694 void CLocatedBindableDialog::OnNoAutoLod()
696 NL3D::CPSParticle
*p
= NLMISC::safe_cast
<NL3D::CPSParticle
*>(_Bindable
);
697 p
->disableAutoLOD(((CButton
*) GetDlgItem(IDC_NO_AUTO_LOD
))->GetCheck() != 0);
698 updateModifiedFlag();
701 //***********************************************************************************
702 void CLocatedBindableDialog::OnGlobalColorLighting()
704 NL3D::CPSParticle
*p
= NLMISC::safe_cast
<NL3D::CPSParticle
*>(_Bindable
);
705 p
->enableGlobalColorLighting(((CButton
*) GetDlgItem(ID_GLOBAL_COLOR_LIGHTING
))->GetCheck() == 1);
707 updateModifiedFlag();
710 //***********************************************************************************
711 void CLocatedBindableDialog::OnAlignOnMotion()
713 bool align
= ((CButton
*) GetDlgItem(IDC_ALIGN_ON_MOTION
))->GetCheck() != 0;
714 NL3D::CPSFaceLookAt
*fla
= NLMISC::safe_cast
<NL3D::CPSFaceLookAt
*>(_Bindable
);
715 fla
->setAlignOnMotion(align
);
716 updateValidWndForAlignOnMotion(align
);
717 updateModifiedFlag();
720 //***********************************************************************************
721 void CLocatedBindableDialog::updateValidWndForAlignOnMotion(bool align
)
723 BOOL enable
= align
? FALSE
: TRUE
;
724 for(uint k
= 0; k
< _MotionBlurWnd
.size(); ++k
)
726 CEditAttribDlg
*ead
= dynamic_cast<CEditAttribDlg
*>(_MotionBlurWnd
[k
]);
729 ead
->EnableWindow(enable
); // enable window not virtual in CWnd ...
733 _MotionBlurWnd
[k
]->EnableWindow(enable
);
736 GetDlgItem(IDC_ZALIGN
)->EnableWindow(enable
);
739 //***********************************************************************************
740 void CLocatedBindableDialog::OnZtest()
743 NL3D::CPSMaterial
*mat
= dynamic_cast<NL3D::CPSMaterial
*>(_Bindable
);
745 mat
->enableZTest(((CButton
*) GetDlgItem(IDC_ZTEST
))->GetCheck() != BST_UNCHECKED
);
746 updateModifiedFlag();
749 // TODO: factor this code
750 static void concatEdit2Lines(CEdit
&edit
)
752 const uint lineLen
= 1000;
754 // retrieve the 2 lines.
755 TCHAR tmp0
[2*lineLen
];
757 n
= edit
.GetLine(0, tmp0
, lineLen
); tmp0
[n
]= 0;
758 n
= edit
.GetLine(1, tmp1
, lineLen
); tmp1
[n
]= 0;
759 // concat and update the CEdit.
760 edit
.SetWindowText(_tcscat(tmp0
, tmp1
));
763 //***************************************************************************************************************************
764 void CLocatedBindableDialog::updateZBias()
767 m_ZBias
.GetWindowText(value
);
769 int dummy
; // to test if end of string as no not wanted extra characters
770 if (_stscanf((LPCTSTR
)(value
+ _T("\n0")), _T("%f\n%d"), &zbias
, &dummy
) == 2)
772 NLMISC::safe_cast
<NL3D::CPSParticle
*>(_Bindable
)->setZBias(-zbias
);
778 caption
.LoadString(IDS_CAPTION_ERROR
);
779 mess
.LoadString(IDS_BAD_ZBIAS
);
780 m_ZBias
.SetWindowText(_T("0.00"));
781 MessageBox((LPCTSTR
) mess
, (LPCTSTR
) caption
, MB_ICONERROR
);
782 NLMISC::safe_cast
<NL3D::CPSParticle
*>(_Bindable
)->setZBias(0);
783 updateModifiedFlag();
787 //***************************************************************************************************************************
788 void CLocatedBindableDialog::OnChangeZbias()
791 // Trick to track "Enter" keypress: CEdit are multiline. If GetLineCount()>1, then
792 // user has press enter.
793 if(m_ZBias
.GetLineCount()>1)
795 // must ccat 2 lines of the CEdit.
796 concatEdit2Lines(m_ZBias
);
801 //***************************************************************************************************************************
802 void CLocatedBindableDialog::OnKillfocusZbias()
807 //***************************************************************************************************************************
808 void CLocatedBindableDialog::OnZalign()
810 bool align
= ((CButton
*) GetDlgItem(IDC_ZALIGN
))->GetCheck() != 0;
811 NL3D::CPSFaceLookAt
*fla
= NLMISC::safe_cast
<NL3D::CPSFaceLookAt
*>(_Bindable
);
812 fla
->setAlignOnZAxis(align
);
813 updateModifiedFlag();