289 lines
7.6 KiB
C++
289 lines
7.6 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 "mesh_dlg.h"
|
||
|
#include "edit_morph_mesh_dlg.h"
|
||
|
//
|
||
|
#include "nel/3d/ps_particle.h"
|
||
|
#include "nel/3d/ps_mesh.h"
|
||
|
#include "nel/3d/particle_system_model.h"
|
||
|
//
|
||
|
#include "nel/misc/path.h"
|
||
|
|
||
|
///==================================================================
|
||
|
CMeshDlg::CMeshDlg(CParticleWorkspace::CNode *ownerNode, NL3D::CPSShapeParticle *sp, CParticleDlg *particleDlg)
|
||
|
: _Node(ownerNode), _ShapeParticle(sp), _EMMD(NULL), _ParticleDlg(particleDlg)
|
||
|
{
|
||
|
//{{AFX_DATA_INIT(CMeshDlg)
|
||
|
//}}AFX_DATA_INIT
|
||
|
}
|
||
|
|
||
|
CMeshDlg::~CMeshDlg()
|
||
|
{
|
||
|
if (_EMMD)
|
||
|
{
|
||
|
_EMMD->DestroyWindow();
|
||
|
delete _EMMD;
|
||
|
_EMMD = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///==================================================================
|
||
|
void CMeshDlg::init(CWnd *pParent, sint x, sint y)
|
||
|
{
|
||
|
Create(IDD_CHOOSE_MESH, pParent);
|
||
|
RECT r;
|
||
|
GetClientRect(&r);
|
||
|
r.top += y; r.bottom += y;
|
||
|
r.right += x; r.left += x;
|
||
|
MoveWindow(&r);
|
||
|
|
||
|
ShowWindow(SW_SHOW);
|
||
|
}
|
||
|
|
||
|
|
||
|
///==================================================================
|
||
|
void CMeshDlg::DoDataExchange(CDataExchange* pDX)
|
||
|
{
|
||
|
CDialog::DoDataExchange(pDX);
|
||
|
//{{AFX_DATA_MAP(CMeshDlg)
|
||
|
DDX_Control(pDX, IDC_MESH_ERROR, m_MeshErrorMsg);
|
||
|
DDX_Text(pDX, IDC_SHAPE_NAME, m_ShapeName);
|
||
|
//}}AFX_DATA_MAP
|
||
|
}
|
||
|
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CMeshDlg, CDialog)
|
||
|
//{{AFX_MSG_MAP(CMeshDlg)
|
||
|
ON_BN_CLICKED(IDC_BROWSE_SHAPE, OnBrowseShape)
|
||
|
ON_BN_CLICKED(IDC_ENABLE_MORPHING, OnEnableMorphing)
|
||
|
ON_BN_CLICKED(IDC_EDIT_MORPH, OnEditMorph)
|
||
|
//}}AFX_MSG_MAP
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
///==================================================================
|
||
|
void CMeshDlg::touchPSState()
|
||
|
{
|
||
|
if (_Node && _Node->getPSModel())
|
||
|
{
|
||
|
_Node->getPSModel()->touchTransparencyState();
|
||
|
_Node->getPSModel()->touchLightableState();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///==================================================================
|
||
|
void CMeshDlg::OnBrowseShape()
|
||
|
{
|
||
|
|
||
|
CFileDialog fd(TRUE, ".shape", "*.shape", 0, NULL, this);
|
||
|
if (fd.DoModal() == IDOK)
|
||
|
{
|
||
|
// Add to the path
|
||
|
char drive[256];
|
||
|
char dir[256];
|
||
|
char path[256];
|
||
|
char fname[256];
|
||
|
char ext[256];
|
||
|
|
||
|
|
||
|
// Add search path for the texture
|
||
|
_splitpath (fd.GetPathName(), drive, dir, fname, ext);
|
||
|
_makepath (path, drive, dir, NULL, NULL);
|
||
|
NLMISC::CPath::addSearchPath (path);
|
||
|
|
||
|
try
|
||
|
{
|
||
|
_ShapeParticle->setShape(std::string(fname) + ext);
|
||
|
m_ShapeName = (std::string(fname) + ext).c_str();
|
||
|
touchPSState();
|
||
|
}
|
||
|
catch (NLMISC::Exception &e)
|
||
|
{
|
||
|
MessageBox(e.what(), "shape loading error");
|
||
|
}
|
||
|
updateMeshErrorString();
|
||
|
}
|
||
|
UpdateData(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
///==================================================================
|
||
|
BOOL CMeshDlg::OnInitDialog()
|
||
|
{
|
||
|
CDialog::OnInitDialog();
|
||
|
if (!dynamic_cast<NL3D::CPSConstraintMesh *>(_ShapeParticle))
|
||
|
{
|
||
|
// hide the unused fields
|
||
|
GetDlgItem(IDC_ENABLE_MORPHING)->ShowWindow(SW_HIDE);
|
||
|
GetDlgItem(IDC_EDIT_MORPH)->ShowWindow(SW_HIDE);
|
||
|
GetDlgItem(IDC_MORPH_FRAME)->ShowWindow(SW_HIDE);
|
||
|
m_ShapeName = _ShapeParticle->getShape().c_str();
|
||
|
UpdateData(FALSE);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
NL3D::CPSConstraintMesh *cm = NLMISC::safe_cast<NL3D::CPSConstraintMesh *>(_ShapeParticle);
|
||
|
if (cm->getNumShapes() > 1)
|
||
|
{
|
||
|
((CButton *) GetDlgItem(IDC_ENABLE_MORPHING))->SetCheck(TRUE);
|
||
|
}
|
||
|
updateForMorph();
|
||
|
}
|
||
|
m_MeshErrorMsg.SetTextColor(RGB(255, 0, 0));
|
||
|
|
||
|
return TRUE; // return TRUE unless you set the focus to a control
|
||
|
// EXCEPTION: OCX Property Pages should return FALSE
|
||
|
}
|
||
|
|
||
|
///==================================================================
|
||
|
void CMeshDlg::updateForMorph()
|
||
|
{
|
||
|
NL3D::CPSConstraintMesh *cm = NLMISC::safe_cast<NL3D::CPSConstraintMesh *>(_ShapeParticle);
|
||
|
if (cm)
|
||
|
{
|
||
|
BOOL enable = cm->getNumShapes() > 1;
|
||
|
GetDlgItem(IDC_EDIT_MORPH)->EnableWindow(enable);
|
||
|
GetDlgItem(IDC_BROWSE_SHAPE)->EnableWindow(!enable);
|
||
|
GetDlgItem(IDC_SHAPE_NAME)->EnableWindow(!enable);
|
||
|
if (!enable)
|
||
|
{
|
||
|
m_ShapeName = cm->getShape().c_str();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_ShapeName = "";
|
||
|
}
|
||
|
}
|
||
|
updateMeshErrorString();
|
||
|
UpdateData(FALSE);
|
||
|
}
|
||
|
|
||
|
///==================================================================
|
||
|
void CMeshDlg::OnEnableMorphing()
|
||
|
{
|
||
|
NL3D::CPSConstraintMesh *cm = NLMISC::safe_cast<NL3D::CPSConstraintMesh *>(_ShapeParticle);
|
||
|
if (((CButton *) GetDlgItem(IDC_ENABLE_MORPHING))->GetCheck())
|
||
|
{
|
||
|
// morphing enabled..
|
||
|
std::string currName[2] = { cm->getShape(), cm->getShape()};
|
||
|
cm->setShapes(currName, 2);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// morphing disabled
|
||
|
std::string currName = cm->getShape(0);
|
||
|
cm->setShape(currName);
|
||
|
}
|
||
|
updateForMorph();
|
||
|
updateModifiedFlag();
|
||
|
updateMeshErrorString();
|
||
|
}
|
||
|
|
||
|
///==================================================================
|
||
|
void CMeshDlg::OnEditMorph()
|
||
|
{
|
||
|
nlassert(_EMMD == NULL);
|
||
|
NL3D::CPSConstraintMesh *cm = NLMISC::safe_cast<NL3D::CPSConstraintMesh *>(_ShapeParticle);
|
||
|
EnableWindow(FALSE);
|
||
|
_EMMD = new CEditMorphMeshDlg(_Node, cm, this, _ParticleDlg, this);
|
||
|
_EMMD->init(this);
|
||
|
}
|
||
|
|
||
|
///==================================================================
|
||
|
void CMeshDlg::childPopupClosed(CWnd *child)
|
||
|
{
|
||
|
nlassert(_EMMD == child);
|
||
|
_EMMD->DestroyWindow();
|
||
|
delete _EMMD;
|
||
|
_EMMD = NULL;
|
||
|
EnableWindow(TRUE);
|
||
|
updateMeshErrorString();
|
||
|
}
|
||
|
|
||
|
|
||
|
///==================================================================
|
||
|
BOOL CMeshDlg::EnableWindow( BOOL bEnable)
|
||
|
{
|
||
|
if (!bEnable)
|
||
|
{
|
||
|
GetDlgItem(IDC_EDIT_MORPH)->EnableWindow(FALSE);
|
||
|
GetDlgItem(IDC_BROWSE_SHAPE)->EnableWindow(FALSE);
|
||
|
GetDlgItem(IDC_ENABLE_MORPHING)->EnableWindow(FALSE);
|
||
|
GetDlgItem(IDC_SHAPE_NAME)->EnableWindow(FALSE);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
GetDlgItem(IDC_ENABLE_MORPHING)->EnableWindow(TRUE);
|
||
|
updateForMorph();
|
||
|
}
|
||
|
updateMeshErrorString();
|
||
|
return CDialog::EnableWindow(bEnable);
|
||
|
}
|
||
|
|
||
|
///==================================================================
|
||
|
void CMeshDlg::updateMeshErrorString()
|
||
|
{
|
||
|
GetDlgItem(IDC_MESH_ERROR)->SetWindowText("");
|
||
|
NL3D::CPSConstraintMesh *cm = dynamic_cast<NL3D::CPSConstraintMesh *>(_ShapeParticle);
|
||
|
if (!cm) return;
|
||
|
std::vector<sint> numVerts;
|
||
|
cm->getShapeNumVerts(numVerts);
|
||
|
if (numVerts.empty()) return;
|
||
|
if (numVerts.size() == 1)
|
||
|
{
|
||
|
GetDlgItem(IDC_MESH_ERROR)->SetWindowText((LPCTSTR) getShapeErrorString(numVerts[0]));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// display error msg for morphed meshs
|
||
|
bool hasError = false;
|
||
|
for(uint k = 0; k < numVerts.size(); ++k)
|
||
|
{
|
||
|
if (numVerts[k] < 0)
|
||
|
{
|
||
|
hasError = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (hasError)
|
||
|
{
|
||
|
CString errorInMorphMesh;
|
||
|
errorInMorphMesh.LoadString(IDS_ERROR_IN_MORPH_MESH);
|
||
|
GetDlgItem(IDC_MESH_ERROR)->SetWindowText((LPCTSTR) errorInMorphMesh);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//====================================================================
|
||
|
CString CMeshDlg::getShapeErrorString(sint errorCode)
|
||
|
{
|
||
|
CString str;
|
||
|
switch(errorCode)
|
||
|
{
|
||
|
case NL3D::CPSConstraintMesh::ShapeFileIsNotAMesh: str.LoadString(IDS_SHAPE_FILE_NOT_MESH); break;
|
||
|
case NL3D::CPSConstraintMesh::ShapeFileNotLoaded: str.LoadString(IDS_SHAPE_NOT_LOADED); break;
|
||
|
case NL3D::CPSConstraintMesh::ShapeHasTooMuchVertices: str.LoadString(IDS_TOO_MUCH_VERTICES); break;
|
||
|
default:
|
||
|
break;
|
||
|
};
|
||
|
return str;
|
||
|
}
|
||
|
|
||
|
|
||
|
|