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"
23 #include "edit_morph_mesh_dlg.h"
25 #include "nel/3d/ps_particle.h"
26 #include "nel/3d/ps_mesh.h"
27 #include "nel/3d/particle_system_model.h"
29 #include "nel/misc/path.h"
31 ///==================================================================
32 CMeshDlg::CMeshDlg(CParticleWorkspace::CNode
*ownerNode
, NL3D::CPSShapeParticle
*sp
, CParticleDlg
*particleDlg
)
33 : _Node(ownerNode
), _ShapeParticle(sp
), _EMMD(NULL
), _ParticleDlg(particleDlg
)
35 //{{AFX_DATA_INIT(CMeshDlg)
43 _EMMD
->DestroyWindow();
49 ///==================================================================
50 void CMeshDlg::init(CWnd
*pParent
, sint x
, sint y
)
52 Create(IDD_CHOOSE_MESH
, pParent
);
55 r
.top
+= y
; r
.bottom
+= y
;
56 r
.right
+= x
; r
.left
+= x
;
63 ///==================================================================
64 void CMeshDlg::DoDataExchange(CDataExchange
* pDX
)
66 CDialog::DoDataExchange(pDX
);
67 //{{AFX_DATA_MAP(CMeshDlg)
68 DDX_Control(pDX
, IDC_MESH_ERROR
, m_MeshErrorMsg
);
69 DDX_Text(pDX
, IDC_SHAPE_NAME
, m_ShapeName
);
74 BEGIN_MESSAGE_MAP(CMeshDlg
, CDialog
)
75 //{{AFX_MSG_MAP(CMeshDlg)
76 ON_BN_CLICKED(IDC_BROWSE_SHAPE
, OnBrowseShape
)
77 ON_BN_CLICKED(IDC_ENABLE_MORPHING
, OnEnableMorphing
)
78 ON_BN_CLICKED(IDC_EDIT_MORPH
, OnEditMorph
)
82 ///==================================================================
83 void CMeshDlg::touchPSState()
85 if (_Node
&& _Node
->getPSModel())
87 _Node
->getPSModel()->touchTransparencyState();
88 _Node
->getPSModel()->touchLightableState();
92 ///==================================================================
93 void CMeshDlg::OnBrowseShape()
96 CFileDialog
fd(TRUE
, _T(".shape"), _T("*.shape"), 0, NULL
, this);
97 if (fd
.DoModal() == IDOK
)
100 std::string fullPath
= NLMISC::tStrToUtf8(fd
.GetPathName());
101 std::string fname
= NLMISC::CFile::getFilenameWithoutExtension(fullPath
);
102 std::string ext
= NLMISC::CFile::getExtension(fullPath
);
104 // Add search path for the texture
105 NLMISC::CPath::addSearchPath (NLMISC::CFile::getPath(fullPath
));
109 _ShapeParticle
->setShape(fname
+ "." + ext
);
110 m_ShapeName
= nlUtf8ToTStr(fname
+ "." + ext
);
113 catch (const NLMISC::Exception
&e
)
115 MessageBox(nlUtf8ToTStr(e
.what()), _T("shape loading error"));
118 updateMeshErrorString();
125 ///==================================================================
126 BOOL
CMeshDlg::OnInitDialog()
128 CDialog::OnInitDialog();
129 if (!dynamic_cast<NL3D::CPSConstraintMesh
*>(_ShapeParticle
))
131 // hide the unused fields
132 GetDlgItem(IDC_ENABLE_MORPHING
)->ShowWindow(SW_HIDE
);
133 GetDlgItem(IDC_EDIT_MORPH
)->ShowWindow(SW_HIDE
);
134 GetDlgItem(IDC_MORPH_FRAME
)->ShowWindow(SW_HIDE
);
135 m_ShapeName
= _ShapeParticle
->getShape().c_str();
140 NL3D::CPSConstraintMesh
*cm
= NLMISC::safe_cast
<NL3D::CPSConstraintMesh
*>(_ShapeParticle
);
141 if (cm
->getNumShapes() > 1)
143 ((CButton
*) GetDlgItem(IDC_ENABLE_MORPHING
))->SetCheck(TRUE
);
147 m_MeshErrorMsg
.SetTextColor(RGB(255, 0, 0));
149 return TRUE
; // return TRUE unless you set the focus to a control
150 // EXCEPTION: OCX Property Pages should return FALSE
153 ///==================================================================
154 void CMeshDlg::updateForMorph()
156 NL3D::CPSConstraintMesh
*cm
= NLMISC::safe_cast
<NL3D::CPSConstraintMesh
*>(_ShapeParticle
);
159 BOOL enable
= cm
->getNumShapes() > 1;
160 GetDlgItem(IDC_EDIT_MORPH
)->EnableWindow(enable
);
161 GetDlgItem(IDC_BROWSE_SHAPE
)->EnableWindow(!enable
);
162 GetDlgItem(IDC_SHAPE_NAME
)->EnableWindow(!enable
);
165 m_ShapeName
= nlUtf8ToTStr(cm
->getShape());
172 updateMeshErrorString();
176 ///==================================================================
177 void CMeshDlg::OnEnableMorphing()
179 NL3D::CPSConstraintMesh
*cm
= NLMISC::safe_cast
<NL3D::CPSConstraintMesh
*>(_ShapeParticle
);
180 if (((CButton
*) GetDlgItem(IDC_ENABLE_MORPHING
))->GetCheck())
182 // morphing enabled..
183 std::string currName
[2] = { cm
->getShape(), cm
->getShape()};
184 cm
->setShapes(currName
, 2);
189 std::string currName
= cm
->getShape(0);
190 cm
->setShape(currName
);
193 updateModifiedFlag();
194 updateMeshErrorString();
197 ///==================================================================
198 void CMeshDlg::OnEditMorph()
200 nlassert(_EMMD
== NULL
);
201 NL3D::CPSConstraintMesh
*cm
= NLMISC::safe_cast
<NL3D::CPSConstraintMesh
*>(_ShapeParticle
);
203 _EMMD
= new CEditMorphMeshDlg(_Node
, cm
, this, _ParticleDlg
, this);
207 ///==================================================================
208 void CMeshDlg::childPopupClosed(CWnd
*child
)
210 nlassert(_EMMD
== child
);
211 _EMMD
->DestroyWindow();
215 updateMeshErrorString();
219 ///==================================================================
220 BOOL
CMeshDlg::EnableWindow( BOOL bEnable
)
224 GetDlgItem(IDC_EDIT_MORPH
)->EnableWindow(FALSE
);
225 GetDlgItem(IDC_BROWSE_SHAPE
)->EnableWindow(FALSE
);
226 GetDlgItem(IDC_ENABLE_MORPHING
)->EnableWindow(FALSE
);
227 GetDlgItem(IDC_SHAPE_NAME
)->EnableWindow(FALSE
);
231 GetDlgItem(IDC_ENABLE_MORPHING
)->EnableWindow(TRUE
);
234 updateMeshErrorString();
235 return CDialog::EnableWindow(bEnable
);
238 ///==================================================================
239 void CMeshDlg::updateMeshErrorString()
241 GetDlgItem(IDC_MESH_ERROR
)->SetWindowText(_T(""));
242 NL3D::CPSConstraintMesh
*cm
= dynamic_cast<NL3D::CPSConstraintMesh
*>(_ShapeParticle
);
244 std::vector
<sint
> numVerts
;
245 cm
->getShapeNumVerts(numVerts
);
246 if (numVerts
.empty()) return;
247 if (numVerts
.size() == 1)
249 GetDlgItem(IDC_MESH_ERROR
)->SetWindowText((LPCTSTR
) getShapeErrorString(numVerts
[0]));
253 // display error msg for morphed meshs
254 bool hasError
= false;
255 for(uint k
= 0; k
< numVerts
.size(); ++k
)
265 CString errorInMorphMesh
;
266 errorInMorphMesh
.LoadString(IDS_ERROR_IN_MORPH_MESH
);
267 GetDlgItem(IDC_MESH_ERROR
)->SetWindowText((LPCTSTR
) errorInMorphMesh
);
272 //====================================================================
273 CString
CMeshDlg::getShapeErrorString(sint errorCode
)
278 case NL3D::CPSConstraintMesh::ShapeFileIsNotAMesh
: str
.LoadString(IDS_SHAPE_FILE_NOT_MESH
); break;
279 case NL3D::CPSConstraintMesh::ShapeFileNotLoaded
: str
.LoadString(IDS_SHAPE_NOT_LOADED
); break;
280 case NL3D::CPSConstraintMesh::ShapeHasTooMuchVertices
: str
.LoadString(IDS_TOO_MUCH_VERTICES
); break;