123
This commit is contained in:
418
Editor/ShapePanel.cpp
Normal file
418
Editor/ShapePanel.cpp
Normal file
@@ -0,0 +1,418 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: shapepanel.cpp
|
||||
// Version: v1.00
|
||||
// Created: 28/2/2002 by Timur.
|
||||
// Compilers: Visual C++.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ShapePanel.h"
|
||||
|
||||
#include "Viewport.h"
|
||||
#include "Objects\\ShapeObject.h"
|
||||
#include "EditTool.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CEditShapeObjectTool : public CEditTool
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CEditShapeObjectTool)
|
||||
|
||||
CEditShapeObjectTool();
|
||||
~CEditShapeObjectTool();
|
||||
|
||||
// Ovverides from CEditTool
|
||||
bool MouseCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags );
|
||||
|
||||
virtual void SetUserData( void *userData );
|
||||
|
||||
// Delete itself.
|
||||
void Release() { delete this; };
|
||||
|
||||
virtual void BeginEditParams( IEditor *ie,int flags ) {};
|
||||
virtual void EndEditParams() {};
|
||||
|
||||
virtual void Display( DisplayContext &dc ) {};
|
||||
virtual bool OnKeyDown( CViewport *view,uint nChar,uint nRepCnt,uint nFlags );
|
||||
virtual bool OnKeyUp( CViewport *view,uint nChar,uint nRepCnt,uint nFlags ) { return false; };
|
||||
|
||||
private:
|
||||
CShapeObject *m_shape;
|
||||
int m_currPoint;
|
||||
bool m_modifying;
|
||||
CPoint m_mouseDownPos;
|
||||
Vec3 m_pointPos;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CEditShapeObjectTool,CEditTool)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CEditShapeObjectTool::CEditShapeObjectTool()
|
||||
{
|
||||
m_shape = 0;
|
||||
m_currPoint = -1;
|
||||
m_modifying = false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEditShapeObjectTool::SetUserData( void *userData )
|
||||
{
|
||||
m_shape = (CShapeObject*)userData;
|
||||
assert( m_shape != 0 );
|
||||
|
||||
// Modify shape undo.
|
||||
if (!CUndo::IsRecording())
|
||||
{
|
||||
CUndo ("Modify Shape");
|
||||
m_shape->StoreUndo( "Shape Modify" );
|
||||
}
|
||||
|
||||
m_shape->SelectPoint(-1);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CEditShapeObjectTool::~CEditShapeObjectTool()
|
||||
{
|
||||
if (m_shape)
|
||||
{
|
||||
m_shape->SelectPoint(-1);
|
||||
}
|
||||
if (GetIEditor()->IsUndoRecording())
|
||||
GetIEditor()->CancelUndo();
|
||||
}
|
||||
|
||||
bool CEditShapeObjectTool::OnKeyDown( CViewport *view,uint nChar,uint nRepCnt,uint nFlags )
|
||||
{
|
||||
if (nChar == VK_ESCAPE)
|
||||
{
|
||||
GetIEditor()->SetEditTool(0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CEditShapeObjectTool::MouseCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags )
|
||||
{
|
||||
if (!m_shape)
|
||||
return false;
|
||||
|
||||
if (event == eMouseLDown)
|
||||
{
|
||||
m_mouseDownPos = point;
|
||||
}
|
||||
|
||||
if (event == eMouseLDown || event == eMouseMove || event == eMouseLDblClick || event == eMouseLUp)
|
||||
{
|
||||
const Matrix44 &shapeTM = m_shape->GetWorldTM();
|
||||
|
||||
/*
|
||||
float fShapeCloseDistance = SHAPE_CLOSE_DISTANCE;
|
||||
Vec3 pos = view->ViewToWorld( point );
|
||||
if (pos.x == 0 && pos.y == 0 && pos.z == 0)
|
||||
{
|
||||
// Find closest point on the shape.
|
||||
fShapeCloseDistance = SHAPE_CLOSE_DISTANCE * view->GetScreenScaleFactor(pos) * 0.01f;
|
||||
}
|
||||
else
|
||||
fShapeCloseDistance = SHAPE_CLOSE_DISTANCE * view->GetScreenScaleFactor(pos) * 0.01f;
|
||||
*/
|
||||
|
||||
|
||||
float dist;
|
||||
|
||||
Vec3 raySrc,rayDir;
|
||||
view->ViewToWorldRay( point,raySrc,rayDir );
|
||||
|
||||
// Find closest point on the shape.
|
||||
int p1,p2;
|
||||
Vec3 intPnt;
|
||||
m_shape->GetNearestEdge( raySrc,rayDir,p1,p2,dist,intPnt );
|
||||
|
||||
float fShapeCloseDistance = SHAPE_CLOSE_DISTANCE * view->GetScreenScaleFactor(intPnt) * 0.01f;
|
||||
|
||||
|
||||
if ((flags & MK_CONTROL) && !m_modifying)
|
||||
{
|
||||
// If control we are editing edges..
|
||||
if (p1 >= 0 && p2 >= 0 && dist < fShapeCloseDistance+view->GetSelectionTolerance())
|
||||
{
|
||||
// Cursor near one of edited shape edges.
|
||||
view->SetObjectCursor(0);
|
||||
if (event == eMouseLDown)
|
||||
{
|
||||
view->CaptureMouse();
|
||||
m_modifying = true;
|
||||
GetIEditor()->BeginUndo();
|
||||
if (GetIEditor()->IsUndoRecording())
|
||||
m_shape->StoreUndo( "Make Point" );
|
||||
|
||||
Vec3 newWorldPnt = view->MapViewToCP(point);
|
||||
Matrix44 invShapeTM = shapeTM;
|
||||
invShapeTM.Invert44();
|
||||
Vec3 newLocalPnt = invShapeTM.TransformPointOLD(newWorldPnt);
|
||||
|
||||
// If last edge, insert at end.
|
||||
if (p2 == 0)
|
||||
p2 = -1;
|
||||
// Create new point between nearest edge.
|
||||
// Put intPnt into local space of shape.
|
||||
//Matrix invShapeTM = shapeTM;
|
||||
//invShapeTM.Invert44();
|
||||
//intPnt = invShapeTM.TransformPointOLD(intPnt);
|
||||
int index = m_shape->InsertPoint( p2,newLocalPnt );
|
||||
m_shape->SelectPoint( index );
|
||||
|
||||
// Set construction plance for view.
|
||||
m_pointPos = shapeTM.TransformPointOLD( m_shape->GetPoint(index) );
|
||||
Matrix44 tm;
|
||||
tm.SetIdentity();
|
||||
tm.SetTranslationOLD( m_pointPos );
|
||||
view->SetConstrPlane( point,tm );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int index = m_shape->GetNearestPoint( raySrc,rayDir,dist );
|
||||
if (index >= 0 && dist < fShapeCloseDistance+view->GetSelectionTolerance())
|
||||
{
|
||||
// Cursor near one of edited shape points.
|
||||
view->SetObjectCursor(0);
|
||||
if (event == eMouseLDown)
|
||||
{
|
||||
if (!m_modifying)
|
||||
{
|
||||
m_shape->SelectPoint( index );
|
||||
m_modifying = true;
|
||||
view->CaptureMouse();
|
||||
GetIEditor()->BeginUndo();
|
||||
|
||||
// Set construction plance for view.
|
||||
m_pointPos = shapeTM.TransformPointOLD( m_shape->GetPoint(index) );
|
||||
Matrix44 tm;
|
||||
tm.SetIdentity();
|
||||
tm.SetTranslationOLD( m_pointPos );
|
||||
view->SetConstrPlane( point,tm );
|
||||
}
|
||||
}
|
||||
|
||||
//GetNearestEdge
|
||||
|
||||
if (event == eMouseLDblClick)
|
||||
{
|
||||
m_modifying = false;
|
||||
m_shape->RemovePoint( index );
|
||||
m_shape->SelectPoint( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
if (m_modifying && event == eMouseLUp)
|
||||
{
|
||||
// Accept changes.
|
||||
m_modifying = false;
|
||||
m_shape->SelectPoint( -1 );
|
||||
view->ReleaseMouse();
|
||||
m_shape->CalcBBox();
|
||||
|
||||
if (GetIEditor()->IsUndoRecording())
|
||||
GetIEditor()->AcceptUndo( "Shape Modify" );
|
||||
}
|
||||
|
||||
if (m_modifying && event == eMouseMove)
|
||||
{
|
||||
// Move selected point point.
|
||||
Vec3 p1 = view->MapViewToCP(m_mouseDownPos);
|
||||
Vec3 p2 = view->MapViewToCP(point);
|
||||
Vec3 v = view->GetCPVector(p1,p2);
|
||||
|
||||
if (m_shape->GetSelectedPoint() >= 0)
|
||||
{
|
||||
Vec3 wp = m_pointPos;
|
||||
Vec3 newp = wp + v;
|
||||
if (GetIEditor()->GetAxisConstrains() == AXIS_TERRAIN)
|
||||
{
|
||||
// Keep height.
|
||||
newp = view->MapViewToCP(point);
|
||||
//float z = wp.z - GetIEditor()->GetTerrainElevation(wp.x,wp.y);
|
||||
//newp.z = GetIEditor()->GetTerrainElevation(newp.x,newp.y) + z;
|
||||
//newp.z = GetIEditor()->GetTerrainElevation(newp.x,newp.y) + SHAPE_Z_OFFSET;
|
||||
newp.z += SHAPE_Z_OFFSET;
|
||||
}
|
||||
|
||||
if (newp.x != 0 && newp.y != 0 && newp.z != 0)
|
||||
{
|
||||
// Put newp into local space of shape.
|
||||
Matrix44 invShapeTM = shapeTM;
|
||||
invShapeTM.Invert44();
|
||||
newp = invShapeTM.TransformPointOLD(newp);
|
||||
|
||||
if (GetIEditor()->IsUndoRecording())
|
||||
m_shape->StoreUndo( "Move Point" );
|
||||
m_shape->SetPoint( m_shape->GetSelectedPoint(),newp );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Vec3 raySrc,rayDir;
|
||||
view->ViewToWorldRay( point,raySrc,rayDir );
|
||||
CBaseObject *hitObj = GetIEditor()->GetObjectManager()->HitTest( raySrc,rayDir,view->GetSelectionTolerance() );
|
||||
*/
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// CShapePanel dialog
|
||||
|
||||
IMPLEMENT_DYNAMIC(CShapePanel, CDialog)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CShapePanel::CShapePanel( CWnd* pParent /* = NULL */)
|
||||
: CDialog(CShapePanel::IDD, pParent)
|
||||
{
|
||||
Create( IDD,AfxGetMainWnd() );
|
||||
}
|
||||
|
||||
CShapePanel::~CShapePanel()
|
||||
{
|
||||
}
|
||||
|
||||
void CShapePanel::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
DDX_Control(pDX, IDC_PICK, m_pickButton);
|
||||
DDX_Control(pDX, IDC_SELECT, m_selectButton);
|
||||
DDX_Control(pDX, IDC_EDIT_SHAPE, m_editShapeButton);
|
||||
DDX_Control(pDX, IDC_ENTITIES, m_entities);
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CShapePanel, CDialog)
|
||||
ON_BN_CLICKED(IDC_SELECT, OnBnClickedSelect)
|
||||
ON_BN_CLICKED(IDC_REMOVE, OnBnClickedRemove)
|
||||
ON_LBN_DBLCLK(IDC_ENTITIES, OnLbnDblclkEntities)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
// CShapePanel message handlers
|
||||
|
||||
BOOL CShapePanel::OnInitDialog()
|
||||
{
|
||||
__super::OnInitDialog();
|
||||
|
||||
m_pickButton.SetPickCallback( this,"Pick Entity" );
|
||||
m_entities.SetBkColor( RGB(0xE0,0xE0,0xE0) );
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
void CShapePanel::SetShape( CShapeObject *shape )
|
||||
{
|
||||
assert( shape );
|
||||
m_shape = shape;
|
||||
|
||||
if (shape->GetPointCount() > 1)
|
||||
m_editShapeButton.SetToolClass( RUNTIME_CLASS(CEditShapeObjectTool),m_shape );
|
||||
else
|
||||
m_editShapeButton.EnableWindow( FALSE );
|
||||
|
||||
ReloadEntities();
|
||||
|
||||
CString str;
|
||||
str.Format( "Num Points: %d",shape->GetPointCount() );
|
||||
GetDlgItem(IDC_NUM_POINTS)->SetWindowText( str );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CShapePanel::OnPick( CBaseObject *picked )
|
||||
{
|
||||
assert( m_shape );
|
||||
CUndo undo("[Shape] Add Entity");
|
||||
m_shape->AddEntity( picked );
|
||||
ReloadEntities();
|
||||
// m_entityName.SetWindowText( picked->GetName() );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CShapePanel::OnPickFilter( CBaseObject *picked )
|
||||
{
|
||||
assert( picked != 0 );
|
||||
return picked->GetType() == OBJTYPE_ENTITY;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CShapePanel::OnCancelPick()
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CShapePanel::OnBnClickedSelect()
|
||||
{
|
||||
assert( m_shape );
|
||||
int sel = m_entities.GetCurSel();
|
||||
if (sel != LB_ERR)
|
||||
{
|
||||
CBaseObject *obj = m_shape->GetEntity(sel);
|
||||
if (obj)
|
||||
{
|
||||
GetIEditor()->ClearSelection();
|
||||
GetIEditor()->SelectObject( obj );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CShapePanel::ReloadEntities()
|
||||
{
|
||||
if (!m_shape)
|
||||
return;
|
||||
|
||||
m_entities.ResetContent();
|
||||
for (int i = 0; i < m_shape->GetEntityCount(); i++)
|
||||
{
|
||||
CBaseObject *obj = m_shape->GetEntity(i);
|
||||
if (obj)
|
||||
m_entities.AddString( obj->GetName() );
|
||||
else
|
||||
m_entities.AddString( "<Null>" );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CShapePanel::OnBnClickedRemove()
|
||||
{
|
||||
assert( m_shape );
|
||||
int sel = m_entities.GetCurSel();
|
||||
if (sel != LB_ERR)
|
||||
{
|
||||
CUndo undo("[Shape] Remove Entity");
|
||||
if (sel < m_shape->GetEntityCount())
|
||||
m_shape->RemoveEntity(sel);
|
||||
ReloadEntities();
|
||||
}
|
||||
}
|
||||
|
||||
void CShapePanel::OnLbnDblclkEntities()
|
||||
{
|
||||
// Select current entity.
|
||||
OnBnClickedSelect();
|
||||
}
|
||||
Reference in New Issue
Block a user