123
This commit is contained in:
282
Editor/Objects/AIAnchor.cpp
Normal file
282
Editor/Objects/AIAnchor.cpp
Normal file
@@ -0,0 +1,282 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: aianchor.cpp
|
||||
// Version: v1.00
|
||||
// Created: 9/9/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "AIAnchor.h"
|
||||
|
||||
#include "..\AI\AIManager.h"
|
||||
#include "..\Viewport.h"
|
||||
#include "Settings.h"
|
||||
|
||||
#include <IAISystem.h>
|
||||
#include <IAgent.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CBase implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CAIAnchor,CBaseObject)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
float CAIAnchor::m_helperScale = 1;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CAIAnchor::CAIAnchor()
|
||||
{
|
||||
m_aiObject = 0;
|
||||
|
||||
AddVariable( mv_action,"Action",functor(*this,&CAIAnchor::OnActionChange),IVariable::DT_AI_ANCHOR );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIAnchor::Done()
|
||||
{
|
||||
if (m_aiObject)
|
||||
{
|
||||
GetIEditor()->GetSystem()->GetAISystem()->RemoveObject(m_aiObject);
|
||||
m_aiObject = 0;
|
||||
}
|
||||
CBaseObject::Done();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAIAnchor::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
SetColor( RGB(0,255,0) );
|
||||
bool res = CBaseObject::Init( ie,prev,file );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAIAnchor::CreateGameObject()
|
||||
{
|
||||
CString action = mv_action;
|
||||
int aiObjectType = GetIEditor()->GetAI()->AnchorActionToId(action);
|
||||
|
||||
if (aiObjectType < 0)
|
||||
aiObjectType = 0;
|
||||
|
||||
if (aiObjectType >= 0)
|
||||
{
|
||||
if (m_aiObject)
|
||||
{
|
||||
GetIEditor()->GetSystem()->GetAISystem()->RemoveObject(m_aiObject);
|
||||
m_aiObject = 0;
|
||||
}
|
||||
|
||||
m_aiObject = GetIEditor()->GetSystem()->GetAISystem()->CreateAIObject( aiObjectType,0 );
|
||||
if (m_aiObject)
|
||||
{
|
||||
m_aiObject->SetName( GetName() );
|
||||
m_aiObject->SetRadius( GetArea() );
|
||||
m_aiObject->SetPos( GetWorldPos() );
|
||||
m_aiObject->SetAngles( GetWorldAngles() );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
float CAIAnchor::GetRadius()
|
||||
{
|
||||
return 0.5f*m_helperScale*gSettings.gizmo.helpersScale;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIAnchor::SetName( const CString &name )
|
||||
{
|
||||
CBaseObject::SetName( name );
|
||||
if (m_aiObject)
|
||||
m_aiObject->SetName(name);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIAnchor::InvalidateTM()
|
||||
{
|
||||
CBaseObject::InvalidateTM();
|
||||
|
||||
if (m_aiObject)
|
||||
{
|
||||
m_aiObject->SetPos( GetWorldPos() );
|
||||
m_aiObject->SetAngles( GetWorldAngles() );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIAnchor::SetScale( const Vec3d &scale )
|
||||
{
|
||||
// Ignore scale.
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIAnchor::BeginEditParams( IEditor *ie,int flags )
|
||||
{
|
||||
CBaseObject::BeginEditParams( ie,flags );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIAnchor::EndEditParams( IEditor *ie )
|
||||
{
|
||||
CBaseObject::EndEditParams( ie );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CAIAnchor::MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags )
|
||||
{
|
||||
if (event == eMouseMove || event == eMouseLDown)
|
||||
{
|
||||
Vec3 pos;
|
||||
if (GetIEditor()->GetAxisConstrains() != AXIS_TERRAIN)
|
||||
{
|
||||
pos = view->MapViewToCP(point);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Snap to terrain.
|
||||
bool hitTerrain;
|
||||
pos = view->ViewToWorld( point,&hitTerrain );
|
||||
if (hitTerrain)
|
||||
{
|
||||
pos.z = GetIEditor()->GetTerrainElevation(pos.x,pos.y) + 1.0f;
|
||||
}
|
||||
pos = view->SnapToGrid(pos);
|
||||
}
|
||||
|
||||
pos = view->SnapToGrid(pos);
|
||||
SetPos( pos );
|
||||
if (event == eMouseLDown)
|
||||
return MOUSECREATE_OK;
|
||||
return MOUSECREATE_CONTINUE;
|
||||
}
|
||||
return CBaseObject::MouseCreateCallback( view,event,point,flags );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIAnchor::Display( DisplayContext &dc )
|
||||
{
|
||||
const Matrix44 &wtm = GetWorldTM();
|
||||
|
||||
//CHANGED_BY_IVO
|
||||
Vec3 x = wtm.TransformVectorOLD( Vec3(0,-1,0) );
|
||||
|
||||
Vec3 wp = wtm.GetTranslationOLD();
|
||||
|
||||
if (IsFrozen())
|
||||
dc.SetFreezeColor();
|
||||
else
|
||||
dc.SetColor( GetColor() );
|
||||
|
||||
//dc.DrawArrow( wp,wp+x*0.5,0.5 );
|
||||
|
||||
//dc.DrawBall( wp,GetRadius() );
|
||||
|
||||
Matrix44 tm(wtm);
|
||||
dc.RenderObject( STATOBJECT_ANCHOR,tm );
|
||||
|
||||
if (IsSelected())
|
||||
{
|
||||
dc.SetSelectedColor();
|
||||
//dc.DrawBall( wp,GetRadius()+0.02f );
|
||||
|
||||
dc.PushMatrix(wtm);
|
||||
float r = GetRadius();
|
||||
dc.DrawWireBox( -Vec3(r,r,r),Vec3(r,r,r) );
|
||||
dc.PopMatrix();
|
||||
}
|
||||
DrawDefault( dc );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAIAnchor::HitTest( HitContext &hc )
|
||||
{
|
||||
Vec3 origin = GetWorldPos();
|
||||
float radius = GetRadius();
|
||||
|
||||
Vec3 w = origin - hc.raySrc;
|
||||
w = hc.rayDir.Cross( w );
|
||||
float d = w.Length();
|
||||
|
||||
if (d < radius + hc.distanceTollerance)
|
||||
{
|
||||
hc.dist = GetDistance(hc.raySrc,origin);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIAnchor::GetBoundBox( BBox &box )
|
||||
{
|
||||
Vec3 pos = GetWorldPos();
|
||||
float r = GetRadius();
|
||||
box.min = pos - Vec3(r,r,r);
|
||||
box.max = pos + Vec3(r,r,r);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIAnchor::GetLocalBounds( BBox &box )
|
||||
{
|
||||
float r = GetRadius();
|
||||
box.min = -Vec3(r,r,r);
|
||||
box.max = Vec3(r,r,r);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
XmlNodeRef CAIAnchor::Export( const CString &levelPath,XmlNodeRef &xmlNode )
|
||||
{
|
||||
XmlNodeRef objNode = CBaseObject::Export( levelPath,xmlNode );
|
||||
|
||||
// Export position in world space.
|
||||
Matrix44 wtm = GetWorldTM();
|
||||
wtm.NoScale();
|
||||
|
||||
//QUAT_CHANGED_BY_IVO
|
||||
//Quat q(wtm);
|
||||
//Quat q = CovertMatToQuat<float>( GetTransposed44(wtm) );
|
||||
Quat q = Quat( GetTransposed44(wtm) );
|
||||
|
||||
Vec3 worldPos = wtm.GetTranslationOLD();
|
||||
Vec3 worldAngles = Ang3::GetAnglesXYZ(Matrix33(q)) * 180.0f/gf_PI;
|
||||
|
||||
CString actionName = mv_action;
|
||||
int aiObjectType = GetIEditor()->GetAI()->AnchorActionToId( actionName );
|
||||
|
||||
objNode->setAttr( "AnchorId",aiObjectType );
|
||||
objNode->setAttr( "Area",GetArea() );
|
||||
|
||||
if (!IsEquivalent(worldPos,Vec3(0,0,0),0))
|
||||
objNode->setAttr( "Pos",worldPos );
|
||||
|
||||
if (!IsEquivalent(worldAngles,Vec3(0,0,0),0))
|
||||
objNode->setAttr( "Angles",worldAngles );
|
||||
|
||||
return objNode;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIAnchor::OnActionChange( IVariable *var )
|
||||
{
|
||||
if (m_aiObject)
|
||||
CreateGameObject();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIAnchor::OnUIUpdate()
|
||||
{
|
||||
CBaseObject::OnUIUpdate();
|
||||
|
||||
if (m_aiObject)
|
||||
m_aiObject->SetRadius(GetArea());
|
||||
}
|
||||
104
Editor/Objects/AIAnchor.h
Normal file
104
Editor/Objects/AIAnchor.h
Normal file
@@ -0,0 +1,104 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: aianchor.h
|
||||
// Version: v1.00
|
||||
// Created: 9/9/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __aianchor_h__
|
||||
#define __aianchor_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "BaseObject.h"
|
||||
|
||||
// forward declaration.
|
||||
struct IAIObject;
|
||||
|
||||
/*!
|
||||
* CAIAnchor is an special tag point,that registered with AI, and tell him what to do when AI is idle.
|
||||
*
|
||||
*/
|
||||
class CAIAnchor : public CBaseObject
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CAIAnchor)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
void Display( DisplayContext &disp );
|
||||
bool CreateGameObject();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetName( const CString &name );
|
||||
virtual void SetScale( const Vec3d &scale );
|
||||
virtual void InvalidateTM();
|
||||
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
|
||||
//! Called when object is being created.
|
||||
int MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags );
|
||||
bool HitTest( HitContext &hc );
|
||||
|
||||
void GetBoundBox( BBox &box );
|
||||
void GetLocalBounds( BBox &box );
|
||||
|
||||
void OnUIUpdate();
|
||||
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual void SetHelperScale( float scale ) { m_helperScale = scale; };
|
||||
virtual float GetHelperScale() { return m_helperScale; };
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CAIAnchor();
|
||||
|
||||
float GetRadius();
|
||||
|
||||
void OnActionChange( IVariable *var );
|
||||
void CreateAIObject( int type );
|
||||
|
||||
void DeleteThis() { delete this; };
|
||||
|
||||
CVariable<CString> mv_action;
|
||||
|
||||
IAIObject *m_aiObject;
|
||||
static float m_helperScale;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of TagPoint.
|
||||
*/
|
||||
class CAIAnchorClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {10E57056-78C7-489e-B230-89B673196DE4}
|
||||
static const GUID guid = { 0x10e57056, 0x78c7, 0x489e, { 0xb2, 0x30, 0x89, 0xb6, 0x73, 0x19, 0x6d, 0xe4 } };
|
||||
return guid;
|
||||
};
|
||||
ObjectType GetObjectType() { return OBJTYPE_AIPOINT; };
|
||||
const char* ClassName() { return "AIAnchor"; };
|
||||
const char* Category() { return "AI"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CAIAnchor); };
|
||||
int GameCreationOrder() { return 111; };
|
||||
};
|
||||
|
||||
#endif // __aianchor_h__
|
||||
769
Editor/Objects/AiPoint.cpp
Normal file
769
Editor/Objects/AiPoint.cpp
Normal file
@@ -0,0 +1,769 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: AIPoint.cpp
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: CAIPoint implementation.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "AIPoint.h"
|
||||
#include "ErrorReport.h"
|
||||
|
||||
#include "..\AIPointPanel.h"
|
||||
#include <IAgent.h>
|
||||
|
||||
#include "..\Viewport.h"
|
||||
#include "Settings.h"
|
||||
|
||||
#include <I3DEngine.h>
|
||||
//#include <I3DIndoorEngine.h>
|
||||
#include <IAISystem.h>
|
||||
|
||||
#define AIWAYPOINT_RADIUS 0.3f
|
||||
#define DIR_VECTOR Vec3(0,-1,0)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CBase implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CAIPoint,CBaseObject)
|
||||
|
||||
int CAIPoint::m_rollupId = 0;
|
||||
CAIPointPanel* CAIPoint::m_panel = 0;
|
||||
|
||||
float CAIPoint::m_helperScale = 1;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CAIPoint::CAIPoint()
|
||||
{
|
||||
m_aiNode = 0;
|
||||
m_bIndoorEntrance = false;
|
||||
m_bIndoors = false;
|
||||
m_aiType = EAIPOINT_WAYPOINT;
|
||||
|
||||
m_bLinksValid = false;
|
||||
m_bIgnoreUpdateLinks = false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::Done()
|
||||
{
|
||||
m_bLinksValid = false;
|
||||
if (m_aiNode)
|
||||
{
|
||||
IGraph *aiGraph = GetIEditor()->GetSystem()->GetAISystem()->GetNodeGraph();
|
||||
if (aiGraph)
|
||||
{
|
||||
aiGraph->Disconnect(m_aiNode,false);
|
||||
if (m_bIndoorEntrance)
|
||||
{
|
||||
aiGraph->RemoveEntrance( m_aiNode->nBuildingID,m_aiNode );
|
||||
}
|
||||
}
|
||||
m_aiNode = 0;
|
||||
}
|
||||
|
||||
while (!m_links.empty())
|
||||
{
|
||||
CAIPoint *obj = GetLink(0);
|
||||
if (obj)
|
||||
RemoveLink( obj );
|
||||
else
|
||||
m_links.erase(m_links.begin());
|
||||
}
|
||||
|
||||
CBaseObject::Done();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAIPoint::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
m_bLinksValid = false;
|
||||
|
||||
SetColor( RGB(0,128,255) );
|
||||
bool res = CBaseObject::Init( ie,prev,file );
|
||||
|
||||
if (IsCreateGameObjects())
|
||||
if (m_aiType != EAIPOINT_HIDE)
|
||||
{
|
||||
// Create AI graph node in game.
|
||||
IGraph *aiGraph = GetIEditor()->GetSystem()->GetAISystem()->GetNodeGraph();
|
||||
if (aiGraph)
|
||||
m_aiNode = aiGraph->CreateNewNode();
|
||||
}
|
||||
|
||||
if (prev)
|
||||
{
|
||||
CAIPoint *pOriginal = (CAIPoint *)prev;
|
||||
SetAIType(pOriginal->m_aiType);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CString CAIPoint::GetTypeDescription() const
|
||||
{
|
||||
if (m_aiType == EAIPOINT_HIDE)
|
||||
{
|
||||
return CString(GetClassDesc()->ClassName()) + "(Hide)";
|
||||
}
|
||||
else if (m_aiType == EAIPOINT_ENTRY)
|
||||
{
|
||||
return CString(GetClassDesc()->ClassName()) + "(Entry)";
|
||||
}
|
||||
else if (m_aiType == EAIPOINT_EXIT)
|
||||
{
|
||||
return CString(GetClassDesc()->ClassName()) + "(Exit)";
|
||||
}
|
||||
return GetClassDesc()->ClassName();
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
float CAIPoint::GetRadius()
|
||||
{
|
||||
return AIWAYPOINT_RADIUS*m_helperScale * gSettings.gizmo.helpersScale;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::SetPos( const Vec3d &pos )
|
||||
{
|
||||
Vec3d oldpos = GetWorldPos();
|
||||
CBaseObject::SetPos( pos );
|
||||
|
||||
/*
|
||||
if (m_aiNode)
|
||||
{
|
||||
m_aiNode->data.m_pos = pos;
|
||||
|
||||
m_buildingId = -1;
|
||||
|
||||
m_bIndoors = false;
|
||||
IAISystem *pAISystem = GetIEditor()->GetSystem()->GetAISystem();
|
||||
int buildingId;IVisArea *pArea;
|
||||
if (pAISystem && pAISystem->CheckInside(pos,buildingId,pArea))
|
||||
{
|
||||
m_aiNode->nBuildingID = buildingId;
|
||||
m_aiNode->pArea = pArea;
|
||||
|
||||
if (m_buildingId != buildingId)
|
||||
m_bLinksValid = false;
|
||||
m_buildingId = buildingId;
|
||||
m_pArea= pArea;
|
||||
m_bIndoors = true;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bIndoors = false;
|
||||
IAISystem *pAISystem = GetIEditor()->GetSystem()->GetAISystem();
|
||||
if (!pAISystem)
|
||||
return;
|
||||
IGraph *pGraph = pAISystem->GetNodeGraph();
|
||||
if (!pGraph)
|
||||
return;
|
||||
int buildingId;IVisArea *pArea;
|
||||
if (pAISystem->CheckInside(pos,buildingId,pArea))
|
||||
{
|
||||
if (m_buildingId != buildingId)
|
||||
m_bLinksValid = false;
|
||||
|
||||
m_buildingId = buildingId;
|
||||
m_pArea= pArea;
|
||||
m_bIndoors = true;
|
||||
}
|
||||
|
||||
// for hide points
|
||||
int numLinks = m_links.size();
|
||||
for (int i = 0; i < numLinks; i++)
|
||||
{
|
||||
// go trough all the links in the waypoint
|
||||
CAIPoint *pnt = GetLink(i);
|
||||
if (!pnt || !pnt->m_aiNode)
|
||||
continue;
|
||||
|
||||
Matrix44 m;
|
||||
m.SetIdentity();
|
||||
|
||||
//m.RotateMatrix_fix(GetAngles());
|
||||
m=GetRotationZYX44(-GetAngles()*gf_DEGTORAD)*m; //NOTE: angles in radians and negated
|
||||
|
||||
//CHANGED_BY_IVO
|
||||
//Vec3 dir = m.TransformVector(DIR_VECTOR);
|
||||
Vec3 dir = GetTransposed44(m) * (DIR_VECTOR);
|
||||
|
||||
pGraph->RemoveHidePoint(pnt->m_aiNode,oldpos,dir);
|
||||
pGraph->AddHidePoint(pnt->m_aiNode,pos,dir);
|
||||
// and update the point there
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::SetAngles( const Vec3d &angles )
|
||||
{
|
||||
//if (m_aiType == EAIPOINT_HIDE)
|
||||
{
|
||||
CBaseObject::SetAngles(angles);
|
||||
}
|
||||
}
|
||||
|
||||
void CAIPoint::SetScale( const Vec3d &angles )
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAIPoint::HitTest( HitContext &hc )
|
||||
{
|
||||
Vec3 origin = GetWorldPos();
|
||||
float radius = GetRadius();
|
||||
|
||||
Vec3 w = origin - hc.raySrc;
|
||||
w = hc.rayDir.Cross( w );
|
||||
float d = w.GetLengthSquared();
|
||||
|
||||
if (d < radius*radius + hc.distanceTollerance)
|
||||
{
|
||||
Vec3 i0;
|
||||
if (Intersect::Ray_SphereFirst( Ray(hc.raySrc,hc.rayDir),Sphere(origin,radius),i0))
|
||||
{
|
||||
hc.dist = GetDistance(hc.raySrc,i0);
|
||||
return true;
|
||||
}
|
||||
hc.dist = GetDistance(hc.raySrc,origin);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::GetBoundBox( BBox &box )
|
||||
{
|
||||
Vec3 pos = GetWorldPos();
|
||||
float r = GetRadius();
|
||||
box.min = pos - Vec3(r,r,r);
|
||||
box.max = pos + Vec3(r,r,r);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::GetLocalBounds( BBox &box )
|
||||
{
|
||||
float r = GetRadius();
|
||||
box.min = -Vec3(r,r,r);
|
||||
box.max = Vec3(r,r,r);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::BeginEditParams( IEditor *ie,int flags )
|
||||
{
|
||||
CBaseObject::BeginEditParams( ie,flags );
|
||||
|
||||
// Unselect all links.
|
||||
for (int i = 0; i < GetLinkCount(); i++)
|
||||
SelectLink(i,false);
|
||||
|
||||
if (!m_panel)
|
||||
{
|
||||
m_panel = new CAIPointPanel;
|
||||
m_rollupId = ie->AddRollUpPage( ROLLUP_OBJECTS,"AIPoint Parameters",m_panel );
|
||||
}
|
||||
if (m_panel)
|
||||
m_panel->SetObject( this );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::EndEditParams( IEditor *ie )
|
||||
{
|
||||
if (m_panel)
|
||||
{
|
||||
ie->RemoveRollUpPage( ROLLUP_OBJECTS,m_rollupId );
|
||||
}
|
||||
m_rollupId = 0;
|
||||
m_panel = 0;
|
||||
|
||||
// Unselect all links.
|
||||
for (int i = 0; i < GetLinkCount(); i++)
|
||||
SelectLink(i,false);
|
||||
|
||||
CBaseObject::EndEditParams( ie );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CAIPoint::MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags )
|
||||
{
|
||||
if (event == eMouseMove || event == eMouseLDown)
|
||||
{
|
||||
Vec3 pos;
|
||||
if (GetIEditor()->GetAxisConstrains() != AXIS_TERRAIN)
|
||||
{
|
||||
pos = view->MapViewToCP(point);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Snap to terrain.
|
||||
bool hitTerrain;
|
||||
pos = view->ViewToWorld( point,&hitTerrain );
|
||||
if (hitTerrain)
|
||||
{
|
||||
pos.z = GetIEditor()->GetTerrainElevation(pos.x,pos.y) + GetRadius();
|
||||
}
|
||||
pos = view->SnapToGrid(pos);
|
||||
}
|
||||
SetPos( pos );
|
||||
if (event == eMouseLDown)
|
||||
return MOUSECREATE_OK;
|
||||
return MOUSECREATE_CONTINUE;
|
||||
}
|
||||
return CBaseObject::MouseCreateCallback( view,event,point,flags );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::Display( DisplayContext &dc )
|
||||
{
|
||||
COLORREF color = GetColor();
|
||||
COLORREF clrSelectedLink = GetColor();
|
||||
|
||||
if (!m_bIndoors)
|
||||
{
|
||||
// Draw invalid node.
|
||||
color = RGB(255,0,0);
|
||||
}
|
||||
Vec3 wp = GetWorldPos();
|
||||
if (m_aiType == EAIPOINT_HIDE)
|
||||
{
|
||||
color = RGB(0,255,0); //<<FIXME>> Timur solve this in a better way.
|
||||
if (IsSelected())
|
||||
dc.SetSelectedColor();
|
||||
else
|
||||
dc.SetColor( color,1 );
|
||||
|
||||
//Vec3 arrowTrg = GetWorldTM().TransformPoint(0.5f*Vec3d(0,-1,0));
|
||||
//dc.DrawArrow(wp,arrowTrg);
|
||||
Matrix44 tm = GetWorldTM();
|
||||
float sz = m_helperScale * gSettings.gizmo.helpersScale;
|
||||
tm.ScaleMatRow( Vec3(sz,sz,sz) );
|
||||
dc.RenderObject( STATOBJECT_HIDEPOINT,tm );
|
||||
}
|
||||
else if (m_aiType == EAIPOINT_ENTRY || m_aiType == EAIPOINT_EXIT)
|
||||
{
|
||||
if (IsSelected())
|
||||
dc.SetSelectedColor();
|
||||
else
|
||||
dc.SetColor( color,1 );
|
||||
Matrix44 tm = GetWorldTM();
|
||||
float sz = m_helperScale * gSettings.gizmo.helpersScale;
|
||||
tm.ScaleMatRow( Vec3(sz,sz,sz) );
|
||||
dc.RenderObject( STATOBJECT_ENTRANCE,GetWorldTM() );
|
||||
}
|
||||
else
|
||||
{
|
||||
dc.SetColor( color,1 );
|
||||
dc.DrawBall( wp,GetRadius() );
|
||||
if (IsSelected())
|
||||
{
|
||||
dc.SetSelectedColor( 0.3f );
|
||||
dc.renderer->DrawBall( wp,GetRadius()+0.1f );
|
||||
}
|
||||
}
|
||||
|
||||
int numLinks = m_links.size();
|
||||
for (int i = 0; i < numLinks; i++)
|
||||
{
|
||||
CAIPoint *pnt = GetLink(i);
|
||||
if (!pnt)
|
||||
continue;
|
||||
|
||||
if (m_links[i].selected)
|
||||
{
|
||||
dc.SetSelectedColor();
|
||||
dc.DrawLine( wp+Vec3(0,0,0.05f),pnt->GetWorldPos()+Vec3(0,0,0.05f) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pnt->m_aiType == EAIPOINT_HIDE)
|
||||
color = RGB(0,255,0);
|
||||
dc.SetColor( color );
|
||||
dc.DrawLine( wp,pnt->GetWorldPos() );
|
||||
}
|
||||
}
|
||||
|
||||
DrawDefault( dc );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::Serialize( CObjectArchive &ar )
|
||||
{
|
||||
m_bIgnoreUpdateLinks = true;
|
||||
CBaseObject::Serialize( ar );
|
||||
m_bIgnoreUpdateLinks = false;
|
||||
|
||||
XmlNodeRef xmlNode = ar.node;
|
||||
if (ar.bLoading)
|
||||
{
|
||||
m_bIgnoreUpdateLinks = true;
|
||||
int aiType = 0;
|
||||
xmlNode->getAttr( "AIType",aiType );
|
||||
|
||||
// Load Links.
|
||||
m_links.clear();
|
||||
XmlNodeRef links = xmlNode->findChild( "Links" );
|
||||
if (links)
|
||||
{
|
||||
m_bLinksValid = false;
|
||||
for (int i = 0; i < links->getChildCount(); i++)
|
||||
{
|
||||
XmlNodeRef pnt = links->getChild(i);
|
||||
Link link;
|
||||
link.object = 0;
|
||||
pnt->getAttr( "Id",link.id );
|
||||
m_links.push_back(link);
|
||||
}
|
||||
}
|
||||
SetAIType((EAIPointType)aiType);
|
||||
m_bIgnoreUpdateLinks = false;
|
||||
if (ar.bUndo)
|
||||
UpdateLinks();
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlNode->setAttr( "AIType",(int)m_aiType );
|
||||
// Save Links.
|
||||
if (!m_links.empty())
|
||||
{
|
||||
XmlNodeRef links = xmlNode->newChild( "Links" );
|
||||
for (int i = 0; i < m_links.size(); i++)
|
||||
{
|
||||
XmlNodeRef pnt = links->newChild( "Link" );
|
||||
CAIPoint* link = GetLink(i);
|
||||
if (!link)
|
||||
continue;
|
||||
pnt->setAttr( "Id",link->GetId() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
XmlNodeRef CAIPoint::Export( const CString &levelPath,XmlNodeRef &xmlNode )
|
||||
{
|
||||
/*
|
||||
XmlNodeRef objNode = CBaseObject::Export( levelPath,xmlNode );
|
||||
objNode->setAttr( "Id",GetId() );
|
||||
|
||||
// Save Links.
|
||||
if (!m_links.empty())
|
||||
{
|
||||
XmlNodeRef links = xmlNode->newChild( "Links" );
|
||||
for (int i = 0; i < m_links.size(); i++)
|
||||
{
|
||||
XmlNodeRef pnt = links->newChild( "Link" );
|
||||
pnt->setAttr( "Id",m_links[i].id );
|
||||
}
|
||||
}
|
||||
|
||||
return CBaseObject::Export( levelPath,xmlNode );
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::OnEvent( ObjectEvent event )
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
//case EVENT_AFTER_LOAD: // After all objects loaded.
|
||||
case EVENT_REFRESH: // when refreshing level.
|
||||
// Recalculate indoors.
|
||||
SetPos( GetPos() );
|
||||
// After loading reconnect all links.
|
||||
UpdateLinks();
|
||||
break;
|
||||
case EVENT_CLEAR_AIGRAPH:
|
||||
m_aiNode = 0;
|
||||
break;
|
||||
case EVENT_MISSION_CHANGE:
|
||||
{
|
||||
// After mission have been changed, AI graph invalidates all pointers, create them again.
|
||||
// Create AI graph node in game.
|
||||
IGraph *aiGraph = GetIEditor()->GetSystem()->GetAISystem()->GetNodeGraph();
|
||||
if (aiGraph)
|
||||
{
|
||||
m_bLinksValid = false;
|
||||
if (m_aiType != EAIPOINT_HIDE)
|
||||
{
|
||||
m_aiNode = aiGraph->CreateNewNode();
|
||||
}
|
||||
UpdateLinks();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CAIPoint* CAIPoint::GetLink( int index )
|
||||
{
|
||||
assert( index >= 0 && index < m_links.size() );
|
||||
if (!m_links[index].object)
|
||||
{
|
||||
CBaseObject *obj = FindObject(m_links[index].id);
|
||||
if (obj && obj->IsKindOf(RUNTIME_CLASS(CAIPoint)))
|
||||
{
|
||||
((CAIPoint*)obj)->AddLink( this,false );
|
||||
m_links[index].object = (CAIPoint*)obj;
|
||||
}
|
||||
}
|
||||
return m_links[index].object;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::AddLink( CAIPoint* obj,bool bNeighbour )
|
||||
{
|
||||
if (obj == this)
|
||||
return;
|
||||
|
||||
GUID id = obj->GetId();
|
||||
for (int i = 0; i < m_links.size(); i++)
|
||||
{
|
||||
if (m_links[i].object == obj || m_links[i].id == id)
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_aiType == EAIPOINT_HIDE)
|
||||
{
|
||||
if (obj->m_aiType == EAIPOINT_HIDE)
|
||||
{
|
||||
Warning( _T("Cannot connect hide spots") );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Link link;
|
||||
link.object = obj;
|
||||
link.id = id;
|
||||
m_links.push_back( link );
|
||||
m_bLinksValid = false;
|
||||
|
||||
|
||||
if (!bNeighbour)
|
||||
{
|
||||
obj->AddLink( this,true );
|
||||
UpdateLinks();
|
||||
}
|
||||
else if (m_aiType == EAIPOINT_HIDE)
|
||||
{
|
||||
UpdateLinks();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::RemoveLink( CAIPoint* obj,bool bNeighbour )
|
||||
{
|
||||
if (obj == this || obj == 0)
|
||||
return;
|
||||
|
||||
if (m_aiType == EAIPOINT_HIDE && obj->m_aiNode)
|
||||
{
|
||||
IAISystem *aiSystem = GetIEditor()->GetSystem()->GetAISystem();
|
||||
IGraph *aiGraph = aiSystem->GetNodeGraph();
|
||||
if (aiGraph)
|
||||
{
|
||||
aiGraph->RemoveHidePoint(obj->m_aiNode,m_currHidePos,m_currHideDir );
|
||||
}
|
||||
}
|
||||
|
||||
int index = -1;
|
||||
GUID id = obj->GetId();
|
||||
for (int i = 0; i < m_links.size(); i++)
|
||||
{
|
||||
if (m_links[i].object == obj || m_links[i].id == id)
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
m_links.erase( m_links.begin() + index );
|
||||
m_bLinksValid = false;
|
||||
|
||||
if (!bNeighbour)
|
||||
{
|
||||
obj->RemoveLink( this,true );
|
||||
UpdateLinks();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::UpdateLinks()
|
||||
{
|
||||
if (m_bLinksValid || m_bIgnoreUpdateLinks)
|
||||
return;
|
||||
|
||||
IAISystem *aiSystem = GetIEditor()->GetSystem()->GetAISystem();
|
||||
if (!aiSystem)
|
||||
return;
|
||||
IGraph *aiGraph = aiSystem->GetNodeGraph();
|
||||
|
||||
if (!aiGraph)
|
||||
return;
|
||||
|
||||
m_bIndoors = false;
|
||||
|
||||
if (m_aiType != EAIPOINT_HIDE)
|
||||
{
|
||||
if (!m_aiNode)
|
||||
return;
|
||||
|
||||
IVisArea *pArea = NULL;
|
||||
int nBuildingId = -1;
|
||||
Vec3 wp = GetWorldPos();
|
||||
if (aiSystem->CheckInside(wp,nBuildingId,pArea))
|
||||
{
|
||||
m_bIndoors = true;
|
||||
}
|
||||
|
||||
aiGraph->Disconnect(m_aiNode,false);
|
||||
|
||||
if (m_bIndoorEntrance)
|
||||
{
|
||||
aiGraph->RemoveEntrance( m_aiNode->nBuildingID,m_aiNode );
|
||||
m_bIndoorEntrance = false;
|
||||
}
|
||||
|
||||
m_aiNode->nBuildingID = nBuildingId;
|
||||
m_aiNode->pArea = m_pArea;
|
||||
m_aiNode->data.m_pos = wp;
|
||||
|
||||
if (m_aiType == EAIPOINT_ENTRY && m_aiNode->nBuildingID >= 0)
|
||||
{
|
||||
aiGraph->AddIndoorEntrance( m_aiNode->nBuildingID,m_aiNode );
|
||||
m_bIndoorEntrance = true;
|
||||
}
|
||||
else if (m_aiType == EAIPOINT_EXIT && m_aiNode->nBuildingID >= 0)
|
||||
{
|
||||
aiGraph->AddIndoorEntrance( m_aiNode->nBuildingID,m_aiNode,true);
|
||||
m_bIndoorEntrance = true;
|
||||
}
|
||||
|
||||
int numLinks = GetLinkCount();
|
||||
for (int i = 0; i < numLinks; i++)
|
||||
{
|
||||
CAIPoint *lnk = GetLink(i);
|
||||
if (!lnk)
|
||||
continue;
|
||||
|
||||
if (!lnk->m_aiNode)
|
||||
{
|
||||
if (lnk->m_aiType == EAIPOINT_HIDE)
|
||||
{
|
||||
Vec3 wp = lnk->GetWorldPos();
|
||||
Matrix44 m = lnk->GetWorldTM();
|
||||
m.NoScale();
|
||||
Vec3 dir = m.TransformVectorOLD(DIR_VECTOR);
|
||||
aiGraph->AddHidePoint(m_aiNode,wp,dir );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aiGraph->Connect(m_aiNode,lnk->m_aiNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec3 wp = GetWorldPos();
|
||||
Matrix44 m = GetWorldTM();
|
||||
m.NoScale();
|
||||
Vec3 dir = m.TransformVectorOLD(DIR_VECTOR);
|
||||
|
||||
int numLinks = GetLinkCount();
|
||||
for (int i = 0; i < numLinks; i++)
|
||||
{
|
||||
CAIPoint *lnk = GetLink(i);
|
||||
if (!lnk || !lnk->m_aiNode)
|
||||
continue;
|
||||
|
||||
aiGraph->RemoveHidePoint( lnk->m_aiNode,m_currHidePos,m_currHideDir );
|
||||
aiGraph->AddHidePoint(lnk->m_aiNode,wp,dir );
|
||||
}
|
||||
m_currHidePos = wp;
|
||||
m_currHideDir = dir;
|
||||
}
|
||||
m_bLinksValid = true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::SetAIType( EAIPointType type )
|
||||
{
|
||||
if (type == m_aiType)
|
||||
return;
|
||||
StoreUndo( "Set AIPoint Type" );
|
||||
EAIPointType oldType = m_aiType;
|
||||
m_aiType = type;
|
||||
if (m_aiType == EAIPOINT_HIDE)
|
||||
{
|
||||
IAISystem *aiSystem = GetIEditor()->GetSystem()->GetAISystem();
|
||||
IGraph *aiGraph = aiSystem->GetNodeGraph();
|
||||
if (m_aiNode && aiGraph)
|
||||
{
|
||||
//aiGraph->DeleteNode(m_aiNode);
|
||||
aiGraph->Disconnect(m_aiNode);
|
||||
m_aiNode = 0;
|
||||
}
|
||||
}
|
||||
else if (!m_aiNode)
|
||||
{
|
||||
IAISystem *aiSystem = GetIEditor()->GetSystem()->GetAISystem();
|
||||
IGraph *aiGraph = aiSystem->GetNodeGraph();
|
||||
if (aiGraph)
|
||||
m_aiNode = aiGraph->CreateNewNode();
|
||||
}
|
||||
|
||||
m_bLinksValid = false;
|
||||
|
||||
UpdateLinks();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Invalidates cached transformation matrix.
|
||||
void CAIPoint::InvalidateTM()
|
||||
{
|
||||
CBaseObject::InvalidateTM();
|
||||
|
||||
m_bLinksValid = false;
|
||||
UpdateLinks();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::StartPick()
|
||||
{
|
||||
if (m_panel)
|
||||
m_panel->StartPick();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAIPoint::Validate( CErrorReport *report )
|
||||
{
|
||||
CBaseObject::Validate( report );
|
||||
if (!m_bIndoors && m_aiType != EAIPOINT_HIDE)
|
||||
{
|
||||
CErrorRecord err;
|
||||
err.error.Format( "AI Point is not valid %s (Must be indoors)",(const char*)GetName() );
|
||||
err.pObject = this;
|
||||
err.severity = CErrorRecord::ESEVERITY_WARNING;
|
||||
err.flags = CErrorRecord::FLAG_AI;
|
||||
report->ReportError(err);
|
||||
}
|
||||
}
|
||||
157
Editor/Objects/AiPoint.h
Normal file
157
Editor/Objects/AiPoint.h
Normal file
@@ -0,0 +1,157 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: AIPoint.h
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: AIPoint object definition.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __AIPoint_h__
|
||||
#define __AIPoint_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "BaseObject.h"
|
||||
|
||||
enum EAIPointType
|
||||
{
|
||||
EAIPOINT_WAYPOINT = 0, //!< AI Graph node, waypoint.
|
||||
EAIPOINT_HIDE, //!< Good hiding point.
|
||||
EAIPOINT_ENTRY, //!< Entry point to indoors.
|
||||
EAIPOINT_EXIT, //!< Exit point from indoors.
|
||||
};
|
||||
|
||||
struct IVisArea;
|
||||
|
||||
/*!
|
||||
* CAIPoint is an object that represent named AI waypoint in the world.
|
||||
*
|
||||
*/
|
||||
class CAIPoint : public CBaseObject
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CAIPoint)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
void Display( DisplayContext &disp );
|
||||
|
||||
virtual CString GetTypeDescription() const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetPos( const Vec3d &pos );
|
||||
virtual void SetAngles( const Vec3d &angles );
|
||||
virtual void SetScale( const Vec3d &angles );
|
||||
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
|
||||
//! Called when object is being created.
|
||||
int MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags );
|
||||
|
||||
bool HitTest( HitContext &hc );
|
||||
|
||||
void GetBoundBox( BBox &box );
|
||||
void GetLocalBounds( BBox &box );
|
||||
|
||||
void OnEvent( ObjectEvent event );
|
||||
|
||||
void Serialize( CObjectArchive &ar );
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
|
||||
//! Invalidates cached transformation matrix.
|
||||
virtual void InvalidateTM();
|
||||
|
||||
virtual void SetHelperScale( float scale ) { m_helperScale = scale; };
|
||||
virtual float GetHelperScale() { return m_helperScale; };
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Retreive number of link points.
|
||||
int GetLinkCount() const { return m_links.size(); }
|
||||
CAIPoint* GetLink( int index );
|
||||
void AddLink( CAIPoint* obj,bool bNeighbour=false );
|
||||
void RemoveLink( CAIPoint* obj,bool bNeighbour=false );
|
||||
bool IsLinkSelected( int iLink ) const { m_links[iLink].selected; };
|
||||
void SelectLink( int iLink,bool bSelect ) { m_links[iLink].selected = bSelect; };
|
||||
|
||||
void SetAIType( EAIPointType type );
|
||||
EAIPointType GetAIType() const { return m_aiType; };
|
||||
|
||||
// Enable picking of AI points.
|
||||
void StartPick();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void Validate( CErrorReport *report );
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CAIPoint();
|
||||
void DeleteThis() { delete this; };
|
||||
|
||||
// Update links in AI graph.
|
||||
void UpdateLinks();
|
||||
float GetRadius();
|
||||
|
||||
//! Ids of linked waypoints.
|
||||
struct Link
|
||||
{
|
||||
CAIPoint *object;
|
||||
GUID id;
|
||||
bool selected; // True if link is currently selected.
|
||||
Link() { object = 0; id = GUID_NULL; selected = false; }
|
||||
};
|
||||
std::vector<Link> m_links;
|
||||
EAIPointType m_aiType;
|
||||
|
||||
//! True if this waypoint is indoors.
|
||||
bool m_bIndoors;
|
||||
IVisArea *m_pArea;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool m_bLinksValid;
|
||||
bool m_bIgnoreUpdateLinks;
|
||||
|
||||
// AI graph node.
|
||||
struct GraphNode *m_aiNode;
|
||||
bool m_bIndoorEntrance;
|
||||
|
||||
Vec3 m_currHidePos;
|
||||
Vec3 m_currHideDir;
|
||||
|
||||
static int m_rollupId;
|
||||
static class CAIPointPanel* m_panel;
|
||||
static float m_helperScale;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of AIPoint.
|
||||
*/
|
||||
class CAIPointClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {07303078-B211-40b9-9621-9910A0271AB7}
|
||||
static const GUID guid = { 0x7303078, 0xb211, 0x40b9, { 0x96, 0x21, 0x99, 0x10, 0xa0, 0x27, 0x1a, 0xb7 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_AIPOINT; };
|
||||
const char* ClassName() { return "AIPoint"; };
|
||||
const char* Category() { return "AI"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CAIPoint); };
|
||||
int GameCreationOrder() { return 110; };
|
||||
};
|
||||
|
||||
#endif // __AIPoint_h__
|
||||
447
Editor/Objects/AreaBox.cpp
Normal file
447
Editor/Objects/AreaBox.cpp
Normal file
@@ -0,0 +1,447 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: AreaBox.cpp
|
||||
// Version: v1.00
|
||||
// Created: 22/10/2002 by Lennert.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: CAreaBox implementation.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "AreaBox.h"
|
||||
#include "ObjectManager.h"
|
||||
#include "..\Viewport.h"
|
||||
#include <IEntitySystem.h>
|
||||
#include <IGame.h>
|
||||
#include <IMarkers.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CBase implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CAreaBox,CBaseObject)
|
||||
|
||||
int CAreaBox::m_nRollupId=0;
|
||||
CPickEntitiesPanel* CAreaBox::m_pPanel=NULL;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CAreaBox::CAreaBox()
|
||||
{
|
||||
m_IArea=NULL;
|
||||
m_areaId = -1;
|
||||
m_edgeWidth=0;
|
||||
mv_width = 4;
|
||||
mv_length = 4;
|
||||
mv_height = 1;
|
||||
mv_groupId = 0;
|
||||
|
||||
m_box.min=Vec3(-mv_width/2, -mv_length/2, 0);
|
||||
m_box.max=Vec3(mv_width/2, mv_length/2, mv_height);
|
||||
|
||||
AddVariable( m_areaId,"AreaId",functor(*this,&CAreaBox::OnAreaChange) );
|
||||
AddVariable( m_edgeWidth,"FadeInZone",functor(*this,&CAreaBox::OnSizeChange) );
|
||||
AddVariable( mv_width,"Width",functor(*this,&CAreaBox::OnSizeChange) );
|
||||
AddVariable( mv_length,"Length",functor(*this,&CAreaBox::OnSizeChange) );
|
||||
AddVariable( mv_height,"Height",functor(*this,&CAreaBox::OnSizeChange) );
|
||||
AddVariable( mv_groupId,"GroupId",functor(*this,&CAreaBox::OnAreaChange) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::Done()
|
||||
{
|
||||
if (m_IArea)
|
||||
{
|
||||
GetIEditor()->GetGame()->GetAreaManager()->DeleteArea( m_IArea );
|
||||
m_IArea=NULL;
|
||||
}
|
||||
CBaseObject::Done();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAreaBox::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
bool res = CBaseObject::Init( ie,prev,file );
|
||||
SetColor( RGB(0,0,255) );
|
||||
return res;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::GetBoundBox( BBox &box )
|
||||
{
|
||||
box = m_box;
|
||||
box.Transform( GetWorldTM() );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::GetLocalBounds( BBox &box )
|
||||
{
|
||||
box = m_box;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::SetScale( const Vec3d &scale )
|
||||
{
|
||||
// Ignore scale on CAreaBox.
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAreaBox::HitTest( HitContext &hc )
|
||||
{
|
||||
Vec3 p;
|
||||
/*BBox box;
|
||||
box = m_box;
|
||||
box.Transform( GetWorldTM() );
|
||||
float tr = hc.distanceTollerance/2;
|
||||
box.min -= Vec3(tr,tr,tr);
|
||||
box.max += Vec3(tr,tr,tr);
|
||||
if (box.IsIntersectRay(hc.raySrc,hc.rayDir,p ))
|
||||
{
|
||||
hc.dist = Vec3(hc.raySrc - p).Length();
|
||||
return true;
|
||||
}*/
|
||||
Matrix44 invertWTM = GetWorldTM();
|
||||
Vec3 worldPos = invertWTM.GetTranslationOLD();
|
||||
invertWTM.Invert44();
|
||||
|
||||
Vec3 xformedRaySrc = invertWTM.TransformPointOLD(hc.raySrc);
|
||||
//CHANGED_BY_IVO
|
||||
Vec3 xformedRayDir = GetNormalized( invertWTM.TransformVectorOLD(hc.rayDir) );
|
||||
|
||||
float epsilonDist = hc.view->GetScreenScaleFactor( worldPos ) * 0.01f;
|
||||
float hitDist;
|
||||
|
||||
float tr = hc.distanceTollerance/2 + 1;
|
||||
BBox box;
|
||||
box.min = m_box.min - Vec3(tr+epsilonDist,tr+epsilonDist,tr+epsilonDist);
|
||||
box.max = m_box.max + Vec3(tr+epsilonDist,tr+epsilonDist,tr+epsilonDist);
|
||||
if (box.IsIntersectRay( xformedRaySrc,xformedRayDir,p ))
|
||||
{
|
||||
if (m_box.RayEdgeIntersection( xformedRaySrc,xformedRayDir,epsilonDist,hitDist,p ))
|
||||
{
|
||||
hc.dist = GetDistance(xformedRaySrc,p);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::BeginEditParams( IEditor *ie,int flags )
|
||||
{
|
||||
CBaseObject::BeginEditParams( ie,flags );
|
||||
if (!m_pPanel)
|
||||
{
|
||||
m_pPanel = new CPickEntitiesPanel;
|
||||
m_pPanel->Create( CPickEntitiesPanel::IDD,AfxGetMainWnd() );
|
||||
m_nRollupId = ie->AddRollUpPage( ROLLUP_OBJECTS,"Attached Entities",m_pPanel );
|
||||
}
|
||||
if (m_pPanel)
|
||||
m_pPanel->SetOwner(this);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::EndEditParams( IEditor *ie )
|
||||
{
|
||||
if (m_nRollupId)
|
||||
ie->RemoveRollUpPage( ROLLUP_OBJECTS, m_nRollupId);
|
||||
m_nRollupId = 0;
|
||||
m_pPanel = NULL;
|
||||
CBaseObject::EndEditParams( ie );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::OnAreaChange(IVariable *pVar)
|
||||
{
|
||||
UpdateGameArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::OnSizeChange(IVariable *pVar)
|
||||
{
|
||||
Vec3 size( 0,0,0 );
|
||||
size.x = mv_width;
|
||||
size.y = mv_length;
|
||||
size.z = mv_height;
|
||||
|
||||
m_box.min = -size/2;
|
||||
m_box.max = size/2;
|
||||
// Make volume position bottom of bounding box.
|
||||
m_box.min.z = 0;
|
||||
m_box.max.z = size.z;
|
||||
UpdateGameArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::Display( DisplayContext &dc )
|
||||
{
|
||||
COLORREF wireColor,solidColor;
|
||||
float wireOffset = 0;
|
||||
float alpha = 0.3f;
|
||||
if (IsSelected())
|
||||
{
|
||||
wireColor = dc.GetSelectedColor();
|
||||
solidColor = GetColor();
|
||||
wireOffset = -0.1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
wireColor = GetColor();
|
||||
solidColor = GetColor();
|
||||
}
|
||||
|
||||
//dc.renderer->SetCullMode( R_CULL_DISABLE );
|
||||
|
||||
dc.PushMatrix( GetWorldTM() );
|
||||
BBox box=m_box;
|
||||
|
||||
bool bFrozen = IsFrozen();
|
||||
|
||||
if (bFrozen)
|
||||
dc.SetFreezeColor();
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (!bFrozen)
|
||||
dc.SetColor( solidColor,alpha );
|
||||
|
||||
if (IsSelected())
|
||||
{
|
||||
int rstate = dc.ClearStateFlag( GS_DEPTHWRITE );
|
||||
dc.renderer->SetCullMode( R_CULL_DISABLE );
|
||||
dc.DrawSolidBox( box.min,box.max );
|
||||
dc.SetState( rstate );
|
||||
dc.renderer->SetCullMode( R_CULL_BACK );
|
||||
}
|
||||
|
||||
if (!bFrozen)
|
||||
dc.SetColor( wireColor,1 );
|
||||
dc.DrawWireBox( box.min,box.max,wireOffset );
|
||||
if (m_edgeWidth)
|
||||
{
|
||||
float fFadeScale=m_edgeWidth/200.0f;
|
||||
BBox InnerBox=box;
|
||||
Vec3 EdgeDist=InnerBox.max-InnerBox.min;
|
||||
InnerBox.min.x+=EdgeDist.x*fFadeScale; InnerBox.max.x-=EdgeDist.x*fFadeScale;
|
||||
InnerBox.min.y+=EdgeDist.y*fFadeScale; InnerBox.max.y-=EdgeDist.y*fFadeScale;
|
||||
InnerBox.min.z+=EdgeDist.z*fFadeScale; InnerBox.max.z-=EdgeDist.z*fFadeScale;
|
||||
dc.DrawWireBox( InnerBox.min,InnerBox.max );
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
dc.PopMatrix();
|
||||
|
||||
if (!m_entities.empty())
|
||||
{
|
||||
Vec3 vcol = Vec3(1, 1, 1);
|
||||
for (int i = 0; i < m_entities.size(); i++)
|
||||
{
|
||||
CBaseObject *obj = GetEntity(i);
|
||||
if (!obj)
|
||||
continue;
|
||||
dc.DrawLine(GetWorldPos(), obj->GetWorldPos(), CFColor(vcol.x,vcol.y,vcol.z,0.7f), CFColor(1,1,1,0.7f) );
|
||||
}
|
||||
}
|
||||
|
||||
DrawDefault(dc);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::InvalidateTM()
|
||||
{
|
||||
CBaseObject::InvalidateTM();
|
||||
UpdateGameArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::Serialize( CObjectArchive &ar )
|
||||
{
|
||||
CBaseObject::Serialize( ar );
|
||||
XmlNodeRef xmlNode = ar.node;
|
||||
if (ar.bLoading)
|
||||
{
|
||||
m_entities.clear();
|
||||
|
||||
|
||||
BBox box;
|
||||
xmlNode->getAttr( "BoxMin",box.min );
|
||||
xmlNode->getAttr( "BoxMax",box.max );
|
||||
|
||||
// Load Entities.
|
||||
XmlNodeRef entities = xmlNode->findChild( "Entities" );
|
||||
if (entities)
|
||||
{
|
||||
for (int i = 0; i < entities->getChildCount(); i++)
|
||||
{
|
||||
XmlNodeRef ent = entities->getChild(i);
|
||||
GUID entityId;
|
||||
ent->getAttr( "Id",entityId );
|
||||
m_entities.push_back(entityId);
|
||||
}
|
||||
}
|
||||
SetAreaId( m_areaId );
|
||||
SetBox(box);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Saving.
|
||||
// xmlNode->setAttr( "AreaId",m_areaId );
|
||||
xmlNode->setAttr( "BoxMin",m_box.min );
|
||||
xmlNode->setAttr( "BoxMax",m_box.max );
|
||||
// Save Entities.
|
||||
if (!m_entities.empty())
|
||||
{
|
||||
XmlNodeRef nodes = xmlNode->newChild( "Entities" );
|
||||
for (int i = 0; i < m_entities.size(); i++)
|
||||
{
|
||||
XmlNodeRef entNode = nodes->newChild( "Entity" );
|
||||
entNode->setAttr( "Id",m_entities[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
XmlNodeRef CAreaBox::Export( const CString &levelPath,XmlNodeRef &xmlNode )
|
||||
{
|
||||
XmlNodeRef objNode = CBaseObject::Export( levelPath,xmlNode );
|
||||
Matrix44 wtm = GetWorldTM();
|
||||
// objNode->setAttr( "AreaId",m_areaId );
|
||||
// objNode->setAttr( "EdgeWidth",m_edgeWidth );
|
||||
// Export Entities.
|
||||
if (!m_entities.empty())
|
||||
{
|
||||
XmlNodeRef nodes = objNode->newChild( "Entities" );
|
||||
for (int i = 0; i < m_entities.size(); i++)
|
||||
{
|
||||
XmlNodeRef entNode = nodes->newChild( "Entity" );
|
||||
CBaseObject *obj = FindObject(m_entities[i]);
|
||||
CString name;
|
||||
if (obj)
|
||||
name = obj->GetName();
|
||||
entNode->setAttr( "Name",name );
|
||||
}
|
||||
}
|
||||
return objNode;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::SetAreaId(int nAreaId)
|
||||
{
|
||||
m_areaId=nAreaId;
|
||||
UpdateGameArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CAreaBox::GetAreaId()
|
||||
{
|
||||
return m_areaId;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::SetBox(BBox box)
|
||||
{
|
||||
m_box=box;
|
||||
UpdateGameArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
BBox CAreaBox::GetBox()
|
||||
{
|
||||
return m_box;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::AddEntity( CBaseObject *pEntity )
|
||||
{
|
||||
assert( pEntity );
|
||||
// Check if this entity already binded.
|
||||
if (std::find(m_entities.begin(),m_entities.end(),pEntity->GetId()) != m_entities.end())
|
||||
return;
|
||||
|
||||
StoreUndo( "Add Entity" );
|
||||
m_entities.push_back(pEntity->GetId());
|
||||
UpdateGameArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::RemoveEntity( int index )
|
||||
{
|
||||
assert( index >= 0 && index < m_entities.size() );
|
||||
StoreUndo( "Remove Entity" );
|
||||
|
||||
m_entities.erase( m_entities.begin()+index );
|
||||
UpdateGameArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CBaseObject* CAreaBox::GetEntity( int index )
|
||||
{
|
||||
assert( index >= 0 && index < m_entities.size() );
|
||||
return GetIEditor()->GetObjectManager()->FindObject(m_entities[index]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::OnEvent( ObjectEvent event )
|
||||
{
|
||||
if (event == EVENT_AFTER_LOAD)
|
||||
{
|
||||
// After loading Update game structure.
|
||||
UpdateGameArea();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaBox::UpdateGameArea()
|
||||
{
|
||||
if (!IsCreateGameObjects())
|
||||
return;
|
||||
|
||||
// AffineParts affineParts;
|
||||
// affineParts.SpectralDecompose(GetWorldTM());
|
||||
// Vec3 angles = RAD2DEG(affineParts.rot.GetEulerAngles());
|
||||
|
||||
BBox box = m_box;
|
||||
// box.min+=affineParts.pos;
|
||||
// box.max+=affineParts.pos;
|
||||
|
||||
if (m_IArea)
|
||||
{
|
||||
m_IArea->SetMin(box.min);
|
||||
m_IArea->SetMax(box.max);
|
||||
m_IArea->SetTM(GetWorldTM());
|
||||
m_IArea->SetProximity( m_edgeWidth );
|
||||
m_IArea->SetID(m_areaId);
|
||||
m_IArea->SetGroup(mv_groupId);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<string> entitiesName;
|
||||
entitiesName.clear();
|
||||
//areaFix
|
||||
// m_IArea = GetIEditor()->GetGame()->CreateArea(box.min, box.max, GetWorldTM(), entitiesName, m_areaId, m_edgeWidth );
|
||||
m_IArea = GetIEditor()->GetGame()->GetAreaManager()->CreateArea(box.min, box.max, GetWorldTM(), entitiesName, m_areaId, -1, m_edgeWidth );
|
||||
if (m_IArea)
|
||||
{
|
||||
m_IArea->SetMin(box.min);
|
||||
m_IArea->SetMax(box.max);
|
||||
m_IArea->SetTM(GetWorldTM());
|
||||
m_IArea->SetProximity( m_edgeWidth );
|
||||
m_IArea->SetID(m_areaId);
|
||||
m_IArea->SetGroup(mv_groupId);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_IArea)
|
||||
{
|
||||
m_IArea->ClearEntities();
|
||||
for (int i = 0; i < GetEntityCount(); i++)
|
||||
{
|
||||
CBaseObject *obj = GetEntity(i);
|
||||
if (obj)
|
||||
m_IArea->AddEntity( obj->GetName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
125
Editor/Objects/AreaBox.h
Normal file
125
Editor/Objects/AreaBox.h
Normal file
@@ -0,0 +1,125 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: AreaBox.h
|
||||
// Version: v1.00
|
||||
// Created: 22/10/2001 by Lennert.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: AreaBox object definition.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __AreaBox_h__
|
||||
#define __AreaBox_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "BaseObject.h"
|
||||
#include "PickEntitiesPanel.h"
|
||||
|
||||
/*!
|
||||
* CAreaBox is a box volume in space where entites can be attached to.
|
||||
*
|
||||
*/
|
||||
class CAreaBox : public CBaseObject, public IPickEntitesOwner
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CAreaBox)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
|
||||
void Display( DisplayContext &dc );
|
||||
|
||||
void InvalidateTM();
|
||||
|
||||
void SetScale( const Vec3d &scale );
|
||||
|
||||
void GetBoundBox( BBox &box );
|
||||
void GetLocalBounds( BBox &box );
|
||||
bool HitTest( HitContext &hc );
|
||||
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
|
||||
void OnEvent( ObjectEvent event );
|
||||
|
||||
void Serialize( CObjectArchive &ar );
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
|
||||
void SetAreaId(int nAreaId);
|
||||
int GetAreaId();
|
||||
void SetBox(BBox box);
|
||||
BBox GetBox();
|
||||
|
||||
void UpdateGameArea();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Binded entities.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Bind entity to this shape.
|
||||
void AddEntity( CBaseObject *pEntity );
|
||||
void RemoveEntity( int index );
|
||||
CBaseObject* GetEntity( int index );
|
||||
int GetEntityCount() { return m_entities.size(); }
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CAreaBox();
|
||||
|
||||
void DeleteThis() { delete this; };
|
||||
|
||||
void OnAreaChange(IVariable *pVar);
|
||||
void OnSizeChange(IVariable *pVar);
|
||||
|
||||
//! List of binded entities.
|
||||
std::vector<GUID> m_entities;
|
||||
|
||||
//! AreaId
|
||||
CVariable<int> m_areaId;
|
||||
//! EdgeWidth
|
||||
CVariable<float> m_edgeWidth;
|
||||
//! Local volume space bounding box.
|
||||
CVariable<float> mv_width;
|
||||
CVariable<float> mv_length;
|
||||
CVariable<float> mv_height;
|
||||
CVariable<int> mv_groupId;
|
||||
|
||||
//! Local volume space bounding box.
|
||||
BBox m_box;
|
||||
|
||||
struct IXArea *m_IArea;
|
||||
|
||||
static int m_nRollupId;
|
||||
static CPickEntitiesPanel *m_pPanel;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of AreaBox.
|
||||
*/
|
||||
class CAreaBoxClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {0EEA0A78-428C-4ad4-9EC1-97525AEB1BCB}
|
||||
static const GUID guid = { 0xeea0a78, 0x428c, 0x4ad4, { 0x9e, 0xc1, 0x97, 0x52, 0x5a, 0xeb, 0x1b, 0xcb } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_VOLUME; };
|
||||
const char* ClassName() { return "AreaBox"; };
|
||||
const char* Category() { return "Area"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CAreaBox); };
|
||||
int GameCreationOrder() { return 52; };
|
||||
};
|
||||
|
||||
#endif // __AreaBox_h__
|
||||
382
Editor/Objects/AreaSphere.cpp
Normal file
382
Editor/Objects/AreaSphere.cpp
Normal file
@@ -0,0 +1,382 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: AreaSphere.cpp
|
||||
// Version: v1.00
|
||||
// Created: 25/10/2002 by Lennert.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: CAreaSphere implementation.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "AreaSphere.h"
|
||||
#include "ObjectManager.h"
|
||||
#include "..\Viewport.h"
|
||||
#include <IEntitySystem.h>
|
||||
#include <IGame.h>
|
||||
#include <IMarkers.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CBase implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CAreaSphere,CBaseObject)
|
||||
|
||||
int CAreaSphere::m_nRollupId=0;
|
||||
CPickEntitiesPanel* CAreaSphere::m_pPanel=NULL;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CAreaSphere::CAreaSphere()
|
||||
{
|
||||
m_IArea=NULL;
|
||||
m_areaId = -1;
|
||||
m_edgeWidth=0;
|
||||
m_radius = 3;
|
||||
mv_groupId = 0;
|
||||
|
||||
AddVariable( m_areaId,"AreaId",functor(*this,&CAreaSphere::OnAreaChange) );
|
||||
AddVariable( m_edgeWidth,"FadeInZone",functor(*this,&CAreaSphere::OnSizeChange) );
|
||||
AddVariable( m_radius,"Radius",functor(*this,&CAreaSphere::OnSizeChange) );
|
||||
AddVariable( mv_groupId,"GroupId",functor(*this,&CAreaSphere::OnAreaChange) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaSphere::Done()
|
||||
{
|
||||
if (m_IArea)
|
||||
{
|
||||
GetIEditor()->GetGame()->GetAreaManager()->DeleteArea( m_IArea );
|
||||
m_IArea=NULL;
|
||||
}
|
||||
CBaseObject::Done();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAreaSphere::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
bool res = CBaseObject::Init( ie,prev,file );
|
||||
SetColor( RGB(0,0,255) );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaSphere::GetBoundBox( BBox &box )
|
||||
{
|
||||
box.min=Vec3d(-m_radius, -m_radius, -m_radius);
|
||||
box.max=Vec3d(m_radius, m_radius, m_radius);
|
||||
box.Transform( GetWorldTM() );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaSphere::GetLocalBounds( BBox &box )
|
||||
{
|
||||
box.min = Vec3d(-m_radius, -m_radius, -m_radius);
|
||||
box.max = Vec3d(m_radius, m_radius, m_radius);
|
||||
}
|
||||
|
||||
void CAreaSphere::SetAngles( const Vec3d &angles )
|
||||
{
|
||||
// Ignore angles on CAreaBox.
|
||||
}
|
||||
|
||||
void CAreaSphere::SetScale( const Vec3d &scale )
|
||||
{
|
||||
// Ignore scale on CAreaBox.
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAreaSphere::HitTest( HitContext &hc )
|
||||
{
|
||||
Vec3 origin = GetWorldPos();
|
||||
Vec3 w = origin - hc.raySrc;
|
||||
w = hc.rayDir.Cross( w );
|
||||
float d = w.Length();
|
||||
|
||||
Matrix44 invertWTM = GetWorldTM();
|
||||
Vec3 worldPos = invertWTM.GetTranslationOLD();
|
||||
float epsilonDist = hc.view->GetScreenScaleFactor( worldPos ) * 0.01f;
|
||||
if ((d < m_radius + epsilonDist) &&
|
||||
(d > m_radius - epsilonDist))
|
||||
{
|
||||
hc.dist = GetDistance(hc.raySrc,origin);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaSphere::BeginEditParams( IEditor *ie,int flags )
|
||||
{
|
||||
CBaseObject::BeginEditParams( ie,flags );
|
||||
if (!m_pPanel)
|
||||
{
|
||||
m_pPanel = new CPickEntitiesPanel;
|
||||
m_pPanel->Create( CPickEntitiesPanel::IDD,AfxGetMainWnd() );
|
||||
m_nRollupId = ie->AddRollUpPage( ROLLUP_OBJECTS,"Attached Entities",m_pPanel );
|
||||
}
|
||||
if (m_pPanel)
|
||||
m_pPanel->SetOwner(this);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaSphere::EndEditParams( IEditor *ie )
|
||||
{
|
||||
if (m_nRollupId)
|
||||
ie->RemoveRollUpPage( ROLLUP_OBJECTS, m_nRollupId);
|
||||
m_nRollupId = 0;
|
||||
m_pPanel = NULL;
|
||||
CBaseObject::EndEditParams( ie );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaSphere::OnAreaChange(IVariable *pVar)
|
||||
{
|
||||
UpdateGameArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaSphere::OnSizeChange(IVariable *pVar)
|
||||
{
|
||||
UpdateGameArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaSphere::Display( DisplayContext &dc )
|
||||
{
|
||||
COLORREF wireColor,solidColor;
|
||||
float wireOffset = 0;
|
||||
float alpha = 0.3f;
|
||||
if (IsSelected())
|
||||
{
|
||||
wireColor = dc.GetSelectedColor();
|
||||
solidColor = GetColor();
|
||||
wireOffset = -0.1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
wireColor = GetColor();
|
||||
solidColor = GetColor();
|
||||
}
|
||||
|
||||
|
||||
const Matrix44 &tm = GetWorldTM();
|
||||
Vec3 pos = GetWorldPos();
|
||||
|
||||
bool bFrozen = IsFrozen();
|
||||
|
||||
if (bFrozen)
|
||||
dc.SetFreezeColor();
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (!bFrozen)
|
||||
dc.SetColor( solidColor,alpha );
|
||||
|
||||
if (IsSelected())
|
||||
{
|
||||
dc.renderer->SetCullMode( R_CULL_DISABLE );
|
||||
int rstate = dc.ClearStateFlag( GS_DEPTHWRITE );
|
||||
dc.DrawBall( pos, m_radius );
|
||||
dc.SetState( rstate );
|
||||
dc.renderer->SetCullMode( R_CULL_BACK );
|
||||
}
|
||||
|
||||
if (!bFrozen)
|
||||
dc.SetColor( wireColor,1 );
|
||||
dc.DrawWireSphere( pos, m_radius );
|
||||
if (m_edgeWidth)
|
||||
dc.DrawWireSphere( pos, m_radius-m_edgeWidth );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (!m_entities.empty())
|
||||
{
|
||||
Vec3 vcol = Vec3(1, 1, 1);
|
||||
for (int i = 0; i < m_entities.size(); i++)
|
||||
{
|
||||
CBaseObject *obj = GetEntity(i);
|
||||
if (!obj)
|
||||
continue;
|
||||
dc.DrawLine(GetWorldPos(), obj->GetWorldPos(), CFColor(vcol.x,vcol.y,vcol.z,0.7f), CFColor(1,1,1,0.7f) );
|
||||
}
|
||||
}
|
||||
|
||||
DrawDefault(dc);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaSphere::Serialize( CObjectArchive &ar )
|
||||
{
|
||||
CBaseObject::Serialize( ar );
|
||||
XmlNodeRef xmlNode = ar.node;
|
||||
if (ar.bLoading)
|
||||
{
|
||||
m_entities.clear();
|
||||
|
||||
BBox box;
|
||||
// Load Entities.
|
||||
XmlNodeRef entities = xmlNode->findChild( "Entities" );
|
||||
if (entities)
|
||||
{
|
||||
for (int i = 0; i < entities->getChildCount(); i++)
|
||||
{
|
||||
XmlNodeRef ent = entities->getChild(i);
|
||||
GUID entityId;
|
||||
ent->getAttr( "Id",entityId );
|
||||
m_entities.push_back(entityId);
|
||||
}
|
||||
}
|
||||
SetAreaId( m_areaId );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Saving.
|
||||
// Save Entities.
|
||||
if (!m_entities.empty())
|
||||
{
|
||||
XmlNodeRef nodes = xmlNode->newChild( "Entities" );
|
||||
for (int i = 0; i < m_entities.size(); i++)
|
||||
{
|
||||
XmlNodeRef entNode = nodes->newChild( "Entity" );
|
||||
entNode->setAttr( "Id",m_entities[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
XmlNodeRef CAreaSphere::Export( const CString &levelPath,XmlNodeRef &xmlNode )
|
||||
{
|
||||
XmlNodeRef objNode = CBaseObject::Export( levelPath,xmlNode );
|
||||
Matrix44 wtm = GetWorldTM();
|
||||
// objNode->setAttr( "AreaId",m_areaId );
|
||||
// objNode->setAttr( "EdgeWidth",m_edgeWidth );
|
||||
// Export Entities.
|
||||
if (!m_entities.empty())
|
||||
{
|
||||
XmlNodeRef nodes = objNode->newChild( "Entities" );
|
||||
for (int i = 0; i < m_entities.size(); i++)
|
||||
{
|
||||
XmlNodeRef entNode = nodes->newChild( "Entity" );
|
||||
CBaseObject *obj = FindObject(m_entities[i]);
|
||||
CString name;
|
||||
if (obj)
|
||||
name = obj->GetName();
|
||||
entNode->setAttr( "Name",name );
|
||||
}
|
||||
}
|
||||
return objNode;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaSphere::SetAreaId(int nAreaId)
|
||||
{
|
||||
m_areaId=nAreaId;
|
||||
UpdateGameArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CAreaSphere::GetAreaId()
|
||||
{
|
||||
return m_areaId;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaSphere::SetRadius(float fRadius)
|
||||
{
|
||||
m_radius=fRadius;
|
||||
UpdateGameArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
float CAreaSphere::GetRadius()
|
||||
{
|
||||
return m_radius;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaSphere::AddEntity( CBaseObject *pEntity )
|
||||
{
|
||||
assert( pEntity );
|
||||
// Check if this entity already binded.
|
||||
if (std::find(m_entities.begin(),m_entities.end(),pEntity->GetId()) != m_entities.end())
|
||||
return;
|
||||
|
||||
StoreUndo( "Add Entity" );
|
||||
m_entities.push_back(pEntity->GetId());
|
||||
UpdateGameArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaSphere::RemoveEntity( int index )
|
||||
{
|
||||
assert( index >= 0 && index < m_entities.size() );
|
||||
StoreUndo( "Remove Entity" );
|
||||
|
||||
m_entities.erase( m_entities.begin()+index );
|
||||
UpdateGameArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CBaseObject* CAreaSphere::GetEntity( int index )
|
||||
{
|
||||
assert( index >= 0 && index < m_entities.size() );
|
||||
return GetIEditor()->GetObjectManager()->FindObject(m_entities[index]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaSphere::OnEvent( ObjectEvent event )
|
||||
{
|
||||
if (event == EVENT_AFTER_LOAD)
|
||||
{
|
||||
// After loading Update game structure.
|
||||
UpdateGameArea();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAreaSphere::UpdateGameArea()
|
||||
{
|
||||
if (!IsCreateGameObjects())
|
||||
return;
|
||||
|
||||
Vec3 Pos=GetWorldPos();
|
||||
|
||||
if (m_IArea)
|
||||
{
|
||||
m_IArea->SetCenter(Pos);
|
||||
m_IArea->SetRadius(m_radius);
|
||||
m_IArea->SetProximity( m_edgeWidth );
|
||||
m_IArea->SetID(m_areaId);
|
||||
m_IArea->SetGroup(mv_groupId);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<string> entitiesName;
|
||||
entitiesName.clear();
|
||||
//areaFix
|
||||
// m_IArea = GetIEditor()->GetGame()->CreateArea(Pos, m_radius, entitiesName, m_areaId, m_edgeWidth );
|
||||
m_IArea = GetIEditor()->GetGame()->GetAreaManager()->CreateArea(Pos, m_radius, entitiesName, m_areaId, -1, m_edgeWidth );
|
||||
if (m_IArea)
|
||||
{
|
||||
m_IArea->SetCenter(Pos);
|
||||
m_IArea->SetRadius(m_radius);
|
||||
m_IArea->SetProximity( m_edgeWidth );
|
||||
m_IArea->SetID(m_areaId);
|
||||
m_IArea->SetGroup(mv_groupId);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_IArea)
|
||||
{
|
||||
m_IArea->ClearEntities();
|
||||
for (int i = 0; i < GetEntityCount(); i++)
|
||||
{
|
||||
CBaseObject *obj = GetEntity(i);
|
||||
if (obj)
|
||||
m_IArea->AddEntity( obj->GetName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
120
Editor/Objects/AreaSphere.h
Normal file
120
Editor/Objects/AreaSphere.h
Normal file
@@ -0,0 +1,120 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: AreaSphere.h
|
||||
// Version: v1.00
|
||||
// Created: 25/10/2001 by Lennert.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: AreaSphere object definition.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __AreaSphere_h__
|
||||
#define __AreaSphere_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "BaseObject.h"
|
||||
#include "PickEntitiesPanel.h"
|
||||
|
||||
/*!
|
||||
* CAreaSphere is a sphere volume in space where entites can be attached to.
|
||||
*
|
||||
*/
|
||||
class CAreaSphere : public CBaseObject, public IPickEntitesOwner
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CAreaSphere)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
|
||||
void Display( DisplayContext &dc );
|
||||
|
||||
void SetAngles( const Vec3d &angles );
|
||||
void SetScale( const Vec3d &scale );
|
||||
|
||||
void GetBoundBox( BBox &box );
|
||||
void GetLocalBounds( BBox &box );
|
||||
|
||||
bool HitTest( HitContext &hc );
|
||||
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
|
||||
void OnEvent( ObjectEvent event );
|
||||
|
||||
void Serialize( CObjectArchive &ar );
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
|
||||
void SetAreaId(int nAreaId);
|
||||
int GetAreaId();
|
||||
void SetRadius(float fRadius);
|
||||
float GetRadius();
|
||||
|
||||
void UpdateGameArea();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Binded entities.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Bind entity to this shape.
|
||||
void AddEntity( CBaseObject *pEntity );
|
||||
void RemoveEntity( int index );
|
||||
CBaseObject* GetEntity( int index );
|
||||
int GetEntityCount() { return m_entities.size(); }
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CAreaSphere();
|
||||
|
||||
void DeleteThis() { delete this; };
|
||||
|
||||
void OnAreaChange(IVariable *pVar);
|
||||
void OnSizeChange(IVariable *pVar);
|
||||
|
||||
//! List of binded entities.
|
||||
std::vector<GUID> m_entities;
|
||||
|
||||
//! AreaId
|
||||
CVariable<int> m_areaId;
|
||||
//! EdgeWidth
|
||||
CVariable<float> m_edgeWidth;
|
||||
//! Local volume space radius.
|
||||
CVariable<float> m_radius;
|
||||
CVariable<int> mv_groupId;
|
||||
|
||||
struct IXArea *m_IArea;
|
||||
|
||||
static int m_nRollupId;
|
||||
static CPickEntitiesPanel *m_pPanel;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of AreaBox.
|
||||
*/
|
||||
class CAreaSphereClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {640A1105-A421-4ed3-9E71-7783F091AA27}
|
||||
static const GUID guid = { 0x640a1105, 0xa421, 0x4ed3, { 0x9e, 0x71, 0x77, 0x83, 0xf0, 0x91, 0xaa, 0x27 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_VOLUME; };
|
||||
const char* ClassName() { return "AreaSphere"; };
|
||||
const char* Category() { return "Area"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CAreaSphere); };
|
||||
int GameCreationOrder() { return 51; };
|
||||
};
|
||||
|
||||
#endif // __AreaSphere_h__
|
||||
435
Editor/Objects/AxisGizmo.cpp
Normal file
435
Editor/Objects/AxisGizmo.cpp
Normal file
@@ -0,0 +1,435 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: axisgizmo.cpp
|
||||
// Version: v1.00
|
||||
// Created: 2/7/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "AxisGizmo.h"
|
||||
#include "DisplayContext.h"
|
||||
|
||||
#include "..\Viewport.h"
|
||||
#include "..\DisplaySettings.h"
|
||||
#include "ObjectManager.h"
|
||||
|
||||
#include "GizmoManager.h"
|
||||
#include "Settings.h"
|
||||
#include "Cry_Geo.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CAxisGizmo implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CAxisGizmo::m_axisGizmoCount = 0;
|
||||
|
||||
#define PLANE_SCALE (0.3f)
|
||||
#define HIT_RADIUS (4)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CAxisGizmo::CAxisGizmo( CBaseObject *object )
|
||||
{
|
||||
assert( object != 0 );
|
||||
m_object = object;
|
||||
|
||||
// Set selectable flag.
|
||||
SetFlags( EGIZMO_SELECTABLE );
|
||||
|
||||
m_axisGizmoCount++;
|
||||
m_object->AddEventListener( functor(*this,&CAxisGizmo::OnObjectEvent) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CAxisGizmo::~CAxisGizmo()
|
||||
{
|
||||
m_object->RemoveEventListener( functor(*this,&CAxisGizmo::OnObjectEvent) );
|
||||
m_axisGizmoCount--;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAxisGizmo::OnObjectEvent( CBaseObject *object,int event )
|
||||
{
|
||||
if (event == CBaseObject::ON_DELETE || event == CBaseObject::ON_UNSELECT)
|
||||
{
|
||||
// This gizmo must be deleted as well.
|
||||
GetGizmoManager()->RemoveGizmo(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAxisGizmo::Display( DisplayContext &dc )
|
||||
{
|
||||
bool bNotSelected = !m_object->CheckFlags(OBJFLAG_VISIBLE) || !m_object->IsSelected();
|
||||
if (bNotSelected)
|
||||
{
|
||||
// This gizmo must be deleted.
|
||||
DeleteThis();
|
||||
return;
|
||||
}
|
||||
DrawAxis( dc );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAxisGizmo::GetWorldBounds( BBox &bbox )
|
||||
{
|
||||
m_object->GetBoundBox( bbox );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAxisGizmo::DrawAxis( DisplayContext &dc )
|
||||
{
|
||||
float fScreenScale = dc.view->GetScreenScaleFactor(m_object->GetWorldPos());
|
||||
float size = gSettings.gizmo.axisGizmoSize * fScreenScale;
|
||||
|
||||
int prevRState = dc.GetState();
|
||||
|
||||
if (!(dc.flags & DISPLAY_2D))
|
||||
prevRState = dc.SetStateFlag(GS_NODEPTHTEST);
|
||||
Vec3 x(size,0,0);
|
||||
Vec3 y(0,size,0);
|
||||
Vec3 z(0,0,size);
|
||||
|
||||
Matrix44 tm;
|
||||
|
||||
RefCoordSys refCoordSys = GetIEditor()->GetReferenceCoordSys();
|
||||
if (refCoordSys == COORDS_LOCAL)
|
||||
{
|
||||
tm = m_object->GetWorldTM();
|
||||
tm.NoScale();
|
||||
}
|
||||
else
|
||||
{
|
||||
tm.SetIdentity();
|
||||
if (dc.flags & DISPLAY_2D)
|
||||
{
|
||||
tm = dc.view->GetViewTM();
|
||||
}
|
||||
tm.SetTranslationOLD( m_object->GetWorldPos() );
|
||||
}
|
||||
|
||||
dc.PushMatrix(tm);
|
||||
|
||||
bool bNeedX = true;
|
||||
bool bNeedY = true;
|
||||
bool bNeedZ = true;
|
||||
|
||||
if (dc.flags & DISPLAY_2D)
|
||||
{
|
||||
if (dc.view->GetType() == ET_ViewportXY)
|
||||
bNeedZ = false;
|
||||
else if (dc.view->GetType() == ET_ViewportXZ)
|
||||
bNeedY = false;
|
||||
else if (dc.view->GetType() == ET_ViewportYZ)
|
||||
bNeedX = false;
|
||||
|
||||
if (refCoordSys == COORDS_VIEW)
|
||||
{
|
||||
bNeedX = true;
|
||||
bNeedY = true;
|
||||
bNeedZ = false;
|
||||
}
|
||||
}
|
||||
|
||||
Vec3 colSelected(1,1,0);
|
||||
Vec3 axisColor(1,1,1);
|
||||
|
||||
if (dc.flags & DISPLAY_2D)
|
||||
{
|
||||
//axisColor = Vec3(0,0,0);
|
||||
//colSelected = Vec3(0.8f,0.8f,0);
|
||||
}
|
||||
|
||||
dc.SetColor(axisColor);
|
||||
if (bNeedX && gSettings.gizmo.axisGizmoText)
|
||||
dc.DrawTextLabel( tm.TransformPointOLD(x),1.0f,"X" );
|
||||
if (bNeedY && gSettings.gizmo.axisGizmoText)
|
||||
dc.DrawTextLabel( tm.TransformPointOLD(y),1.0f,"Y" );
|
||||
if (bNeedZ && gSettings.gizmo.axisGizmoText)
|
||||
dc.DrawTextLabel( tm.TransformPointOLD(z),1.0f,"Z" );
|
||||
|
||||
int axis = GetIEditor()->GetAxisConstrains();
|
||||
if (m_highlightAxis)
|
||||
axis = m_highlightAxis;
|
||||
|
||||
float linew[3];
|
||||
linew[0] = linew[1] = linew[2] = 1;
|
||||
Vec3 colX(1,0,0),colY(0,1,0),colZ(0,0,1);
|
||||
Vec3 colXArrow=colX,colYArrow=colY,colZArrow=colZ;
|
||||
if (axis)
|
||||
{
|
||||
float col[4] = { 1,0,0,1 };
|
||||
if (axis == AXIS_X || axis == AXIS_XY || axis == AXIS_XZ)
|
||||
{
|
||||
colX = colSelected;
|
||||
dc.SetColor(colSelected);
|
||||
if (bNeedX && gSettings.gizmo.axisGizmoText)
|
||||
dc.DrawTextLabel( tm.TransformPointOLD(x),1.0f,"X" );
|
||||
linew[0] = 2;
|
||||
}
|
||||
if (axis == AXIS_Y || axis == AXIS_XY || axis == AXIS_YZ)
|
||||
{
|
||||
colY = colSelected;
|
||||
dc.SetColor(colSelected);
|
||||
if (bNeedY && gSettings.gizmo.axisGizmoText)
|
||||
dc.DrawTextLabel( tm.TransformPointOLD(y),1.0f,"Y" );
|
||||
linew[1] = 2;
|
||||
}
|
||||
if (axis == AXIS_Z || axis == AXIS_XZ || axis == AXIS_YZ)
|
||||
{
|
||||
colZ = colSelected;
|
||||
dc.SetColor(colSelected);
|
||||
if (bNeedZ && gSettings.gizmo.axisGizmoText)
|
||||
dc.DrawTextLabel( tm.TransformPointOLD(z),1.0f,"Z" );
|
||||
linew[2] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
x = x * 0.8f;
|
||||
y = y * 0.8f;
|
||||
z = z * 0.8f;
|
||||
float fArrowScale = fScreenScale * 0.07f;
|
||||
|
||||
if (bNeedX)
|
||||
{
|
||||
dc.SetColor( colX );
|
||||
dc.SetLineWidth( linew[0] );
|
||||
dc.DrawLine( Vec3(0,0,0),x );
|
||||
dc.SetColor( colXArrow );
|
||||
dc.DrawArrow( x-x*0.1f,x,fArrowScale );
|
||||
}
|
||||
if (bNeedY)
|
||||
{
|
||||
dc.SetColor( colY );
|
||||
dc.SetLineWidth( linew[1] );
|
||||
dc.DrawLine( Vec3(0,0,0),y );
|
||||
dc.SetColor( colYArrow );
|
||||
dc.DrawArrow( y-y*0.1f,y,fArrowScale );
|
||||
}
|
||||
if (bNeedZ)
|
||||
{
|
||||
dc.SetColor( colZ );
|
||||
dc.SetLineWidth( linew[2] );
|
||||
dc.DrawLine( Vec3(0,0,0),z );
|
||||
dc.SetColor( colZArrow );
|
||||
dc.DrawArrow( z-z*0.1f,z,fArrowScale );
|
||||
}
|
||||
|
||||
dc.SetLineWidth(1);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Draw axis planes.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
Vec3 colXY[2];
|
||||
Vec3 colXZ[2];
|
||||
Vec3 colYZ[2];
|
||||
|
||||
colX = Vec3(1,0,0);
|
||||
colY = Vec3(0,1,0);
|
||||
colZ = Vec3(0,0,1);
|
||||
colXY[0] = colX;
|
||||
colXY[1] = colY;
|
||||
colXZ[0] = colX;
|
||||
colXZ[1] = colZ;
|
||||
colYZ[0] = colY;
|
||||
colYZ[1] = colZ;
|
||||
|
||||
linew[0] = linew[1] = linew[2] = 1;
|
||||
if (axis)
|
||||
{
|
||||
if (axis == AXIS_XY)
|
||||
{
|
||||
colXY[0] = colSelected;
|
||||
colXY[1] = colSelected;
|
||||
linew[0] = 2;
|
||||
}
|
||||
else if (axis == AXIS_XZ)
|
||||
{
|
||||
colXZ[0] = colSelected;
|
||||
colXZ[1] = colSelected;
|
||||
linew[1] = 2;
|
||||
}
|
||||
else if (axis == AXIS_YZ)
|
||||
{
|
||||
colYZ[0] = colSelected;
|
||||
colYZ[1] = colSelected;
|
||||
linew[2] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
dc.SetColor( RGB(255,255,0),0.5f );
|
||||
//dc.DrawQuad( org,org+z*0.5f,org+z*0.5f+x*0.5f,org+x*0.5f );
|
||||
size *= PLANE_SCALE;
|
||||
Vec3 p1(size,size,0);
|
||||
Vec3 p2(size,0,size);
|
||||
Vec3 p3(0,size,size);
|
||||
|
||||
float colAlpha = 1.0f;
|
||||
x *= PLANE_SCALE; y *= PLANE_SCALE; z *= PLANE_SCALE;
|
||||
|
||||
// XY
|
||||
if (bNeedX && bNeedY)
|
||||
{
|
||||
dc.SetLineWidth( linew[0] );
|
||||
dc.SetColor( colXY[0],colAlpha );
|
||||
dc.DrawLine( p1,p1-x );
|
||||
dc.SetColor( colXY[1],colAlpha );
|
||||
dc.DrawLine( p1,p1-y );
|
||||
}
|
||||
|
||||
// XZ
|
||||
if (bNeedX && bNeedZ)
|
||||
{
|
||||
dc.SetLineWidth( linew[1] );
|
||||
dc.SetColor( colXZ[0],colAlpha );
|
||||
dc.DrawLine( p2,p2-x );
|
||||
dc.SetColor( colXZ[1],colAlpha );
|
||||
dc.DrawLine( p2,p2-z );
|
||||
}
|
||||
|
||||
// YZ
|
||||
if (bNeedY && bNeedZ)
|
||||
{
|
||||
dc.SetLineWidth( linew[2] );
|
||||
dc.SetColor( colYZ[0],colAlpha );
|
||||
dc.DrawLine( p3,p3-y );
|
||||
dc.SetColor( colYZ[1],colAlpha );
|
||||
dc.DrawLine( p3,p3-z );
|
||||
}
|
||||
|
||||
dc.SetLineWidth(1);
|
||||
|
||||
colAlpha = 0.25f;
|
||||
|
||||
if (axis == AXIS_XY && bNeedX && bNeedY)
|
||||
{
|
||||
dc.renderer->SetCullMode( R_CULL_DISABLE );
|
||||
dc.SetColor( colSelected,colAlpha );
|
||||
dc.DrawQuad( p1,p1-x,p1-x-y,p1-y );
|
||||
dc.renderer->SetCullMode();
|
||||
}
|
||||
else if (axis == AXIS_XZ && bNeedX && bNeedZ)
|
||||
{
|
||||
dc.renderer->SetCullMode( R_CULL_DISABLE );
|
||||
dc.SetColor( colSelected,colAlpha );
|
||||
dc.DrawQuad( p2,p2-x,p2-x-z,p2-z );
|
||||
dc.renderer->SetCullMode();
|
||||
}
|
||||
else if (axis == AXIS_YZ && bNeedY && bNeedZ)
|
||||
{
|
||||
dc.renderer->SetCullMode( R_CULL_DISABLE );
|
||||
dc.SetColor( colSelected,colAlpha );
|
||||
dc.DrawQuad( p3,p3-y,p3-y-z,p3-z );
|
||||
dc.renderer->SetCullMode();
|
||||
}
|
||||
|
||||
if (!(dc.flags & DISPLAY_2D))
|
||||
dc.SetState( prevRState );
|
||||
|
||||
dc.PopMatrix();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CAxisGizmo::HitTest( HitContext &hc )
|
||||
{
|
||||
if (hc.distanceTollerance != 0)
|
||||
return 0;
|
||||
|
||||
Vec3 org = m_object->GetWorldPos();
|
||||
|
||||
float fScreenScale = hc.view->GetScreenScaleFactor(org);
|
||||
float size = gSettings.gizmo.axisGizmoSize * fScreenScale;
|
||||
|
||||
Vec3 x(size,0,0);
|
||||
Vec3 y(0,size,0);
|
||||
Vec3 z(0,0,size);
|
||||
|
||||
float hitDist = 0.01f * fScreenScale;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Calculate ray in local space of axis.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
Matrix44 tm;
|
||||
RefCoordSys refCoordSys = GetIEditor()->GetReferenceCoordSys();
|
||||
if (refCoordSys == COORDS_LOCAL)
|
||||
{
|
||||
tm = m_object->GetWorldTM();
|
||||
tm.NoScale();
|
||||
}
|
||||
else
|
||||
{
|
||||
tm.SetIdentity();
|
||||
//if (hc.view->IS2.flags & DISPLAY_2D)
|
||||
{
|
||||
tm = hc.view->GetViewTM();
|
||||
}
|
||||
tm.SetTranslationOLD( m_object->GetWorldPos() );
|
||||
}
|
||||
|
||||
Vec3 pos = tm.GetTranslationOLD();
|
||||
|
||||
Vec3 intPoint;
|
||||
Ray ray(hc.raySrc,hc.rayDir);
|
||||
Sphere sphere( pos,size );
|
||||
if (!Intersect::Ray_SphereFirst( ray,sphere,intPoint ))
|
||||
{
|
||||
m_highlightAxis = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
x = tm.TransformVectorOLD(x);
|
||||
y = tm.TransformVectorOLD(y);
|
||||
z = tm.TransformVectorOLD(z);
|
||||
|
||||
size *= PLANE_SCALE;
|
||||
Vec3 p1(size,size,0);
|
||||
Vec3 p2(size,0,size);
|
||||
Vec3 p3(0,size,size);
|
||||
|
||||
p1 = tm.TransformPointOLD(p1);
|
||||
p2 = tm.TransformPointOLD(p2);
|
||||
p3 = tm.TransformPointOLD(p3);
|
||||
|
||||
Vec3 planeX = x*PLANE_SCALE;
|
||||
Vec3 planeY = y*PLANE_SCALE;
|
||||
Vec3 planeZ = z*PLANE_SCALE;
|
||||
|
||||
int hitRadius = HIT_RADIUS;
|
||||
int axis = 0;
|
||||
if (hc.view->HitTestLine( pos,pos+x,hc.point2d,hitRadius ))
|
||||
axis = AXIS_X;
|
||||
else if (hc.view->HitTestLine( pos,pos+y,hc.point2d,hitRadius ))
|
||||
axis = AXIS_Y;
|
||||
else if (hc.view->HitTestLine( pos,pos+z,hc.point2d,hitRadius ))
|
||||
axis = AXIS_Z;
|
||||
else if (hc.view->HitTestLine( p1,p1-planeX,hc.point2d,hitRadius ))
|
||||
axis = AXIS_XY;
|
||||
else if (hc.view->HitTestLine( p1,p1-planeY,hc.point2d,hitRadius ))
|
||||
axis = AXIS_XY;
|
||||
else if (hc.view->HitTestLine( p2,p2-planeX,hc.point2d,hitRadius ))
|
||||
axis = AXIS_XZ;
|
||||
else if (hc.view->HitTestLine( p2,p2-planeZ,hc.point2d,hitRadius ))
|
||||
axis = AXIS_XZ;
|
||||
else if (hc.view->HitTestLine( p3,p3-planeY,hc.point2d,hitRadius ))
|
||||
axis = AXIS_YZ;
|
||||
else if (hc.view->HitTestLine( p3,p3-planeZ,hc.point2d,hitRadius ))
|
||||
axis = AXIS_YZ;
|
||||
|
||||
if (axis != 0)
|
||||
{
|
||||
hc.axis = axis;
|
||||
hc.object = m_object;
|
||||
hc.dist = 0;
|
||||
}
|
||||
|
||||
m_highlightAxis = axis;
|
||||
|
||||
return axis != 0;
|
||||
}
|
||||
45
Editor/Objects/AxisGizmo.h
Normal file
45
Editor/Objects/AxisGizmo.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef __axisgizmo_h__
|
||||
#define __axisgizmo_h__
|
||||
#pragma once
|
||||
|
||||
#include "BaseObject.h"
|
||||
#include "Gizmo.h"
|
||||
|
||||
// forward declarations.
|
||||
struct DisplayContext;
|
||||
|
||||
/** Gizmo of Objects animation track.
|
||||
*/
|
||||
class CAxisGizmo : public CGizmo
|
||||
{
|
||||
public:
|
||||
CAxisGizmo( CBaseObject *object );
|
||||
~CAxisGizmo();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CGizmo
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void GetWorldBounds( BBox &bbox );
|
||||
virtual void Display( DisplayContext &dc );
|
||||
virtual bool HitTest( HitContext &hc );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DrawAxis( DisplayContext &dc );
|
||||
|
||||
static GetGlobalAxisGizmoCount() { return m_axisGizmoCount; }
|
||||
|
||||
private:
|
||||
void OnObjectEvent( CBaseObject *object,int event );
|
||||
|
||||
CBaseObjectPtr m_object;
|
||||
BBox m_bbox;
|
||||
|
||||
int m_highlightAxis;
|
||||
|
||||
static int m_axisGizmoCount;
|
||||
};
|
||||
|
||||
// Define CGizmoPtr smart pointer.
|
||||
SMARTPTR_TYPEDEF(CAxisGizmo);
|
||||
|
||||
#endif
|
||||
1924
Editor/Objects/BaseObject.cpp
Normal file
1924
Editor/Objects/BaseObject.cpp
Normal file
File diff suppressed because it is too large
Load Diff
606
Editor/Objects/BaseObject.h
Normal file
606
Editor/Objects/BaseObject.h
Normal file
@@ -0,0 +1,606 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: BaseObject.h
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: Definition of basic Editor object.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __BaseObject_h__
|
||||
#define __BaseObject_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "IObjectManager.h"
|
||||
#include "ClassDesc.h"
|
||||
#include "DisplayContext.h"
|
||||
#include "ObjectLoader.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// forward declarations.
|
||||
class CGroup;
|
||||
class CUndoBaseObject;
|
||||
class CObjectManager;
|
||||
class CObjectLayer;
|
||||
class CGizmo;
|
||||
class CObjectArchive;
|
||||
class CMaterial;
|
||||
|
||||
//! Collision structure passed to HitTest function.
|
||||
struct HitContext
|
||||
{
|
||||
CViewport *view; //!< Viewport that originates hit testing.
|
||||
bool b2DViewport; //!< Testing performed in 2D viewport.
|
||||
CPoint point2d; //!< 2D point on view that was use to shoot the ray.
|
||||
CRect rect; //!< 2d Selection rectangle (Only when HitTestRect)
|
||||
|
||||
// Input parameters.
|
||||
Vec3 raySrc; //!< Ray origin.
|
||||
Vec3 rayDir; //!< Ray direction.
|
||||
float distanceTollerance; //!< Relaxation parameter for hit testing.
|
||||
bool weakHit; //!< True if this hit should have less priority then non weak hits.
|
||||
// //!< (exp: Ray hit entity bounding box but not entity geometry.)
|
||||
int axis; //! Collision axis.
|
||||
|
||||
// Output parameters.
|
||||
//! Distance to the object from src.
|
||||
float dist;
|
||||
//! Actual object that been hit.
|
||||
CBaseObject* object;
|
||||
|
||||
//Ctor
|
||||
HitContext()
|
||||
{
|
||||
rect.top = 0;
|
||||
rect.left = 0;
|
||||
rect.bottom = 0;
|
||||
rect.right = 0;
|
||||
b2DViewport = false;
|
||||
view = 0;
|
||||
point2d.x = 0; point2d.y = 0;
|
||||
axis = 0;
|
||||
distanceTollerance = 0;
|
||||
raySrc(0,0,0);
|
||||
rayDir(0,0,0);
|
||||
dist = 0;
|
||||
object = 0;
|
||||
weakHit = false;
|
||||
// geometryHit = false;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
This class used for object references remapping dusring cloning operation.
|
||||
*/
|
||||
class CObjectCloneContext
|
||||
{
|
||||
public:
|
||||
//! Add cloned object.
|
||||
SANDBOX_API void AddClone( CBaseObject *pFromObject,CBaseObject *pToObject );
|
||||
|
||||
//! Find cloned object for givven object.
|
||||
SANDBOX_API CBaseObject* FindClone( CBaseObject *pFromObject );
|
||||
|
||||
private:
|
||||
typedef std::map<CBaseObject*,CBaseObject*> ObjectsMap;
|
||||
ObjectsMap m_objectsMap;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
enum ObjectFlags
|
||||
{
|
||||
OBJFLAG_SELECTED = 0x0001, //!< Object is selected. (Do not set this flag explicitly).
|
||||
OBJFLAG_HIDDEN = 0x0002, //!< Object is hidden.
|
||||
OBJFLAG_FROZEN = 0x0004, //!< Object is frozen (Visible but cannot be selected)
|
||||
OBJFLAG_FLATTEN = 0x0008, //!< Flatten area arround object.
|
||||
OBJFLAG_SHARED = 0x0010, //!< This object is shared between missions.
|
||||
|
||||
OBJFLAG_PREFAB = 0x0020, //!< This object is part of prefab object.
|
||||
|
||||
// object is in editing mode.
|
||||
OBJFLAG_EDITING = 0x01000,
|
||||
OBJFLAG_ATTACHING = 0x02000, //!< Object in attaching to group mode.
|
||||
OBJFLAG_DELETED = 0x04000, //!< This object is deleted.
|
||||
OBJFLAG_HIGHLIGHT = 0x08000, //!< Object is highlighted (When mouse over).
|
||||
OBJFLAG_VISIBLE = 0x10000, //!< This object is visible.
|
||||
|
||||
OBJFLAG_PERSISTMASK = OBJFLAG_HIDDEN|OBJFLAG_FROZEN|OBJFLAG_FLATTEN,
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! This flags passed to CBaseObject::BeginEditParams method.
|
||||
enum ObjectEditFlags
|
||||
{
|
||||
OBJECT_CREATE = 0x001,
|
||||
OBJECT_EDIT = 0x002,
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Return values from CBaseObject::MouseCreateCallback method.
|
||||
enum MouseCreateResult
|
||||
{
|
||||
MOUSECREATE_CONTINUE = 0, //!< Continue placing this object.
|
||||
MOUSECREATE_ABORT, //!< Abort creation of this object.
|
||||
MOUSECREATE_OK, //!< Accept this object.
|
||||
};
|
||||
|
||||
/*!
|
||||
* CBaseObject is the base class for all objects which can be placed in map.
|
||||
* Every object belongs to class specified by ClassDesc.
|
||||
* Specific object classes must ovveride this class, to provide specific functionality.
|
||||
* Objects are reference counted and only destroyed when last reference to object
|
||||
* is destroyed.
|
||||
*
|
||||
*/
|
||||
class CBaseObject : public CVarObject
|
||||
{
|
||||
DECLARE_DYNAMIC(CBaseObject);
|
||||
public:
|
||||
//! Events sent by object to listeners in EventCallback.
|
||||
enum EObjectListenerEvent
|
||||
{
|
||||
ON_DELETE = 0,//!< Sent after object was deleted from object manager.
|
||||
ON_SELECT, //!< Sent when objects becomes selected.
|
||||
ON_UNSELECT, //!< Sent when objects unselected.
|
||||
ON_TRANSFORM, //!< Sent when object transformed.
|
||||
ON_VISIBILITY, //!< Sent when object visibility changes.
|
||||
};
|
||||
|
||||
//! This callback will be called if object is deleted.
|
||||
typedef Functor2<CBaseObject*,int> EventCallback;
|
||||
|
||||
//! Childs structure.
|
||||
typedef std::vector<TSmartPtr<CBaseObject> > Childs;
|
||||
|
||||
//! Retrieve class description of this object.
|
||||
CObjectClassDesc* GetClassDesc() const { return m_classDesc; };
|
||||
|
||||
/** Check if both object are of same class.
|
||||
*/
|
||||
virtual bool IsSameClass( CBaseObject *obj );
|
||||
|
||||
ObjectType GetType() const { return m_classDesc->GetObjectType(); };
|
||||
const char* GetTypeName() const { return m_classDesc->ClassName(); };
|
||||
virtual CString GetTypeDescription() const { return m_classDesc->ClassName(); };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Layer support.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SetLayer( CObjectLayer *layer );
|
||||
CObjectLayer* GetLayer() const { return m_layer; };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Flags.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SetFlags( int flags ) { m_flags |= flags; };
|
||||
void ClearFlags( int flags ) { m_flags &= ~flags; };
|
||||
bool CheckFlags( int flags ) const { return (m_flags&flags) != 0; };
|
||||
|
||||
//! Returns true if object hidden.
|
||||
bool IsHidden() const;
|
||||
//! Returns true if object frozen.
|
||||
bool IsFrozen() const;
|
||||
//! Returns true if object is selected.
|
||||
bool IsSelected() const { return CheckFlags(OBJFLAG_SELECTED); }
|
||||
//! Returns true if object is shared between missions.
|
||||
bool IsShared() const { return CheckFlags(OBJFLAG_SHARED); }
|
||||
|
||||
// Check if object potentially can be selected.
|
||||
bool IsSelectable() const;
|
||||
|
||||
//! Set shared between missions flag.
|
||||
virtual void SetShared( bool bShared );
|
||||
//! Set object hidden status.
|
||||
virtual void SetHidden( bool bHidden );
|
||||
//! Set object frozen status.
|
||||
virtual void SetFrozen( bool bFrozen );
|
||||
//! Set object selected status.
|
||||
virtual void SetSelected( bool bSelect );
|
||||
|
||||
//! Set object highlighted (Note: not selected)
|
||||
void SetHighlight( bool bHighlight );
|
||||
//! Check if object is highlighted.
|
||||
bool IsHighlighted() const { return CheckFlags(OBJFLAG_HIGHLIGHT); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Object Id.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Get uniq object id.
|
||||
//! Every object will have it own uniq id assigned.
|
||||
REFGUID GetId() const { return m_guid; };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Name.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Get name of object.
|
||||
const CString& GetName() const;
|
||||
|
||||
//! Change name of object.
|
||||
virtual void SetName( const CString &name );
|
||||
//! Set object name and make sure it is uniq.
|
||||
void SetUniqName( const CString &name );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Geometry.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Set object position.
|
||||
virtual void SetPos( const Vec3d &pos );
|
||||
//! Set object rotation angles.
|
||||
virtual void SetAngles( const Vec3d &angles );
|
||||
//! Set object scale.
|
||||
virtual void SetScale( const Vec3d &scale );
|
||||
|
||||
//! Get object position.
|
||||
Vec3d GetPos() const { return m_pos; }
|
||||
//! Get object rotation angles.
|
||||
Vec3d GetAngles() const { return m_angles; }
|
||||
//! Get object scale.
|
||||
Vec3d GetScale() const { return m_scale; }
|
||||
|
||||
//! Set flatten area.
|
||||
void SetArea( float area );
|
||||
float GetArea() const { return m_flattenArea; };
|
||||
|
||||
//! Assign display color to the object.
|
||||
virtual void SetColor( COLORREF color );
|
||||
//! Get object color.
|
||||
COLORREF GetColor() const { return m_color; };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CHILDS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Return true if node have childs.
|
||||
bool HaveChilds() const { return !m_childs.empty(); };
|
||||
//! Return true if have attached childs.
|
||||
int GetChildCount() const { return m_childs.size(); };
|
||||
|
||||
//! Get child by index.
|
||||
CBaseObject* GetChild( int i ) const;
|
||||
//! Return parent node if exist.
|
||||
CBaseObject* GetParent() const { return m_parent; };
|
||||
//! Scans hiearachy up to determine if we child of specified node.
|
||||
virtual bool IsChildOf( CBaseObject* node );
|
||||
|
||||
//! Attach new child node.
|
||||
//! @param bKeepPos if true Child node will keep its world space position.
|
||||
virtual void AttachChild( CBaseObject* child,bool bKeepPos=true );
|
||||
//! Detach all childs of this node.
|
||||
virtual void DetachAll( bool bKeepPos=true );
|
||||
// Detach this node from parent.
|
||||
virtual void DetachThis( bool bKeepPos=true );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MATRIX
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Get objects's local transformation marix.
|
||||
const Matrix44& GetLocalTM() const;
|
||||
|
||||
//! Get objects's world-space transformation matrix.
|
||||
const Matrix44& GetWorldTM() const;
|
||||
|
||||
//! Get position in world space.
|
||||
Vec3 GetWorldPos() const { return GetWorldTM().GetTranslationOLD(); };
|
||||
Vec3 GetWorldAngles() const;
|
||||
|
||||
//! Set xform of object givven in world space.
|
||||
void SetWorldTM( const Matrix44 &tm );
|
||||
|
||||
//! Set object xform.
|
||||
void SetLocalTM( const Matrix44 &tm );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Interface to be implemented in plugins.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Called when object is being created.
|
||||
virtual int MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags );
|
||||
|
||||
//! Draw object to specified viewport.
|
||||
virtual void Display( DisplayContext &disp ) = 0;
|
||||
|
||||
//! Perform intersection testing of this object.
|
||||
//! Return true if was hit.
|
||||
virtual bool HitTest( HitContext &hc ) { return false; };
|
||||
|
||||
//! Perform intersection testing of this object with rectangle.
|
||||
//! Return true if was hit.
|
||||
virtual bool HitTestRect( HitContext &hc );
|
||||
|
||||
//! Called when user starts editing object parameters.
|
||||
//! Flags is comnination of ObjectEditFlags flags.
|
||||
//! Prev is a previous created base object.
|
||||
virtual void BeginEditParams( IEditor *ie,int flags );
|
||||
//! Called when user ends editing object parameters.
|
||||
virtual void EndEditParams( IEditor *ie );
|
||||
|
||||
//! Called when user starts editing of multiple selected objects.
|
||||
//! @param bAllOfSameType true if all objects in selection are of same type.
|
||||
virtual void BeginEditMultiSelParams( bool bAllOfSameType );
|
||||
//! Called when user ends editing of multiple selected objects.
|
||||
virtual void EndEditMultiSelParams();
|
||||
|
||||
//! Get bounding box of object in world coordinate space.
|
||||
virtual void GetBoundBox( BBox &box );
|
||||
|
||||
//! Get bounding box of object in local object space.
|
||||
virtual void GetLocalBounds( BBox &box );
|
||||
|
||||
//! Called after some parameter been modified.
|
||||
virtual void SetModified();
|
||||
|
||||
//! Called when UI of objects is updated.
|
||||
virtual void OnUIUpdate();
|
||||
|
||||
//! Called when visibility of this object changes.
|
||||
//! Derived classs may ovverride this to respond to new visibility setting.
|
||||
virtual void UpdateVisibility( bool visible );
|
||||
|
||||
//! Serialize object to/from xml.
|
||||
//! @param xmlNode XML node to load/save serialized data to.
|
||||
//! @param bLoading true if loading data from xml.
|
||||
//! @param bUndo true if loading or saving data for Undo/Redo purposes.
|
||||
virtual void Serialize( CObjectArchive &ar );
|
||||
|
||||
//! Export object to xml.
|
||||
//! Return created object node in xml.
|
||||
virtual XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
|
||||
//! Handle events recieved by object.
|
||||
//! Override in derived classes, to handle specific events.
|
||||
virtual void OnEvent( ObjectEvent event );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Group support.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Set group this object belong to.
|
||||
void SetGroup( CGroup *group ) { m_group = group; };
|
||||
//! Get group this object belnog to.
|
||||
CGroup* GetGroup() const { return m_group; };
|
||||
//! Check to see if this object part of any group.
|
||||
bool IsInGroup() const { return m_group != NULL; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// LookAt Target.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetLookAt( CBaseObject *target );
|
||||
CBaseObject* GetLookAt() const { return m_lookat; };
|
||||
//! Returns true if this object is a look-at target.
|
||||
bool IsLookAtTarget() const;
|
||||
|
||||
//! Perform hit testing of Axis.
|
||||
//! @return 0 if no axis hit, return 1-X Axis, 2=Y Axis, 3=Z Axis.
|
||||
virtual int HitTestAxis( HitContext &hc );
|
||||
|
||||
//! Get Animation node assigned to this object.
|
||||
virtual struct IAnimNode* GetAnimNode() const { return 0; };
|
||||
|
||||
//! Gets physics collision entity of this object.
|
||||
virtual class IPhysicalEntity* GetCollisionEntity() const { return 0; };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Return IEditor interface.
|
||||
IEditor* GetIEditor() const { return m_ie; }
|
||||
|
||||
IObjectManager* GetObjectManager() const { return m_objectManager; };
|
||||
|
||||
//! Store undo information for this object.
|
||||
void StoreUndo( const char *UndoDescription,bool minimal=false );
|
||||
|
||||
//! Add event listener callback.
|
||||
void AddEventListener( const EventCallback &cb );
|
||||
//! Remove event listener callback.
|
||||
void RemoveEventListener( const EventCallback &cb );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Material handlaing for this base object.
|
||||
//! Override in derived classes.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Assign new material to this object.
|
||||
virtual void SetMaterial( CMaterial *mtl ) {};
|
||||
//! Get assigned material for this object.
|
||||
virtual CMaterial* GetMaterial() const { return 0; };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Analyze errors for this object.
|
||||
virtual void Validate( CErrorReport *report );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Gather resources of this object.
|
||||
virtual void GatherUsedResources( CUsedResources &resources );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Check if specified object is very similar to this one.
|
||||
virtual bool IsSimilarObject( CBaseObject *pObject );
|
||||
|
||||
protected:
|
||||
friend CObjectManager;
|
||||
friend CObjectLayer;
|
||||
|
||||
//! Ctor is protected to restrict direct usage.
|
||||
CBaseObject();
|
||||
//! Dtor is protected to restrict direct usage.
|
||||
virtual ~CBaseObject();
|
||||
|
||||
//! Initialize Object.
|
||||
//! If previous object specified it must be of exactly same class as this object.
|
||||
//! All data is copied from previous object.
|
||||
//! Optional file parameter specify initial object or script for this object.
|
||||
virtual bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Must be called after cloning the object on clone of object.
|
||||
//! This will make sure object references are cloned correctly.
|
||||
virtual void PostClone( CBaseObject *pFromObject,CObjectCloneContext &ctx );
|
||||
|
||||
//! Must be implemented by derived class to create game related objects.
|
||||
virtual bool CreateGameObject() { return true; };
|
||||
|
||||
/** Called when object is about to be deleted.
|
||||
All Game resources should be freed in this function.
|
||||
*/
|
||||
virtual void Done();
|
||||
|
||||
/** Change current id of object.
|
||||
*/
|
||||
//virtual void SetId( uint objectId ) { m_id = objectId; };
|
||||
|
||||
//! Call this to delete an object.
|
||||
virtual void DeleteThis() = 0;
|
||||
|
||||
//! Called when object need to be converted from different object.
|
||||
virtual bool ConvertFromObject( CBaseObject *object );
|
||||
|
||||
//! Invalidates cached transformation matrix.
|
||||
virtual void InvalidateTM();
|
||||
|
||||
//! Called when local transformation matrix is caluclated.
|
||||
void CalcLocalTM( Matrix44 &tm ) const;
|
||||
|
||||
//! Update editable object UI params.
|
||||
void UpdateEditParams();
|
||||
|
||||
//! Called when child position changed.
|
||||
virtual void OnChildModified() {};
|
||||
|
||||
//! Called when GUID of object is changed for any reason.
|
||||
virtual void OnChangeGUID( REFGUID newGUID );
|
||||
|
||||
//! Remove child from our childs list.
|
||||
virtual void RemoveChild( CBaseObject *node );
|
||||
|
||||
//! Resolve parent from callback.
|
||||
void ResolveParent( CBaseObject *object );
|
||||
|
||||
//! Draw default object items.
|
||||
void DrawDefault( DisplayContext &dc,COLORREF labelColor=RGB(255,255,255) );
|
||||
//! Draw object label.
|
||||
void DrawLabel( DisplayContext &dc,const Vec3 &pos,COLORREF labelColor=RGB(255,255,255) );
|
||||
//! Draw 3D Axis at object position.
|
||||
void DrawAxis( DisplayContext &dc,const Vec3 &pos,float size );
|
||||
//! Draw area arround object.
|
||||
void DrawArea( DisplayContext &dc );
|
||||
|
||||
//! Draw highlight.
|
||||
virtual void DrawHighlight( DisplayContext &dc );
|
||||
|
||||
CBaseObject* FindObject( REFGUID id ) const;
|
||||
|
||||
// Returns true if game objects should be created.
|
||||
bool IsCreateGameObjects() const;
|
||||
|
||||
// Helper gizmo funcitons.
|
||||
void AddGizmo( CGizmo *gizmo );
|
||||
void RemoveGizmo( CGizmo *gizmo );
|
||||
|
||||
//! Notify all listeners about event.
|
||||
void NotifyListeners( EObjectListenerEvent event );
|
||||
|
||||
//! Only used by ObjectManager.
|
||||
bool IsPotentiallyVisible() const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// May be overrided in derived classes to handle helpers scaling.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetHelperScale( float scale ) {};
|
||||
virtual float GetHelperScale() { return 1; };
|
||||
|
||||
private:
|
||||
friend class CUndoBaseObject;
|
||||
friend class CPropertiesPanel;
|
||||
friend class CObjectArchive;
|
||||
friend class CSelectionGroup;
|
||||
|
||||
//! Modify object properties, from modified property template.
|
||||
//! @templ Template to take parameters from.
|
||||
//! @modifiedNode XML Node that was modified in properties.
|
||||
void ModifyProperties( XmlNodeRef &templ,const XmlNodeRef &modifiedNode );
|
||||
|
||||
//! Set class description for this object,
|
||||
//! Only called once after creation by ObjectManager.
|
||||
void SetClassDesc( CObjectClassDesc *classDesc );
|
||||
|
||||
//! Set pointer to main editor Interface.
|
||||
//! Only called once after creation by ObjectManager.
|
||||
void SetIEditor( IEditor *ie ) { m_ie = ie; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PRIVATE FIELDS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
private:
|
||||
//! ID Assigned to this object.
|
||||
//uint m_id;
|
||||
//! Unique object Id.
|
||||
GUID m_guid;
|
||||
|
||||
//! Layer this object is assigned to.
|
||||
CObjectLayer *m_layer;
|
||||
|
||||
//! Flags of this object.
|
||||
int m_flags;
|
||||
|
||||
//! World space object's position.
|
||||
Vec3d m_pos;
|
||||
//! Object's Rotation angles.
|
||||
Vec3d m_angles;
|
||||
//! Object's scale value.
|
||||
Vec3d m_scale;
|
||||
|
||||
//! Display color.
|
||||
COLORREF m_color;
|
||||
|
||||
//! World transformation matrix of this object.
|
||||
mutable Matrix44 m_worldTM;
|
||||
mutable bool m_bMatrixInWorldSpace;
|
||||
mutable bool m_bMatrixValid;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Look At target entity.
|
||||
TSmartPtr<CBaseObject> m_lookat;
|
||||
//! If we are lookat target. this is pointer to source.
|
||||
CBaseObject* m_lookatSource;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Area radius arround object, where terrain is flatten and static objects removed.
|
||||
float m_flattenArea;
|
||||
//! Every object keeps for itself height above terrain.
|
||||
float m_height;
|
||||
//! Object's name.
|
||||
CString m_name;
|
||||
//! Class description for this object.
|
||||
CObjectClassDesc* m_classDesc;
|
||||
//! If object belongs to group, this will point to parent group.
|
||||
CGroup* m_group;
|
||||
//! Pointer to main editor Interface.
|
||||
IEditor* m_ie;
|
||||
//! Pointer to object manager.
|
||||
IObjectManager *m_objectManager;
|
||||
//! Number of reference to this object.
|
||||
//! When reference count reach zero, object will delete itself.
|
||||
int m_numRefs;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Child animation nodes.
|
||||
Childs m_childs;
|
||||
//! Pointer to parent node.
|
||||
mutable CBaseObject *m_parent;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Listeners.
|
||||
std::list<EventCallback> m_eventListeners;
|
||||
std::list<EventCallback>::iterator m_nextListener;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
typedef TSmartPtr<CBaseObject> CBaseObjectPtr;
|
||||
|
||||
#endif // __BaseObject_h__
|
||||
1009
Editor/Objects/BrushObject.cpp
Normal file
1009
Editor/Objects/BrushObject.cpp
Normal file
File diff suppressed because it is too large
Load Diff
197
Editor/Objects/BrushObject.h
Normal file
197
Editor/Objects/BrushObject.h
Normal file
@@ -0,0 +1,197 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: brushobject.h
|
||||
// Version: v1.00
|
||||
// Created: 8/7/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __brushobject_h__
|
||||
#define __brushobject_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "BaseObject.h"
|
||||
#include "..\Brush\Brush.h"
|
||||
|
||||
struct SBrush;
|
||||
class CEdMesh;
|
||||
|
||||
/*!
|
||||
* CTagPoint is an object that represent named 3d position in world.
|
||||
*
|
||||
*/
|
||||
class CBrushObject : public CBaseObject
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CBrushObject)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
void Display( DisplayContext &dc );
|
||||
bool CreateGameObject();
|
||||
|
||||
void GetBoundBox( BBox &box );
|
||||
void GetLocalBounds( BBox &box );
|
||||
|
||||
bool HitTest( HitContext &hc );
|
||||
int HitTestAxis( HitContext &hc );
|
||||
|
||||
virtual void SetScale( const Vec3d &scale );
|
||||
virtual void SetSelected( bool bSelect );
|
||||
virtual IPhysicalEntity* GetCollisionEntity() const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
void BeginEditMultiSelParams( bool bAllOfSameType );
|
||||
void EndEditMultiSelParams();
|
||||
|
||||
//! Called when object is being created.
|
||||
int MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags );
|
||||
|
||||
void Serialize( CObjectArchive &ar );
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
|
||||
virtual void Validate( CErrorReport *report );
|
||||
virtual bool IsSimilarObject( CBaseObject *pObject );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Assign brush to object.
|
||||
void SetBrush( SBrush *brush );
|
||||
//! Retrieve brush assigned to object.
|
||||
SBrush* GetBrush();
|
||||
|
||||
void SelectBrushSide( const Vec3 &raySrc,const Vec3 &rayDir,bool shear );
|
||||
void MoveSelectedPoints( const Vec3 &worldOffset );
|
||||
void ResetToPrefabSize();
|
||||
void ReloadPrefabGeometry();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Used by brush exporter.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IStatObj* GetPrefabGeom() const;
|
||||
Matrix44 GetBrushMatrix() const;
|
||||
int GetRenderFlags() const { return m_renderFlags; };
|
||||
IEntityRender* GetEngineNode() const { return m_engineNode; };
|
||||
float GetRatioLod() const { return mv_ratioLOD; };
|
||||
float GetRatioViewDist() const { return mv_ratioViewDist; };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Material
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SetMaterial( CMaterial *mtl );
|
||||
CMaterial* GetMaterial() const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool IsRecieveLightmap() const { return mv_recvLightmap; };
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CBrushObject();
|
||||
|
||||
virtual void UpdateVisibility( bool visible );
|
||||
|
||||
//! Convert ray givven in world coordinates to the ray in local brush coordinates.
|
||||
void WorldToLocalRay( Vec3 &raySrc,Vec3 &rayDir );
|
||||
|
||||
bool ConvertFromObject( CBaseObject *object );
|
||||
void DeleteThis() { delete this; };
|
||||
void InvalidateTM();
|
||||
|
||||
void CreateBrushFromPrefab( const char *meshFilname );
|
||||
void UpdateEngineNode( bool bOnlyTransform=false );
|
||||
|
||||
void OnFileChange( CString filename );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Local callbacks.
|
||||
void OnPrefabChange( IVariable *var );
|
||||
void OnRenderVarChange( IVariable *var );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BBox m_bbox;
|
||||
Matrix44 m_invertTM;
|
||||
|
||||
//! Actual brush.
|
||||
TSmartPtr<SBrush> m_brush;
|
||||
|
||||
// Selected points of this brush.
|
||||
SBrushSubSelection m_subSelection;
|
||||
//std::vector<Vec3*> m_selectedPoints;
|
||||
|
||||
//! Engine node.
|
||||
//! Node that registered in engine and used to render brush prefab
|
||||
IEntityRender* m_engineNode;
|
||||
|
||||
TSmartPtr<CEdMesh> m_prefabGeom;
|
||||
CBrushIndoor *m_indoor;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Brush parameters.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CVariable<CString> mv_prefabName;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Brush rendering parameters.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CVariable<bool> mv_outdoor;
|
||||
CVariable<bool> mv_castShadows;
|
||||
CVariable<bool> mv_selfShadowing;
|
||||
CVariable<bool> mv_castShadowMaps;
|
||||
CVariable<bool> mv_castLightmap;
|
||||
CVariable<bool> mv_recvLightmap;
|
||||
CVariable<bool> mv_recvShadowMaps;
|
||||
CVariable<bool> mv_hideable;
|
||||
CVariable<int> mv_ratioLOD;
|
||||
CVariable<int> mv_ratioViewDist;
|
||||
CVariable<bool> mv_excludeFromTriangulation;
|
||||
CVariable<float> mv_lightmapQuality;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Rendering flags.
|
||||
int m_renderFlags;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Material assigned to this brush.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
TSmartPtr<CMaterial> m_pMaterial;
|
||||
GUID m_materialGUID;
|
||||
|
||||
bool m_bIgnoreNodeUpdate;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of CBrushObject.
|
||||
*/
|
||||
class CBrushObjectClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {032B8809-71DB-44d7-AAA1-69F75C999463}
|
||||
static const GUID guid = { 0x32b8809, 0x71db, 0x44d7, { 0xaa, 0xa1, 0x69, 0xf7, 0x5c, 0x99, 0x94, 0x63 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_BRUSH; };
|
||||
const char* ClassName() { return "Brush"; };
|
||||
const char* Category() { return "Brush"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CBrushObject); };
|
||||
const char* GetFileSpec() { return "Objects\\*.cgf"; };
|
||||
int GameCreationOrder() { return 150; };
|
||||
};
|
||||
|
||||
#endif // __brushobject_h__
|
||||
642
Editor/Objects/Building.cpp
Normal file
642
Editor/Objects/Building.cpp
Normal file
@@ -0,0 +1,642 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: Building.cpp
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: StaticObject implementation.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "Building.h"
|
||||
#include "Entity.h"
|
||||
|
||||
#include "..\BuildingPanel.h"
|
||||
#include "..\Viewport.h"
|
||||
|
||||
#include <I3DEngine.h>
|
||||
#include "IPhysics.h"
|
||||
#include <I3DIndoorEngine.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CBase implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CBuilding,CGroup)
|
||||
|
||||
int CBuilding::m_rollupId;
|
||||
CBuildingPanel* CBuilding::m_panel = 0;
|
||||
|
||||
bool CBuilding::m_portals = true;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CBuilding::CBuilding()
|
||||
{
|
||||
// Initial area size.
|
||||
m_bbox.min=Vec3d(-1,-1,-1);
|
||||
m_bbox.max=Vec3d(1,1,1);
|
||||
|
||||
m_buildingId = -1;
|
||||
m_bAlwaysDrawBox = false;
|
||||
m_wireFrame = false;
|
||||
|
||||
// Building is initially open.
|
||||
Open();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::Done()
|
||||
{
|
||||
if (ValidBuildingId(m_buildingId))
|
||||
{
|
||||
// Delete indoor building.
|
||||
GetBuildMgr()->DeleteBuilding( m_buildingId );
|
||||
m_buildingId = 0;
|
||||
}
|
||||
UnbindAllHelpers();
|
||||
m_helpers.clear();
|
||||
|
||||
CGroup::Done();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::ReleaseBuilding()
|
||||
{
|
||||
if (ValidBuildingId(m_buildingId))
|
||||
{
|
||||
// Delete indoor building.
|
||||
GetBuildMgr()->DeleteBuilding( m_buildingId );
|
||||
}
|
||||
m_buildingId = -1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CBuilding::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
m_ie = ie;
|
||||
|
||||
SetColor( RGB(255,255,255) );
|
||||
|
||||
CGroup::Init( ie,prev,file );
|
||||
if (prev)
|
||||
{
|
||||
LoadBuilding( ((CBuilding*)prev)->GetObjectName() );
|
||||
}
|
||||
else if (!file.IsEmpty())
|
||||
{
|
||||
LoadBuilding( file );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::SetPos( const Vec3d &pos )
|
||||
{
|
||||
CGroup::SetPos(pos);
|
||||
if (ValidBuildingId(m_buildingId))
|
||||
{
|
||||
// Move indoor building.
|
||||
GetBuildMgr()->SetBuildingPos( GetWorldPos(),m_buildingId );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::SetAngles( const Vec3d &angles )
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::SetScale( const Vec3d &scale )
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
void CBuilding::BeginEditParams( IEditor *ie,int flags )
|
||||
{
|
||||
m_ie = ie;
|
||||
CGroup::BeginEditParams( ie,flags );
|
||||
|
||||
if (!m_panel)
|
||||
{
|
||||
m_panel = new CBuildingPanel(0);
|
||||
m_panel->Create( CBuildingPanel::IDD,AfxGetMainWnd() );
|
||||
m_rollupId = ie->AddRollUpPage( ROLLUP_OBJECTS,"Building Parameters",m_panel );
|
||||
}
|
||||
|
||||
m_panel->SetBuilding( this );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::EndEditParams( IEditor *ie )
|
||||
{
|
||||
if (m_rollupId != 0)
|
||||
ie->RemoveRollUpPage( ROLLUP_OBJECTS,m_rollupId );
|
||||
m_rollupId = 0;
|
||||
m_panel = 0;
|
||||
|
||||
CGroup::EndEditParams( ie );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::GetBoundBox( BBox &box )
|
||||
{
|
||||
CGroup::GetBoundBox( box );
|
||||
/*
|
||||
box = m_box;
|
||||
box.min += GetPos();
|
||||
box.max += GetPos();
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CBuilding::HitTest( HitContext &hc )
|
||||
{
|
||||
bool bHit = CGroup::HitTestChilds( hc );
|
||||
if (bHit)
|
||||
return true;
|
||||
|
||||
Vec3 p;
|
||||
|
||||
float tr = hc.distanceTollerance/2;
|
||||
BBox box;
|
||||
box.min = GetWorldPos() + m_bbox.min - Vec3(tr,tr,tr);
|
||||
box.max = GetWorldPos() + m_bbox.max + Vec3(tr,tr,tr);
|
||||
if (box.IsIntersectRay(hc.raySrc,hc.rayDir,p ))
|
||||
{
|
||||
//hc.dist = Vec3(hc.raySrc - p).Length();
|
||||
|
||||
if (ValidBuildingId(m_buildingId))
|
||||
{
|
||||
//! If camera source is inside building dont select it.
|
||||
if (GetBuildMgr()->CheckInside( hc.raySrc,m_buildingId))
|
||||
return false;
|
||||
|
||||
//Vec3d src = hc.raySrc;
|
||||
//Vec3d trg = hc.raySrc + hc.rayDir*10000.0f;
|
||||
// IndoorRayIntInfo hit;
|
||||
//ASSERT(0);
|
||||
//return (false);
|
||||
//please use the physics code for ray-inters.
|
||||
//if (!GetBuildMgr()->RayIntersection( src,trg,hit,m_buildingId ))
|
||||
// return false;
|
||||
|
||||
vectorf vPos(hc.raySrc);
|
||||
vectorf vDir(hc.rayDir);
|
||||
int objTypes = ent_static;
|
||||
int flags = rwi_stop_at_pierceable|rwi_ignore_terrain_holes;
|
||||
ray_hit hit;
|
||||
int col = GetIEditor()->GetSystem()->GetIPhysicalWorld()->RayWorldIntersection( vPos,vDir,objTypes,flags,&hit,1 );
|
||||
if (col > 0)
|
||||
{
|
||||
IStatObj *pStatObj = (IStatObj*)hit.pCollider->GetForeignData();
|
||||
if (GetBuildMgr()->GetBuildingIdFromObj( pStatObj ) == m_buildingId)
|
||||
{
|
||||
hc.dist = hit.dist;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//hc.geometryHit = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::Display( DisplayContext &dc )
|
||||
{
|
||||
CGroup::Display( dc );
|
||||
|
||||
/*
|
||||
// Create buildling if not done already.
|
||||
DrawDefault(dc,GetColor());
|
||||
|
||||
if (IsSelected())
|
||||
{
|
||||
float t = m_ie->GetSystem()->GetITimer()->GetCurrTime();
|
||||
float r1 = (float)fabs(sin(t*8.0f));
|
||||
// float r2 = cos(t*3);
|
||||
dc.renderer->SetMaterialColor( 1,0,r1,0.5f );
|
||||
//dc.renderer->DrawBall( GetPos(),1.3f );
|
||||
|
||||
dc.renderer->PushMatrix();
|
||||
dc.renderer->TranslateMatrix( GetPos() );
|
||||
dc.renderer->RotateMatrix( GetAngles() );
|
||||
dc.renderer->Draw3dBBox( m_bbox.min,m_bbox.max );
|
||||
dc.renderer->PopMatrix();
|
||||
}
|
||||
*/
|
||||
|
||||
Vec3 origin = GetWorldPos();
|
||||
// Display helpers.
|
||||
dc.SetColor( 0,1,1,0.3f );
|
||||
for (int i = 0; i < m_helpers.size(); i++)
|
||||
{
|
||||
if (m_helpers[i].object == 0)
|
||||
{
|
||||
dc.renderer->DrawBall( origin+m_helpers[i].pos,0.3f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::OnEvent( ObjectEvent event )
|
||||
{
|
||||
CGroup::OnEvent(event);
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case EVENT_INGAME:
|
||||
GetBuildMgr()->EnableVisibility( true );
|
||||
break;
|
||||
|
||||
case EVENT_OUTOFGAME:
|
||||
GetBuildMgr()->EnableVisibility( m_portals );
|
||||
break;
|
||||
|
||||
case EVENT_RELOAD_GEOM:
|
||||
LoadBuilding( m_objectName,true );
|
||||
break;
|
||||
|
||||
case EVENT_UNLOAD_GEOM:
|
||||
ReleaseBuilding();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::Serialize( CObjectArchive &ar )
|
||||
{
|
||||
CGroup::Serialize( ar );
|
||||
XmlNodeRef xmlNode = ar.node;
|
||||
if (ar.bLoading)
|
||||
{
|
||||
bool wireFrame = false;
|
||||
xmlNode->getAttr( "Wireframe",wireFrame );
|
||||
//xmlNode->getAttr( "Portals",portals );
|
||||
SetWireframe( wireFrame );
|
||||
|
||||
for (int i = 0; i < xmlNode->getChildCount(); i++)
|
||||
{
|
||||
XmlNodeRef cgf = xmlNode->getChild(i);
|
||||
CString name;
|
||||
if (cgf->isTag("Cgf") && cgf->getAttr("Name",name))
|
||||
{
|
||||
LoadBuilding( name );
|
||||
// Only one object.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Load information about objects attached to helpers.
|
||||
SerializeHelpers( ar );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Saving.
|
||||
xmlNode->setAttr( "Wireframe",m_wireFrame );
|
||||
//xmlNode->setAttr( "Portals",m_portals );
|
||||
// Only one object.
|
||||
XmlNodeRef cgf = xmlNode->newChild("Cgf");
|
||||
cgf->setAttr( "Name",m_objectName );
|
||||
|
||||
// Serialize helpers that have attached objects.
|
||||
SerializeHelpers( ar );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::SerializeHelpers( CObjectArchive &ar )
|
||||
{
|
||||
XmlNodeRef xmlNode = ar.node;
|
||||
if (ar.bLoading)
|
||||
{
|
||||
// Load information about objects attached to helpers.
|
||||
XmlNodeRef helpersNode = xmlNode->findChild( "Helperes" );
|
||||
if (helpersNode)
|
||||
{
|
||||
for (int i = 0; i < helpersNode->getChildCount(); i++)
|
||||
{
|
||||
XmlNodeRef helperNode = helpersNode->getChild(i);
|
||||
CString helperName;
|
||||
GUID objectId = GUID_NULL;
|
||||
helperNode->getAttr( "Id",objectId );
|
||||
helperNode->getAttr( "Name",helperName );
|
||||
for (int j = 0; j < m_helpers.size(); j++)
|
||||
{
|
||||
if (stricmp(m_helpers[j].name,helperName)==0)
|
||||
{
|
||||
ar.SetResolveCallback( objectId,functor(*this,ResolveHelper),j );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
XmlNodeRef helpersNode = xmlNode->newChild( "Helperes" );
|
||||
|
||||
// Serialize helpers that have attached objects.
|
||||
for (int i = 0; i < m_helpers.size(); i++)
|
||||
{
|
||||
ObjectHelper &helper = m_helpers[i];
|
||||
if (helper.object != 0)
|
||||
{
|
||||
XmlNodeRef helperNode = helpersNode->newChild( "Helper" );
|
||||
helperNode->setAttr( "Id",helper.object->GetId() );
|
||||
helperNode->setAttr( "Name",helper.name );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::ResolveHelper( CBaseObject *object,uint helperIndex )
|
||||
{
|
||||
if (helperIndex >= 0 && helperIndex < m_helpers.size())
|
||||
{
|
||||
BindToHelper( helperIndex,object );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
XmlNodeRef CBuilding::Export( const CString &levelPath,XmlNodeRef &xmlNode )
|
||||
{
|
||||
XmlNodeRef node = CGroup::Export( levelPath,xmlNode );
|
||||
node->setTag( "Building" );
|
||||
node->setAttr( "Geometry",m_objectName );
|
||||
/*
|
||||
//for (int i = 0; i < m_objectNames.size(); i++)
|
||||
{
|
||||
XmlNodeRef cgf = node->newChild("Cgf");
|
||||
cgf->setAttr( "Name",m_objectName );
|
||||
}
|
||||
*/
|
||||
return node;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::LoadBuilding( const CString &object,bool bForceReload )
|
||||
{
|
||||
if (stricmp(object,m_objectName)==0 && ValidBuildingId(m_buildingId) && !bForceReload)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_objectName = object;
|
||||
|
||||
if (!IsCreateGameObjects())
|
||||
return;
|
||||
|
||||
ReleaseBuilding();
|
||||
m_sectorHidden.clear();
|
||||
|
||||
if (m_objectName.IsEmpty())
|
||||
return;
|
||||
|
||||
IndoorBaseInterface IndInterface;
|
||||
ISystem *pISystem = GetIEditor()->GetSystem();
|
||||
IndInterface.m_pSystem = pISystem;
|
||||
IndInterface.m_p3dEngine = pISystem->GetI3DEngine(); //(I3DEngine *)pISystem->GetIProcess();
|
||||
IndInterface.m_pLog = pISystem->GetILog();
|
||||
IndInterface.m_pRenderer = pISystem->GetIRenderer();
|
||||
IndInterface.m_pConsole = pISystem->GetIConsole();
|
||||
|
||||
IIndoorBase *buildManager = GetBuildMgr();
|
||||
|
||||
if (ValidBuildingId(m_buildingId))
|
||||
buildManager->DeleteBuilding( m_buildingId );
|
||||
|
||||
m_buildingId = buildManager->CreateBuilding( IndInterface );
|
||||
if (!ValidBuildingId(m_buildingId))
|
||||
return;
|
||||
|
||||
int numSectors = buildManager->AddBuilding( m_objectName,m_buildingId );
|
||||
|
||||
buildManager->SetBuildingPos( GetWorldPos(),m_buildingId );
|
||||
|
||||
m_sectorHidden.resize(numSectors);
|
||||
|
||||
// Save info about objects to helpers attachment.
|
||||
XmlNodeRef helpers = new CXmlNode( "Helpers" );
|
||||
CObjectArchive saveAr( GetObjectManager(),helpers,false );
|
||||
SerializeHelpers( saveAr );
|
||||
UnbindAllHelpers();
|
||||
m_helpers.clear();
|
||||
|
||||
const char *helperName = 0;
|
||||
int i = 0;
|
||||
do {
|
||||
Vec3 pos;
|
||||
Matrix HelperMat;
|
||||
helperName = buildManager->GetHelper( i,m_buildingId,pos,&HelperMat );
|
||||
if (helperName)
|
||||
{
|
||||
ObjectHelper eh;
|
||||
eh.object = 0;
|
||||
eh.pos = pos;
|
||||
// eh.angles = rot.GetEulerAngles();
|
||||
|
||||
assert(0); // not tested !!!
|
||||
AffineParts affineParts;
|
||||
affineParts.SpectralDecompose(HelperMat);
|
||||
eh.angles = RAD2DEG(Ang3::GetAnglesXYZ(Matrix33(affineParts.rot)));
|
||||
|
||||
eh.name = CString(helperName).SpanExcluding( "/" );
|
||||
if (strchr(helperName,'/') != 0)
|
||||
{
|
||||
eh.className = CString(helperName).Mid( eh.name.GetLength()+1 );
|
||||
}
|
||||
m_helpers.push_back(eh);
|
||||
}
|
||||
i++;
|
||||
} while (helperName != NULL);
|
||||
|
||||
// Load info about objects to helpers attachment.
|
||||
CObjectArchive loadAr( GetObjectManager(),helpers,true );
|
||||
SerializeHelpers( loadAr );
|
||||
|
||||
GetBuildMgr()->EnableVisibility( m_portals );
|
||||
|
||||
CalcBoundBox();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::CalcBoundBox()
|
||||
{
|
||||
// Bounding box of building is an intersection of all objects bounding boxes
|
||||
m_bbox.Reset();
|
||||
|
||||
if (ValidBuildingId(m_buildingId))
|
||||
{
|
||||
GetBuildMgr()->GetBBox( m_bbox.min,m_bbox.max,m_buildingId );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bbox.min=Vec3d(-1,-1,-1);
|
||||
m_bbox.max=Vec3d(1,1,1);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::SpawnEntities()
|
||||
{
|
||||
CEntityClassDesc entClassDesc;
|
||||
|
||||
// Spawn entities using Class Name given in helper.
|
||||
for (int i = 0; i < m_helpers.size(); i++)
|
||||
{
|
||||
ObjectHelper &eh = m_helpers[i];
|
||||
if (eh.object == 0)
|
||||
{
|
||||
//
|
||||
CEntity *entity = (CEntity*)GetIEditor()->NewObject( entClassDesc.ClassName(),eh.className );
|
||||
if (!entity)
|
||||
{
|
||||
CLogFile::FormatLine( "Building: Entity Spawn failed, Unknown class: %s",(const char*)eh.className );
|
||||
continue;
|
||||
}
|
||||
entity->SetPos( GetWorldPos()+eh.pos );
|
||||
entity->SetAngles( eh.angles );
|
||||
eh.object = entity;
|
||||
AttachChild( entity );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::HideSector( int index,bool bHide )
|
||||
{
|
||||
if (ValidBuildingId(m_buildingId))
|
||||
{
|
||||
if (index >= 0 && index < GetNumSectors())
|
||||
{
|
||||
m_sectorHidden[index] = bHide;
|
||||
GetBuildMgr()->HideSector( bHide,m_buildingId,index );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CBuilding::IsSectorHidden( int index ) const
|
||||
{
|
||||
if (index >= 0 && index < GetNumSectors())
|
||||
return m_sectorHidden[index];
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::SetWireframe( bool bEnable )
|
||||
{
|
||||
StoreUndo( "Set Wireframe" );
|
||||
m_wireFrame = bEnable;
|
||||
|
||||
GetBuildMgr()->EnableWireframe( bEnable );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CBuilding::IsWireframe() const
|
||||
{
|
||||
return m_wireFrame;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::BindToHelper( int helperIndex,CBaseObject *obj )
|
||||
{
|
||||
assert( helperIndex >= 0 && helperIndex < m_helpers.size() );
|
||||
|
||||
if (obj->IsChildOf(this) || obj == m_helpers[helperIndex].object)
|
||||
return;
|
||||
|
||||
StoreUndo( "Bind Helper" );
|
||||
|
||||
obj->AddEventListener( functor(*this,OnHelperEvent) );
|
||||
m_helpers[helperIndex].object = obj;
|
||||
obj->SetPos( GetWorldPos() + m_helpers[helperIndex].pos );
|
||||
//obj->SetAngles( m_helpers[helperIndex].angles );
|
||||
|
||||
AttachChild( obj );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::UnbindHelper( int helperIndex )
|
||||
{
|
||||
assert( helperIndex >= 0 && helperIndex < m_helpers.size() );
|
||||
|
||||
if (m_helpers[helperIndex].object)
|
||||
{
|
||||
StoreUndo( "Unbind Helper" );
|
||||
|
||||
m_helpers[helperIndex].object->RemoveEventListener( functor(*this,&CBuilding::OnHelperEvent) );
|
||||
|
||||
RemoveChild( m_helpers[helperIndex].object );
|
||||
m_helpers[helperIndex].object = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::UnbindAllHelpers()
|
||||
{
|
||||
for (int i = 0; i < m_helpers.size(); i++)
|
||||
{
|
||||
if (m_helpers[i].object)
|
||||
{
|
||||
UnbindHelper(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::OnHelperEvent( CBaseObject *object,int event )
|
||||
{
|
||||
if (event == CBaseObject::ON_DELETE)
|
||||
{
|
||||
// Find helper to unbind.
|
||||
for (int i = 0; i < m_helpers.size(); i++)
|
||||
{
|
||||
if (m_helpers[i].object == object)
|
||||
{
|
||||
UnbindHelper(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IIndoorBase* CBuilding::GetBuildMgr()
|
||||
{
|
||||
return GetIEditor()->Get3DEngine()->GetBuildingManager();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::UpdateVisibility( bool visible )
|
||||
{
|
||||
CGroup::UpdateVisibility(visible);
|
||||
if (ValidBuildingId(m_buildingId))
|
||||
GetBuildMgr()->HideBuilding( !visible,m_buildingId );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::InvalidateTM()
|
||||
{
|
||||
CGroup::InvalidateTM();
|
||||
// Move window to new world position.
|
||||
if (ValidBuildingId(m_buildingId))
|
||||
{
|
||||
// Move indoor building.
|
||||
GetBuildMgr()->SetBuildingPos( GetWorldPos(),m_buildingId );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBuilding::SetPortals( bool enable )
|
||||
{
|
||||
m_portals = enable;
|
||||
if (ValidBuildingId(m_buildingId))
|
||||
GetBuildMgr()->EnableVisibility(enable);
|
||||
}
|
||||
163
Editor/Objects/Building.h
Normal file
163
Editor/Objects/Building.h
Normal file
@@ -0,0 +1,163 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: Building.h
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: StaticObject object definition.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __Building_h__
|
||||
#define __Building_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "Group.h"
|
||||
|
||||
/*!
|
||||
* CBuilding is an building on the terrain.
|
||||
*
|
||||
*/
|
||||
class CBuilding : public CGroup
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CBuilding)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
void Display( DisplayContext &disp );
|
||||
|
||||
void SetPos( const Vec3d &pos );
|
||||
void SetAngles( const Vec3d &angles );
|
||||
void SetScale( const Vec3d &scale );
|
||||
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
|
||||
void GetBoundBox( BBox &box );
|
||||
bool HitTest( HitContext &hc );
|
||||
void UpdateVisibility( bool visible );
|
||||
void InvalidateTM();
|
||||
|
||||
void OnEvent( ObjectEvent event );
|
||||
void Serialize( CObjectArchive &ar );
|
||||
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Building interface.
|
||||
|
||||
//! Load Building file and make indoor building representation.
|
||||
void LoadBuilding( const CString &object,bool bForceReload=false );
|
||||
//! Release Indoor building in engine.
|
||||
void ReleaseBuilding();
|
||||
|
||||
//! Get object name by index.
|
||||
const CString& GetObjectName() const { return m_objectName; }
|
||||
int GetBuildingId() { return m_buildingId; };
|
||||
|
||||
//! Return true if building in Indoor Engine is correctly initialized.
|
||||
//! And building id reference valid id.
|
||||
bool ValidBuildingId( int id ) { return id >= 0; };
|
||||
|
||||
//! Returns number of sectors in the building.
|
||||
int GetNumSectors() const { return m_sectorHidden.size(); };
|
||||
//! Hides or shows specified sector.
|
||||
void HideSector( int index,bool bHide );
|
||||
// Returns true if specified sector is hidden.
|
||||
bool IsSectorHidden( int index ) const;
|
||||
|
||||
//! Set wireframe rending mode.
|
||||
void SetWireframe( bool bEnable );
|
||||
//! Check if rendered in wireframe.
|
||||
bool IsWireframe() const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Building Helpers.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! This structure is a single instance of helper in building.
|
||||
struct ObjectHelper
|
||||
{
|
||||
CString name;
|
||||
CString className;
|
||||
Vec3 pos;
|
||||
Vec3 angles;
|
||||
CBaseObject *object;
|
||||
ObjectHelper() { object = 0; };
|
||||
};
|
||||
std::vector<ObjectHelper>& GetHelpers() { return m_helpers; };
|
||||
void SpawnEntities();
|
||||
|
||||
void BindToHelper( int helperIndex,CBaseObject *obj );
|
||||
void UnbindHelper( int helperIndex );
|
||||
void UnbindAllHelpers();
|
||||
|
||||
void SetPortals( bool enable );
|
||||
bool IsPortals() const { return m_portals; };
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CBuilding();
|
||||
|
||||
void SerializeHelpers( CObjectArchive &ar );
|
||||
void ResolveHelper( CBaseObject *object,uint helperIndex );
|
||||
void OnHelperEvent( CBaseObject *object,int event );
|
||||
|
||||
struct IIndoorBase* GetBuildMgr();
|
||||
|
||||
// Ovverides from CBaseObject.
|
||||
void DeleteThis() { delete this; };
|
||||
|
||||
//! Calculate bounding box of building.
|
||||
virtual void CalcBoundBox();
|
||||
|
||||
IEditor* m_ie;
|
||||
CString m_objectName;
|
||||
|
||||
int m_buildingId;
|
||||
int m_numSectors;
|
||||
|
||||
//! When true building displayed in wireframe.
|
||||
bool m_wireFrame;
|
||||
//! When true building rendered with portals.
|
||||
static bool m_portals;
|
||||
|
||||
std::vector<ObjectHelper> m_helpers;
|
||||
std::vector<bool> m_sectorHidden;
|
||||
|
||||
static int m_rollupId;
|
||||
static class CBuildingPanel* m_panel;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of Building
|
||||
*/
|
||||
class CBuildingClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {5237F903-CF62-48de-979A-20C4E989D22D}
|
||||
static const GUID guid = { 0x5237f903, 0xcf62, 0x48de, { 0x97, 0x9a, 0x20, 0xc4, 0xe9, 0x89, 0xd2, 0x2d } };
|
||||
return guid;
|
||||
}
|
||||
void Release() { delete this; }
|
||||
ObjectType GetObjectType() { return OBJTYPE_BUILDING; };
|
||||
const char* ClassName() { return "StdBuilding"; };
|
||||
const char* Category() { return ""; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CBuilding); };
|
||||
const char* GetFileSpec() { return "Objects\\Buildings\\*.bld"; };
|
||||
};
|
||||
|
||||
#endif // __Building_h__
|
||||
527
Editor/Objects/CameraObject.cpp
Normal file
527
Editor/Objects/CameraObject.cpp
Normal file
@@ -0,0 +1,527 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: TagPoint.cpp
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: CCameraObject implementation.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "CameraObject.h"
|
||||
#include "ObjectManager.h"
|
||||
#include "..\Viewport.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CBase implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CCameraObject,CEntity)
|
||||
IMPLEMENT_DYNCREATE(CCameraObjectTarget,CEntity)
|
||||
|
||||
#define CAMERA_COLOR RGB(0,255,255)
|
||||
#define CAMERA_CONE_LENGTH 4
|
||||
#define CAMERABOX_RADIUS 0.7f
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CCameraObject::CCameraObject()
|
||||
{
|
||||
mv_fov = DEG2RAD(60.0f);
|
||||
m_creationStep = 0;
|
||||
SetColor(CAMERA_COLOR);
|
||||
|
||||
AddVariable( mv_fov,"FOV",functor(*this,&CCameraObject::OnFovChange),IVariable::DT_ANGLE );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCameraObject::Done()
|
||||
{
|
||||
CBaseObjectPtr lookat = GetLookAt();
|
||||
|
||||
CEntity::Done();
|
||||
|
||||
if (lookat)
|
||||
{
|
||||
// If look at is also camera class, delete lookat target.
|
||||
if (lookat->IsKindOf(RUNTIME_CLASS(CCameraObjectTarget)))
|
||||
GetObjectManager()->DeleteObject( lookat );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CCameraObject::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
bool res = CEntity::Init( ie,prev,file );
|
||||
|
||||
m_entityClass = "CameraSource";
|
||||
|
||||
if (prev)
|
||||
{
|
||||
CBaseObjectPtr prevLookat = prev->GetLookAt();
|
||||
if (prevLookat)
|
||||
{
|
||||
CBaseObjectPtr lookat = GetObjectManager()->NewObject( prevLookat->GetClassDesc(),prevLookat );
|
||||
if (lookat)
|
||||
{
|
||||
lookat->SetPos( prevLookat->GetPos() + Vec3(3,0,0) );
|
||||
GetObjectManager()->ChangeObjectName( lookat,CString(GetName()) + " Target" );
|
||||
SetLookAt( lookat );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void CCameraObject::Serialize( CObjectArchive &ar )
|
||||
{
|
||||
CEntity::Serialize( ar );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IAnimNode* CCameraObject::CreateAnimNode()
|
||||
{
|
||||
int nodeId = GetId().Data1;
|
||||
IAnimNode *animNode = GetIEditor()->GetMovieSystem()->CreateNode( ANODE_CAMERA,nodeId );
|
||||
//IAnimNode *animNode = CEntity::CreateAnimNode();
|
||||
if (animNode)
|
||||
{
|
||||
float fov = mv_fov;
|
||||
animNode->SetParamValue( 0,APARAM_FOV,RAD2DEG(fov) );
|
||||
}
|
||||
return animNode;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCameraObject::OnNodeAnimated()
|
||||
{
|
||||
assert( m_animNode != 0 ); // Only can be called if there`s an anim node present.
|
||||
|
||||
CEntity::OnNodeAnimated();
|
||||
// Get fov out of node at current time.
|
||||
float fov = RAD2DEG(mv_fov);
|
||||
if (m_animNode->GetParamValue( GetIEditor()->GetAnimation()->GetTime(),APARAM_FOV,fov ))
|
||||
{
|
||||
mv_fov = DEG2RAD(fov);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCameraObject::SetName( const CString &name )
|
||||
{
|
||||
CEntity::SetName(name);
|
||||
if (GetLookAt())
|
||||
{
|
||||
GetLookAt()->SetName( CString(GetName()) + " Target" );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCameraObject::SetScale( const Vec3d &scale )
|
||||
{
|
||||
// Ignore scale.
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCameraObject::BeginEditParams( IEditor *ie,int flags )
|
||||
{
|
||||
// Skip entity begin edit params.
|
||||
CBaseObject::BeginEditParams( ie,flags );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCameraObject::EndEditParams( IEditor *ie )
|
||||
{
|
||||
// Skip entity end edit params.
|
||||
CBaseObject::EndEditParams( ie );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CCameraObject::MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags )
|
||||
{
|
||||
if (event == eMouseMove || event == eMouseLDown || event == eMouseLUp)
|
||||
{
|
||||
Vec3 pos;
|
||||
if (GetIEditor()->GetAxisConstrains() != AXIS_TERRAIN)
|
||||
{
|
||||
pos = view->MapViewToCP(point);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Snap to terrain.
|
||||
bool hitTerrain;
|
||||
pos = view->ViewToWorld( point,&hitTerrain );
|
||||
if (hitTerrain)
|
||||
{
|
||||
pos.z = GetIEditor()->GetTerrainElevation(pos.x,pos.y) + 1.0f;
|
||||
}
|
||||
pos = view->SnapToGrid(pos);
|
||||
}
|
||||
|
||||
if (m_creationStep == 1)
|
||||
{
|
||||
if (GetLookAt())
|
||||
{
|
||||
GetLookAt()->SetPos( pos );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPos(pos);
|
||||
}
|
||||
|
||||
if (event == eMouseLDown && m_creationStep == 0)
|
||||
{
|
||||
m_creationStep = 1;
|
||||
}
|
||||
if (event == eMouseMove && 1 == m_creationStep && !GetLookAt())
|
||||
{
|
||||
float d = GetDistance(pos,GetPos());
|
||||
if (d*view->GetScreenScaleFactor(pos) > 1)
|
||||
{
|
||||
// Create LookAt Target.
|
||||
GetIEditor()->ResumeUndo();
|
||||
CreateTarget();
|
||||
GetIEditor()->SuspendUndo();
|
||||
}
|
||||
}
|
||||
if (eMouseLUp == event && 1 == m_creationStep)
|
||||
return MOUSECREATE_OK;
|
||||
|
||||
return MOUSECREATE_CONTINUE;
|
||||
}
|
||||
return CBaseObject::MouseCreateCallback( view,event,point,flags );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCameraObject::CreateTarget()
|
||||
{
|
||||
// Create another camera object for target.
|
||||
CCameraObject *camTarget = (CCameraObject*)GetObjectManager()->NewObject( "CameraTarget" );
|
||||
if (camTarget)
|
||||
{
|
||||
camTarget->SetName( CString(GetName()) + " Target" );
|
||||
camTarget->SetPos( GetWorldPos() + Vec3(3,0,0) );
|
||||
SetLookAt( camTarget );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCameraObject::Display( DisplayContext &dc )
|
||||
{
|
||||
const Matrix44 &wtm = GetWorldTM();
|
||||
Vec3 wp = wtm.GetTranslationOLD();
|
||||
|
||||
float fScale = dc.view->GetScreenScaleFactor(wp) * 0.03f;
|
||||
|
||||
if (GetLookAt())
|
||||
{
|
||||
// Look at camera.
|
||||
if (IsFrozen())
|
||||
dc.SetFreezeColor();
|
||||
else
|
||||
dc.SetColor( GetColor() );
|
||||
|
||||
bool bSelected = IsSelected();
|
||||
|
||||
if (bSelected || GetLookAt()->IsSelected())
|
||||
{
|
||||
dc.SetSelectedColor();
|
||||
}
|
||||
|
||||
// Line from source to target.
|
||||
dc.DrawLine( wp,GetLookAt()->GetWorldPos() );
|
||||
|
||||
if (bSelected)
|
||||
{
|
||||
dc.SetSelectedColor();
|
||||
}
|
||||
else if (IsFrozen())
|
||||
dc.SetFreezeColor();
|
||||
else
|
||||
dc.SetColor( GetColor() );
|
||||
|
||||
dc.PushMatrix( wtm );
|
||||
|
||||
Vec3 sz(0.2f*fScale,0.1f*fScale,0.2f*fScale);
|
||||
dc.DrawWireBox( -sz,sz );
|
||||
|
||||
float dist = 1.0f;
|
||||
if (bSelected)
|
||||
{
|
||||
dist = GetDistance(GetLookAt()->GetWorldPos(),wtm.GetTranslationOLD());
|
||||
DrawCone( dc,dist );
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawCone( dc,dist,fScale );
|
||||
}
|
||||
dc.PopMatrix();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Free camera
|
||||
if (IsSelected())
|
||||
dc.SetSelectedColor();
|
||||
else if (IsFrozen())
|
||||
dc.SetFreezeColor();
|
||||
else
|
||||
dc.SetColor( GetColor() );
|
||||
|
||||
dc.PushMatrix( wtm );
|
||||
|
||||
Vec3 sz(0.2f*fScale,0.1f*fScale,0.2f*fScale);
|
||||
dc.DrawWireBox( -sz,sz );
|
||||
|
||||
float dist = CAMERA_CONE_LENGTH;
|
||||
DrawCone( dc,dist,fScale );
|
||||
dc.PopMatrix();
|
||||
}
|
||||
|
||||
//dc.DrawIcon( ICON_QUAD,wp,0.1f*dc.view->GetScreenScaleFactor(wp) );
|
||||
|
||||
DrawDefault( dc );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CCameraObject::HitTest( HitContext &hc )
|
||||
{
|
||||
Vec3 origin = GetWorldPos();
|
||||
float radius = CAMERABOX_RADIUS/2.0f;
|
||||
|
||||
float fScale = hc.view->GetScreenScaleFactor(origin) * 0.03f;
|
||||
|
||||
Vec3 w = origin - hc.raySrc;
|
||||
w = hc.rayDir.Cross( w );
|
||||
float d = w.Length();
|
||||
|
||||
if (d < radius*fScale + hc.distanceTollerance)
|
||||
{
|
||||
hc.dist = GetDistance(hc.raySrc,origin);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CCameraObject::HitTestRect( HitContext &hc )
|
||||
{
|
||||
// transform all 8 vertices into world space
|
||||
CPoint p = hc.view->WorldToView( GetWorldPos() );
|
||||
if (hc.rect.PtInRect(p))
|
||||
{
|
||||
hc.object = this;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCameraObject::GetBoundBox( BBox &box )
|
||||
{
|
||||
Vec3 pos = GetWorldPos();
|
||||
float r;
|
||||
r = 1;
|
||||
box.min = pos - Vec3(r,r,r);
|
||||
box.max = pos + Vec3(r,r,r);
|
||||
if (GetLookAt())
|
||||
{
|
||||
box.Add( GetLookAt()->GetWorldPos() );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCameraObject::GetLocalBounds( BBox &box )
|
||||
{
|
||||
GetBoundBox( box );
|
||||
Matrix44 invTM( GetWorldTM() );
|
||||
invTM.Invert44();
|
||||
box.Transform( invTM );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
float CCameraObject::GetFOV() const
|
||||
{
|
||||
return mv_fov;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
float CCameraObject::GetAspect() const
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCameraObject::GetConePoints( Vec3 q[4],float dist )
|
||||
{
|
||||
if (dist > 1e8f)
|
||||
dist = 1e8f;
|
||||
float ta = (float)tan(0.5f*GetFOV());
|
||||
float w = dist * ta;
|
||||
// float h = w * (float).75; // ASPECT ??
|
||||
float h = w / GetAspect();
|
||||
|
||||
//q[0] = Vec3( w, h,-dist);
|
||||
//q[1] = Vec3(-w, h,-dist);
|
||||
//q[2] = Vec3(-w,-h,-dist);
|
||||
//q[3] = Vec3( w,-h,-dist);
|
||||
|
||||
q[0] = Vec3( w,-dist, h);
|
||||
q[1] = Vec3(-w,-dist, h);
|
||||
q[2] = Vec3(-w,-dist,-h);
|
||||
q[3] = Vec3( w,-dist,-h);
|
||||
}
|
||||
|
||||
void CCameraObject::DrawCone( DisplayContext &dc,float dist,float fScale )
|
||||
{
|
||||
Vec3 q[4];
|
||||
GetConePoints(q,dist);
|
||||
|
||||
q[0] *= fScale;
|
||||
q[1] *= fScale;
|
||||
q[2] *= fScale;
|
||||
q[3] *= fScale;
|
||||
|
||||
Vec3 org(0,0,0);
|
||||
dc.DrawLine( org,q[0] );
|
||||
dc.DrawLine( org,q[1] );
|
||||
dc.DrawLine( org,q[2] );
|
||||
dc.DrawLine( org,q[3] );
|
||||
|
||||
// Draw quad.
|
||||
dc.DrawPolyLine( q,4 );
|
||||
|
||||
// Draw cross.
|
||||
//dc.DrawLine( q[0],q[2] );
|
||||
//dc.DrawLine( q[1],q[3] );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
void CCameraObject::DrawCone( DisplayContext &dc )
|
||||
{
|
||||
float dist = 10;
|
||||
|
||||
Vec3 q[5], u[3];
|
||||
GetConePoints(q,dist);
|
||||
|
||||
if (colid) gw->setColor( LINE_COLOR, GetUIColor(colid));
|
||||
if (drawDiags) {
|
||||
u[0] = q[0]; u[1] = q[2];
|
||||
gw->polyline( 2, u, NULL, NULL, FALSE, NULL );
|
||||
u[0] = q[1]; u[1] = q[3];
|
||||
gw->polyline( 2, u, NULL, NULL, FALSE, NULL );
|
||||
}
|
||||
gw->polyline( 4, q, NULL, NULL, TRUE, NULL );
|
||||
if (drawSides) {
|
||||
gw->setColor( LINE_COLOR, GetUIColor(COLOR_CAMERA_CONE));
|
||||
u[0] = Point3(0,0,0);
|
||||
for (int i=0; i<4; i++) {
|
||||
u[1] = q[i];
|
||||
gw->polyline( 2, u, NULL, NULL, FALSE, NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCameraObject::OnFovChange( IVariable *var )
|
||||
{
|
||||
if (m_animNode)
|
||||
{
|
||||
float fov = mv_fov;
|
||||
m_animNode->SetParamValue( GetIEditor()->GetAnimation()->GetTime(),APARAM_FOV, RAD2DEG(fov) );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCameraObject::OnPropertyChange( const CString &property )
|
||||
{
|
||||
CEntity::OnPropertyChange( property );
|
||||
|
||||
float fov = m_fov;
|
||||
GetParams()->getAttr( "FOV",fov );
|
||||
m_fov = fov;
|
||||
if (m_animNode)
|
||||
m_animNode->SetParam( GetIEditor()->GetAnimation()->GetTime(),APARAM_FOV, fov );
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CCameraObjectTarget implementation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CCameraObjectTarget::CCameraObjectTarget()
|
||||
{
|
||||
SetColor(CAMERA_COLOR);
|
||||
}
|
||||
|
||||
bool CCameraObjectTarget::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
SetColor( CAMERA_COLOR );
|
||||
bool res = CEntity::Init( ie,prev,file );
|
||||
m_entityClass = "CameraTargetPoint";
|
||||
return res;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCameraObjectTarget::Display( DisplayContext &dc )
|
||||
{
|
||||
Vec3 wp = GetWorldPos();
|
||||
|
||||
float fScale = dc.view->GetScreenScaleFactor(wp) * 0.03f;
|
||||
|
||||
if (IsSelected())
|
||||
dc.SetSelectedColor();
|
||||
else if (IsFrozen())
|
||||
dc.SetFreezeColor();
|
||||
else
|
||||
dc.SetColor( GetColor() );
|
||||
|
||||
Vec3 sz(0.2f*fScale,0.2f*fScale,0.2f*fScale);
|
||||
dc.DrawWireBox( wp-sz,wp+sz );
|
||||
|
||||
DrawDefault( dc );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CCameraObjectTarget::HitTest( HitContext &hc )
|
||||
{
|
||||
Vec3 origin = GetWorldPos();
|
||||
float radius = CAMERABOX_RADIUS/2.0f;
|
||||
|
||||
float fScale = hc.view->GetScreenScaleFactor(origin) * 0.03f;
|
||||
|
||||
Vec3 w = origin - hc.raySrc;
|
||||
w = hc.rayDir.Cross( w );
|
||||
float d = w.Length();
|
||||
|
||||
if (d < radius*fScale + hc.distanceTollerance)
|
||||
{
|
||||
hc.dist = GetDistance(hc.raySrc,origin);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCameraObjectTarget::GetBoundBox( BBox &box )
|
||||
{
|
||||
Vec3 pos = GetWorldPos();
|
||||
float r = CAMERABOX_RADIUS;
|
||||
box.min = pos - Vec3(r,r,r);
|
||||
box.max = pos + Vec3(r,r,r);
|
||||
}
|
||||
|
||||
void CCameraObjectTarget::Serialize( CObjectArchive &ar )
|
||||
{
|
||||
CEntity::Serialize( ar );
|
||||
}
|
||||
152
Editor/Objects/CameraObject.h
Normal file
152
Editor/Objects/CameraObject.h
Normal file
@@ -0,0 +1,152 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: cameraobject.h
|
||||
// Version: v1.00
|
||||
// Created: 29/7/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __cameraobject_h__
|
||||
#define __cameraobject_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
/*!
|
||||
* CCameraObject is an object that represent Source or Target of camera.
|
||||
*
|
||||
*/
|
||||
class CCameraObject : public CEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CCameraObject)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
CString GetTypeDescription() const { return GetTypeName(); };
|
||||
void Display( DisplayContext &disp );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetName( const CString &name );
|
||||
virtual void SetScale( const Vec3d &scale );
|
||||
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
|
||||
//! Called when object is being created.
|
||||
int MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags );
|
||||
bool HitTest( HitContext &hc );
|
||||
bool HitTestRect( HitContext &hc );
|
||||
void Serialize( CObjectArchive &ar );
|
||||
|
||||
void GetBoundBox( BBox &box );
|
||||
void GetLocalBounds( BBox &box );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Get Camera Field Of View angle.
|
||||
float GetFOV() const;
|
||||
|
||||
//! Get Camera's aspect ratio.
|
||||
float GetAspect() const;
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CCameraObject();
|
||||
IAnimNode* CreateAnimNode();
|
||||
// overrided from IAnimNodeCallback
|
||||
void OnNodeAnimated();
|
||||
|
||||
void OnFovChange( IVariable *var );
|
||||
|
||||
void GetConePoints( Vec3 q[4],float dist );
|
||||
void DrawCone( DisplayContext &dc,float dist,float fScale=1 );
|
||||
void CreateTarget();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Field of view.
|
||||
CVariable<float> mv_fov;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mouse callback.
|
||||
int m_creationStep;
|
||||
};
|
||||
|
||||
/*!
|
||||
* CCameraObjectTarget is a target object for Camera.
|
||||
*
|
||||
*/
|
||||
class CCameraObjectTarget : public CEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CCameraObjectTarget)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
CString GetTypeDescription() const { return GetTypeName(); };
|
||||
void Display( DisplayContext &disp );
|
||||
bool HitTest( HitContext &hc );
|
||||
void GetBoundBox( BBox &box );
|
||||
void SetScale( const Vec3d &scale ) {};
|
||||
void SetAngles( const Vec3d &scale ) {};
|
||||
void Serialize( CObjectArchive &ar );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CCameraObjectTarget();
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of CameraObject.
|
||||
*/
|
||||
class CCameraObjectClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {23612EE3-B568-465d-9B31-0CA32FDE2340}
|
||||
static const GUID guid = { 0x23612ee3, 0xb568, 0x465d, { 0x9b, 0x31, 0xc, 0xa3, 0x2f, 0xde, 0x23, 0x40 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_ENTITY; };
|
||||
const char* ClassName() { return "Camera"; };
|
||||
const char* Category() { return "Camera"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CCameraObject); };
|
||||
int GameCreationOrder() { return 202; };
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of CameraObjectTarget.
|
||||
*/
|
||||
class CCameraObjectTargetClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {1AC4CF4E-9614-4de8-B791-C0028D0010D2}
|
||||
static const GUID guid = { 0x1ac4cf4e, 0x9614, 0x4de8, { 0xb7, 0x91, 0xc0, 0x2, 0x8d, 0x0, 0x10, 0xd2 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_ENTITY; };
|
||||
const char* ClassName() { return "CameraTarget"; };
|
||||
const char* Category() { return ""; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CCameraObjectTarget); };
|
||||
int GameCreationOrder() { return 202; };
|
||||
};
|
||||
|
||||
#endif // __cameraobject_h__
|
||||
80
Editor/Objects/ClassDesc.h
Normal file
80
Editor/Objects/ClassDesc.h
Normal file
@@ -0,0 +1,80 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: ClassDesc.h
|
||||
// Version: v1.00
|
||||
// Created: 8/11/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: Class description of CBaseObject
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __ClassDesc_h__
|
||||
#define __ClassDesc_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "plugin.h"
|
||||
#include "ObjectEvent.h"
|
||||
|
||||
//! Standart categories.
|
||||
#define CATEGORY_STATIC "Static"
|
||||
#define CATEGORY_TAGPOINTS "TagPoint"
|
||||
#define CATEGORY_BUILDING "Building"
|
||||
#define CATEGORY_ENTITY "Entity"
|
||||
#define CATEGORY_SHAP "Shape"
|
||||
#define CATEGORY_SOUND "Sound"
|
||||
|
||||
#define OBJTYPE_ANY_DEFINED (OBJTYPE_GROUP|OBJTYPE_TAGPOINT|OBJTYPE_AIPOINT|OBJTYPE_ENTITY|OBJTYPE_SHAPE|OBJTYPE_VOLUME|OBJTYPE_BRUSH|OBJTYPE_PREFAB)
|
||||
|
||||
/*!
|
||||
* Virtual base class description of CBaseObject.
|
||||
* Ovveride this class to create specific Class descriptions for every base object class.
|
||||
* Type name is specified like this:
|
||||
* Category\Type ex: "TagPoint\Respawn"
|
||||
*/
|
||||
class CObjectClassDesc : public IClassDesc
|
||||
{
|
||||
public:
|
||||
//! Release class description.
|
||||
virtual ObjectType GetObjectType() = 0;
|
||||
|
||||
//! Create instance of editor object.
|
||||
virtual CObject* Create()
|
||||
{
|
||||
return GetRuntimeClass()->CreateObject();
|
||||
}
|
||||
|
||||
//! Get MFC runtime class for this object.
|
||||
virtual CRuntimeClass* GetRuntimeClass() = 0;
|
||||
|
||||
//! If this function return not empty string,object of this class must be created with file.
|
||||
//! Return root path where to look for files this object supports.
|
||||
//! Also wild card for files can be specified, ex: Objects\*.cgf
|
||||
virtual const char* GetFileSpec()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
virtual ESystemClassID SystemClassID() { return ESYSTEM_CLASS_OBJECT; };
|
||||
|
||||
virtual void ShowAbout() {};
|
||||
virtual bool CanExitNow() { return true; }
|
||||
virtual void Serialize( CXmlArchive &ar ) {};
|
||||
virtual void Event( EClassEvent event ) {};
|
||||
//! Ex. Object with creation order 200 will be created after any object with order 100.
|
||||
virtual int GameCreationOrder() { return 100; };
|
||||
|
||||
// IUnknown implementation.
|
||||
ULONG STDMETHODCALLTYPE AddRef() { return 0; } // Ignore.
|
||||
ULONG STDMETHODCALLTYPE Release() { delete this; return 0; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // __ClassDesc_h__
|
||||
622
Editor/Objects/DisplayContext.cpp
Normal file
622
Editor/Objects/DisplayContext.cpp
Normal file
@@ -0,0 +1,622 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: DisplayContext.cpp
|
||||
// Version: v1.00
|
||||
// Created: 4/12/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: DisplayContext
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "DisplayContext.h"
|
||||
|
||||
#include "..\IconManager.h"
|
||||
#include "..\Viewport.h"
|
||||
|
||||
#include <I3DEngine.h>
|
||||
//#include <gl\gl.h>
|
||||
|
||||
#define FREEZE_COLOR RGB(100,100,100)
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
DisplayContext::DisplayContext()
|
||||
{
|
||||
view = 0;
|
||||
renderer = 0;
|
||||
engine = 0;
|
||||
flags = 0;
|
||||
settings = 0;
|
||||
m_renderState = 0;
|
||||
|
||||
m_currentMatrix = 0;
|
||||
m_matrixStack[m_currentMatrix].SetIdentity();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DrawTri( const Vec3 &p1,const Vec3 &p2,const Vec3 &p3 )
|
||||
{
|
||||
struct_VERTEX_FORMAT_P3F_TEX2F verts[4];
|
||||
memset( verts,0,sizeof(verts) );
|
||||
verts[0].xyz = p1;
|
||||
|
||||
verts[1].xyz = p2;
|
||||
|
||||
verts[2].xyz = p3;
|
||||
|
||||
renderer->DrawTriStrip(&(CVertexBuffer(verts,VERTEX_FORMAT_P3F_TEX2F)),3);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DrawQuad( const Vec3 &p1,const Vec3 &p2,const Vec3 &p3,const Vec3 &p4 )
|
||||
{
|
||||
struct_VERTEX_FORMAT_P3F_TEX2F verts[4];
|
||||
memset( verts,0,sizeof(verts) );
|
||||
verts[0].xyz = p1;
|
||||
|
||||
verts[1].xyz = p2;
|
||||
|
||||
verts[3].xyz = p3;
|
||||
|
||||
verts[2].xyz = p4;
|
||||
|
||||
renderer->DrawTriStrip(&(CVertexBuffer(verts,VERTEX_FORMAT_P3F_TEX2F)),4);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DrawTexturePolygon( PolyVertex *points,int numPoints )
|
||||
{
|
||||
assert( points != 0 );
|
||||
assert( numPoints > 0 );
|
||||
renderer->DrawTriStrip(&(CVertexBuffer(points,VERTEX_FORMAT_P3F_TEX2F)),numPoints);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DrawWireBox( const Vec3 &min,const Vec3 &max,float offset )
|
||||
{
|
||||
// Near
|
||||
renderer->DrawLine( Vec3(min.x,min.y,max.z),Vec3(max.x,min.y,max.z) );
|
||||
renderer->DrawLine( Vec3(min.x,max.y,max.z),Vec3(max.x,max.y,max.z) );
|
||||
renderer->DrawLine( Vec3(min.x,min.y,max.z),Vec3(min.x,max.y,max.z) );
|
||||
renderer->DrawLine( Vec3(max.x,min.y,max.z),Vec3(max.x,max.y,max.z) );
|
||||
|
||||
// Far
|
||||
renderer->DrawLine( Vec3(min.x,min.y,min.z),Vec3(max.x,min.y,min.z) );
|
||||
renderer->DrawLine( Vec3(min.x,max.y,min.z),Vec3(max.x,max.y,min.z) );
|
||||
renderer->DrawLine( Vec3(min.x,min.y,min.z),Vec3(min.x,max.y,min.z) );
|
||||
renderer->DrawLine( Vec3(max.x,min.y,min.z),Vec3(max.x,max.y,min.z) );
|
||||
|
||||
// Sides.
|
||||
renderer->DrawLine( Vec3(min.x,min.y,min.z),Vec3(min.x,min.y,max.z) );
|
||||
renderer->DrawLine( Vec3(max.x,min.y,min.z),Vec3(max.x,min.y,max.z) );
|
||||
renderer->DrawLine( Vec3(min.x,max.y,min.z),Vec3(min.x,max.y,max.z) );
|
||||
renderer->DrawLine( Vec3(max.x,max.y,min.z),Vec3(max.x,max.y,max.z) );
|
||||
|
||||
// Draw another wire box with offset.
|
||||
if (offset != 0)
|
||||
{
|
||||
DrawWireBox( min-Vec3(offset,offset,offset),max+Vec3(offset,offset,offset),0 );
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayContext::DrawSolidBox( const Vec3 &min,const Vec3 &max )
|
||||
{
|
||||
Vec3 p[8];
|
||||
p[0] = Vec3(max.x,max.y,max.z);
|
||||
p[1] = Vec3(min.x,max.y,max.z);
|
||||
p[2] = Vec3(min.x,min.y,max.z);
|
||||
p[3] = Vec3(max.x,min.y,max.z);
|
||||
|
||||
p[4] = Vec3(max.x,max.y,min.z);
|
||||
p[5] = Vec3(min.x,max.y,min.z);
|
||||
p[6] = Vec3(min.x,min.y,min.z);
|
||||
p[7] = Vec3(max.x,min.y,min.z);
|
||||
|
||||
DrawQuad( p[0],p[1],p[2],p[3] );
|
||||
DrawQuad( p[4],p[7],p[6],p[5] );
|
||||
|
||||
DrawQuad( p[0],p[3],p[7],p[4] );
|
||||
DrawQuad( p[1],p[5],p[6],p[2] );
|
||||
|
||||
DrawQuad( p[0],p[4],p[5],p[1] );
|
||||
DrawQuad( p[3],p[2],p[6],p[7] );
|
||||
}
|
||||
|
||||
void DisplayContext::DrawLine( const Vec3 &p1,const Vec3 &p2 )
|
||||
{
|
||||
renderer->DrawLine( p1, p2 );
|
||||
}
|
||||
|
||||
void DisplayContext::DrawPolyLine( const Vec3 *pnts,int numPoints )
|
||||
{
|
||||
assert( pnts != 0 );
|
||||
assert( numPoints > 1 );
|
||||
for (int i = 0; i < numPoints; i++)
|
||||
{
|
||||
int j = (i+1)<numPoints?(i+1):0;
|
||||
renderer->DrawLine( pnts[i],pnts[j] );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DrawTerrainCircle( const Vec3 &pos,float radius,float height )
|
||||
{
|
||||
// Draw circle with default radius.
|
||||
Vec3 p0,p1;
|
||||
p0.x = pos.x + radius*sin(0.0f);
|
||||
p0.y = pos.y + radius*cos(0.0f);
|
||||
p0.z = engine->GetTerrainElevation( p0.x,p0.y )+height;
|
||||
float step = 10.0f/180*gf_PI;
|
||||
for (float angle = step; angle < 360.0f/180*gf_PI+step; angle += step)
|
||||
{
|
||||
p1.x = pos.x + radius*sin(angle);
|
||||
p1.y = pos.y + radius*cos(angle);
|
||||
p1.z = engine->GetTerrainElevation( p1.x,p1.y )+height;
|
||||
renderer->DrawLine( p0,p1 );
|
||||
p0 = p1;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DrawCircle( const Vec3 &pos,float radius )
|
||||
{
|
||||
// Draw circle with default radius.
|
||||
Vec3 p0,p1;
|
||||
p0.x = pos.x + radius*sin(0.0f);
|
||||
p0.y = pos.y + radius*cos(0.0f);
|
||||
p0.z = pos.z;
|
||||
float step = 10.0f/180*gf_PI;
|
||||
for (float angle = step; angle < 360.0f/180*gf_PI+step; angle += step)
|
||||
{
|
||||
p1.x = pos.x + radius*sin(angle);
|
||||
p1.y = pos.y + radius*cos(angle);
|
||||
p1.z = pos.z;
|
||||
renderer->DrawLine( p0,p1 );
|
||||
p0 = p1;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DrawWireCircle2d( const CPoint ¢er,float radius,float z )
|
||||
{
|
||||
Vec3 p0,p1,pos;
|
||||
pos.x = center.x;
|
||||
pos.y = center.y;
|
||||
pos.z = z;
|
||||
p0.x = pos.x + radius*sin(0.0f);
|
||||
p0.y = pos.y + radius*cos(0.0f);
|
||||
p0.z = z;
|
||||
float step = 10.0f/180*gf_PI;
|
||||
for (float angle = step; angle < 360.0f/180*gf_PI+step; angle += step)
|
||||
{
|
||||
p1.x = pos.x + radius*sin(angle);
|
||||
p1.y = pos.y + radius*cos(angle);
|
||||
p1.z = z;
|
||||
renderer->DrawLine( p0,p1 );
|
||||
p0 = p1;
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayContext::DrawWireSphere( const Vec3 &pos,float radius )
|
||||
{
|
||||
Vec3 p0,p1;
|
||||
float step = 10.0f/180*gf_PI;
|
||||
float angle;
|
||||
|
||||
// Z Axis
|
||||
p0 = pos;
|
||||
p1 = pos;
|
||||
p0.x += radius*sin(0.0f);
|
||||
p0.y += radius*cos(0.0f);
|
||||
for (angle = step; angle < 360.0f/180*gf_PI+step; angle += step)
|
||||
{
|
||||
p1.x = pos.x + radius*sin(angle);
|
||||
p1.y = pos.y + radius*cos(angle);
|
||||
p1.z = pos.z;
|
||||
renderer->DrawLine( p0,p1 );
|
||||
p0 = p1;
|
||||
}
|
||||
|
||||
// X Axis
|
||||
p0 = pos;
|
||||
p1 = pos;
|
||||
p0.y += radius*sin(0.0f);
|
||||
p0.z += radius*cos(0.0f);
|
||||
for (angle = step; angle < 360.0f/180*gf_PI+step; angle += step)
|
||||
{
|
||||
p1.y = pos.y + radius*sin(angle);
|
||||
p1.z = pos.z + radius*cos(angle);
|
||||
renderer->DrawLine( p0,p1 );
|
||||
p0 = p1;
|
||||
}
|
||||
|
||||
// Y Axis
|
||||
p0 = pos;
|
||||
p1 = pos;
|
||||
p0.x += radius*sin(0.0f);
|
||||
p0.z += radius*cos(0.0f);
|
||||
for (angle = step; angle < 360.0f/180*gf_PI+step; angle += step)
|
||||
{
|
||||
p1.x = pos.x + radius*sin(angle);
|
||||
p1.z = pos.z + radius*cos(angle);
|
||||
renderer->DrawLine( p0,p1 );
|
||||
p0 = p1;
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayContext::DrawWireQuad2d( const CPoint &pmin,const CPoint &pmax,float z )
|
||||
{
|
||||
renderer->DrawLine( Vec3(pmin.x,pmin.y,z),Vec3(pmax.x,pmin.y,z) );
|
||||
renderer->DrawLine( Vec3(pmax.x,pmin.y,z),Vec3(pmax.x,pmax.y,z) );
|
||||
renderer->DrawLine( Vec3(pmax.x,pmax.y,z),Vec3(pmin.x,pmax.y,z) );
|
||||
renderer->DrawLine( Vec3(pmin.x,pmax.y,z),Vec3(pmin.x,pmin.y,z) );
|
||||
}
|
||||
|
||||
void DisplayContext::DrawLine2d( const CPoint &pmin,const CPoint &pmax,float z )
|
||||
{
|
||||
renderer->DrawLine( Vec3(pmin.x,pmin.y,z),Vec3(pmax.x,pmin.y,z) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::SetColor( float r,float g,float b,float a )
|
||||
{
|
||||
m_color[0] = r;
|
||||
m_color[1] = g;
|
||||
m_color[2] = b;
|
||||
m_color[3] = a;
|
||||
renderer->SetMaterialColor( r,g,b,a );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::SetColor( const Vec3 &color,float a )
|
||||
{
|
||||
m_color[0] = color.x;
|
||||
m_color[1] = color.y;
|
||||
m_color[2] = color.z;
|
||||
m_color[3] = a;
|
||||
renderer->SetMaterialColor( color.x,color.y,color.z,a );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::SetColor( COLORREF rgb,float a )
|
||||
{
|
||||
Vec3 col = Rgb2Vec(rgb);
|
||||
m_color[0] = col.x;
|
||||
m_color[1] = col.y;
|
||||
m_color[2] = col.z;
|
||||
m_color[3] = a;
|
||||
renderer->SetMaterialColor( col.x,col.y,col.z,a );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
COLORREF DisplayContext::GetSelectedColor()
|
||||
{
|
||||
float t = GetTickCount() / 1000.0f;
|
||||
float r1 = fabs(sin(t*8.0f));
|
||||
if (r1 > 255)
|
||||
r1 = 255;
|
||||
return RGB( 255,0,r1*255 );
|
||||
// float r2 = cos(t*3);
|
||||
//dc.renderer->SetMaterialColor( 1,0,r1,0.5f );
|
||||
}
|
||||
|
||||
COLORREF DisplayContext::GetFreezeColor()
|
||||
{
|
||||
return FREEZE_COLOR;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::SetSelectedColor( float fAlpha )
|
||||
{
|
||||
SetColor( GetSelectedColor(),fAlpha );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::SetFreezeColor()
|
||||
{
|
||||
SetColor( FREEZE_COLOR,0.5f );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DrawLine( const Vec3 &p1,const Vec3 &p2,const CFColor &col1,const CFColor &col2 )
|
||||
{
|
||||
renderer->DrawLineColor( p1,col1,p2,col2 );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DrawLine( const Vec3 &p1,const Vec3 &p2,COLORREF rgb1,COLORREF rgb2 )
|
||||
{
|
||||
Vec3 c1 = Rgb2Vec(rgb1);
|
||||
Vec3 c2 = Rgb2Vec(rgb2);
|
||||
renderer->DrawLineColor( p1,c1,p2,c2 );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::PushMatrix( const Matrix44 &tm )
|
||||
{
|
||||
m_currentMatrix++;
|
||||
m_matrixStack[m_currentMatrix] = tm * m_matrixStack[m_currentMatrix-1];
|
||||
|
||||
renderer->PushMatrix();
|
||||
//renderer->LoadMatrix( &tm );
|
||||
//renderer->TranslateMatrix( Vec3(tm[3][0],tm[3][1],tm[3][2]) );
|
||||
renderer->MultMatrix( (float*)const_cast<Matrix44*>(&tm) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::PopMatrix()
|
||||
{
|
||||
m_currentMatrix--;
|
||||
renderer->PopMatrix();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DrawBall( const Vec3 &pos,float radius )
|
||||
{
|
||||
//RenderObject( STATOBJECT_SPHERE,pos,radius );
|
||||
renderer->DrawBall( pos,radius );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DrawArrow( const Vec3 &src,const Vec3 &trg,float fHeadScale )
|
||||
{
|
||||
Vec3 dir = trg - src;
|
||||
Matrix44 tm = MatrixFromVector( dir );
|
||||
|
||||
renderer->DrawLine( src,trg );
|
||||
|
||||
tm = Matrix33::CreateScale( Vec3d(fHeadScale,fHeadScale,fHeadScale) ) * tm;
|
||||
|
||||
tm.SetTranslationOLD( trg );
|
||||
//if (flags & DISPLAY_2D)
|
||||
{
|
||||
PushMatrix(tm);
|
||||
|
||||
DrawLine( Vec3(0,0,0),Vec3(0,0.4f,0) );
|
||||
|
||||
DrawLine( Vec3(-0.15f,0,0),Vec3(0,0.4f,0) );
|
||||
DrawLine( Vec3(0.15f,0,0),Vec3(0,0.4f,0) );
|
||||
|
||||
DrawLine( Vec3(0,0,-0.15f),Vec3(0,0.4f,0) );
|
||||
DrawLine( Vec3(0,0,0.15f),Vec3(0,0.4f,0) );
|
||||
PopMatrix();
|
||||
}
|
||||
//else
|
||||
//RenderObject( STATOBJECT_ARROW,tm );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::RenderObject( int objectType,const Vec3 &pos,float scale )
|
||||
{
|
||||
Matrix44 tm;
|
||||
tm.SetIdentity();
|
||||
|
||||
tm = Matrix33::CreateScale( Vec3d(scale,scale,scale) ) * tm;
|
||||
|
||||
tm.SetTranslationOLD(pos);
|
||||
RenderObject( objectType,tm );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::RenderObject( int objectType,const Matrix44 &tm )
|
||||
{
|
||||
IStatObj *object = GetIEditor()->GetIconManager()->GetObject((EObject)objectType);
|
||||
if (object)
|
||||
{
|
||||
Matrix44 xform = tm * m_matrixStack[m_currentMatrix];
|
||||
SRendParams rp;
|
||||
rp.pMatrix = &xform;
|
||||
rp.vColor = Vec3(m_color[0],m_color[1],m_color[2]);
|
||||
rp.fAlpha = m_color[3];
|
||||
rp.nDLightMask = 0xFFFF;
|
||||
rp.dwFObjFlags |= FOB_TRANS_MASK;
|
||||
object->Render( rp, Vec3(zero), 0);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DrawIcon( EIcon icon,const Vec3 &pos,float fScale )
|
||||
{
|
||||
int texId = GetIEditor()->GetIconManager()->GetIcon(icon);
|
||||
renderer->DrawLabelImage( pos,fScale,texId );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DrawTerrainRect( float x1,float y1,float x2,float y2,float height )
|
||||
{
|
||||
Vec3 p1,p2;
|
||||
float x,y;
|
||||
|
||||
float step = MAX( y2-y1,x2-x1 );
|
||||
if (step < 0.1)
|
||||
return;
|
||||
step = step / 100.0f;
|
||||
|
||||
for (y = y1; y < y2+step; y += step)
|
||||
{
|
||||
p1.x = x1;
|
||||
p1.y = y;
|
||||
p1.z = engine->GetTerrainElevation( p1.x,p1.y ) + height;
|
||||
|
||||
p2.x = x1;
|
||||
p2.y = y+step;
|
||||
p2.z = engine->GetTerrainElevation( p2.x,p2.y ) + height;
|
||||
DrawLine( p1,p2 );
|
||||
|
||||
p1.x = x2+step;
|
||||
p1.y = y;
|
||||
p1.z = engine->GetTerrainElevation( p1.x,p1.y ) + height;
|
||||
|
||||
p2.x = x2+step;
|
||||
p2.y = y+step;
|
||||
p2.z = engine->GetTerrainElevation( p2.x,p2.y ) + height;
|
||||
DrawLine( p1,p2 );
|
||||
}
|
||||
for (x = x1; x < x2+step; x += step)
|
||||
{
|
||||
p1.x = x;
|
||||
p1.y = y1;
|
||||
p1.z = engine->GetTerrainElevation( p1.x,p1.y ) + height;
|
||||
|
||||
p2.x = x+step;
|
||||
p2.y = y1;
|
||||
p2.z = engine->GetTerrainElevation( p2.x,p2.y ) + height;
|
||||
DrawLine( p1,p2 );
|
||||
|
||||
p1.x = x;
|
||||
p1.y = y2+step;
|
||||
p1.z = engine->GetTerrainElevation( p1.x,p1.y ) + height;
|
||||
|
||||
p2.x = x+step;
|
||||
p2.y = y2+step;
|
||||
p2.z = engine->GetTerrainElevation( p2.x,p2.y ) + height;
|
||||
DrawLine( p1,p2 );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DrawTextLabel( const Vec3& pos,float size,const char *text )
|
||||
{
|
||||
view->DrawTextLabel( *this,pos,size,CFColor(m_color[0],m_color[1],m_color[2],m_color[3]),text );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::Draw2dTextLabel( float x,float y,float size,const char *text )
|
||||
{
|
||||
renderer->Draw2dLabel( x,y,size,m_color,false,"%s",text );
|
||||
//view->DrawTextLabel( *this,pos,size,Vec3(m_color[0],m_color[1],m_color[2]),text );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::SetLineWidth( float width )
|
||||
{
|
||||
renderer->SetLineWidth( width );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool DisplayContext::IsVisible( const BBox &bounds )
|
||||
{
|
||||
if (flags & DISPLAY_2D)
|
||||
{
|
||||
if (box.IsIntersectBox( bounds ))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return camera->IsAABBVisibleFast( AABB(bounds.min,bounds.max) );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
uint DisplayContext::GetState() const
|
||||
{
|
||||
return m_renderState;
|
||||
}
|
||||
|
||||
//! Set a new render state flags.
|
||||
//! @param returns previous render state.
|
||||
uint DisplayContext::SetState( uint state )
|
||||
{
|
||||
uint old = m_renderState;
|
||||
m_renderState = state;
|
||||
renderer->SetState( m_renderState );
|
||||
return old;
|
||||
}
|
||||
|
||||
//! Set a new render state flags.
|
||||
//! @param returns previous render state.
|
||||
uint DisplayContext::SetStateFlag( uint state )
|
||||
{
|
||||
uint old = m_renderState;
|
||||
m_renderState |= state;
|
||||
renderer->SetState( m_renderState );
|
||||
return old;
|
||||
}
|
||||
|
||||
//! Clear specified flags in render state.
|
||||
//! @param returns previous render state.
|
||||
uint DisplayContext::ClearStateFlag( uint state )
|
||||
{
|
||||
uint old = m_renderState;
|
||||
m_renderState &= ~state;
|
||||
renderer->SetState( m_renderState );
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
char BoxSides[0x40*8] = {
|
||||
0,0,0,0, 0,0,0,0, //00
|
||||
0,4,6,2, 0,0,0,4, //01
|
||||
7,5,1,3, 0,0,0,4, //02
|
||||
0,0,0,0, 0,0,0,0, //03
|
||||
0,1,5,4, 0,0,0,4, //04
|
||||
0,1,5,4, 6,2,0,6, //05
|
||||
7,5,4,0, 1,3,0,6, //06
|
||||
0,0,0,0, 0,0,0,0, //07
|
||||
7,3,2,6, 0,0,0,4, //08
|
||||
0,4,6,7, 3,2,0,6, //09
|
||||
7,5,1,3, 2,6,0,6, //0a
|
||||
0,0,0,0, 0,0,0,0, //0b
|
||||
0,0,0,0, 0,0,0,0, //0c
|
||||
0,0,0,0, 0,0,0,0, //0d
|
||||
0,0,0,0, 0,0,0,0, //0e
|
||||
0,0,0,0, 0,0,0,0, //0f
|
||||
0,2,3,1, 0,0,0,4, //10
|
||||
0,4,6,2, 3,1,0,6, //11
|
||||
7,5,1,0, 2,3,0,6, //12
|
||||
0,0,0,0, 0,0,0,0, //13
|
||||
0,2,3,1, 5,4,0,6, //14
|
||||
1,5,4,6, 2,3,0,6, //15
|
||||
7,5,4,0, 2,3,0,6, //16
|
||||
0,0,0,0, 0,0,0,0, //17
|
||||
0,2,6,7, 3,1,0,6, //18
|
||||
0,4,6,7, 3,1,0,6, //19
|
||||
7,5,1,0, 2,6,0,6, //1a
|
||||
0,0,0,0, 0,0,0,0, //1b
|
||||
0,0,0,0, 0,0,0,0, //1c
|
||||
0,0,0,0, 0,0,0,0, //1d
|
||||
0,0,0,0, 0,0,0,0, //1e
|
||||
0,0,0,0, 0,0,0,0, //1f
|
||||
7,6,4,5, 0,0,0,4, //20
|
||||
0,4,5,7, 6,2,0,6, //21
|
||||
7,6,4,5, 1,3,0,6, //22
|
||||
0,0,0,0, 0,0,0,0, //23
|
||||
7,6,4,0, 1,5,0,6, //24
|
||||
0,1,5,7, 6,2,0,6, //25
|
||||
7,6,4,0, 1,3,0,6, //26
|
||||
0,0,0,0, 0,0,0,0, //27
|
||||
7,3,2,6, 4,5,0,6, //28
|
||||
0,4,5,7, 3,2,0,6, //29
|
||||
6,4,5,1, 3,2,0,6, //2a
|
||||
0,0,0,0, 0,0,0,0, //2b
|
||||
0,0,0,0, 0,0,0,0, //2c
|
||||
0,0,0,0, 0,0,0,0, //2d
|
||||
0,0,0,0, 0,0,0,0, //2e
|
||||
0,0,0,0, 0,0,0,0, //2f
|
||||
0,0,0,0, 0,0,0,0, //30
|
||||
0,0,0,0, 0,0,0,0, //31
|
||||
0,0,0,0, 0,0,0,0, //32
|
||||
0,0,0,0, 0,0,0,0, //33
|
||||
0,0,0,0, 0,0,0,0, //34
|
||||
0,0,0,0, 0,0,0,0, //35
|
||||
0,0,0,0, 0,0,0,0, //36
|
||||
0,0,0,0, 0,0,0,0, //37
|
||||
0,0,0,0, 0,0,0,0, //38
|
||||
0,0,0,0, 0,0,0,0, //39
|
||||
0,0,0,0, 0,0,0,0, //3a
|
||||
0,0,0,0, 0,0,0,0, //3b
|
||||
0,0,0,0, 0,0,0,0, //3c
|
||||
0,0,0,0, 0,0,0,0, //3d
|
||||
0,0,0,0, 0,0,0,0, //3e
|
||||
0,0,0,0, 0,0,0,0, //3f
|
||||
};
|
||||
|
||||
149
Editor/Objects/DisplayContext.h
Normal file
149
Editor/Objects/DisplayContext.h
Normal file
@@ -0,0 +1,149 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: DisplayContext.h
|
||||
// Version: v1.00
|
||||
// Created: 4/12/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: DisplayContext definition.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __DisplayContext_h__
|
||||
#define __DisplayContext_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "..\IconManager.h"
|
||||
|
||||
// forward declarations.
|
||||
class CViewport;
|
||||
|
||||
enum DisplayFlags {
|
||||
DISPLAY_2D = 0x01,
|
||||
DISPLAY_HIDENAMES = 0x02,
|
||||
DISPLAY_BBOX = 0x04,
|
||||
DISPLAY_TRACKS = 0x08,
|
||||
DISPLAY_TRACKTICKS = 0x010,
|
||||
DISPLAY_WORLDSPACEAXIS = 0x020, //!< Set if axis must be displayed in world space.
|
||||
DISPLAY_LINKS = 0x040,
|
||||
DISPLAY_DEGRADATED = 0x080, //!< Display Objects in degradated quality (When moving/modifying).
|
||||
};
|
||||
|
||||
/*!
|
||||
* DisplayContex is a structure passed to BaseObject Display method.
|
||||
* It contains everything the object should know to display itself in a view.
|
||||
* All fields must be filled before passing that structure to Display call.
|
||||
*/
|
||||
struct DisplayContext
|
||||
{
|
||||
typedef struct_VERTEX_FORMAT_P3F_TEX2F PolyVertex;
|
||||
|
||||
CDisplaySettings* settings;
|
||||
CViewport* view;
|
||||
IRenderer* renderer;
|
||||
I3DEngine* engine;
|
||||
CCamera* camera;
|
||||
BBox box; // Bounding box of volume that need to be repainted.
|
||||
int flags;
|
||||
|
||||
|
||||
//! Ctor.
|
||||
DisplayContext();
|
||||
// Helper methods.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Draw functions
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Set current materialc color.
|
||||
void SetColor( float r,float g,float b,float a=1 );
|
||||
void SetColor( const Vec3 &color,float a=1 );
|
||||
void SetColor( COLORREF rgb,float a=1 );
|
||||
|
||||
void SetSelectedColor( float fAlpha=1 );
|
||||
void SetFreezeColor();
|
||||
|
||||
//! Get color to draw selectin of object.
|
||||
COLORREF GetSelectedColor();
|
||||
COLORREF GetFreezeColor();
|
||||
|
||||
//! Draw 3D quad.
|
||||
void DrawQuad( const Vec3 &p1,const Vec3 &p2,const Vec3 &p3,const Vec3 &p4 );
|
||||
//! Draw 3D Triangle.
|
||||
void DrawTri( const Vec3 &p1,const Vec3 &p2,const Vec3 &p3 );
|
||||
//! Draw wireframe box.
|
||||
void DrawWireBox( const Vec3 &min,const Vec3 &max,float offset2nd=0 );
|
||||
void DrawSolidBox( const Vec3 &min,const Vec3 &max );
|
||||
void DrawLine( const Vec3 &p1,const Vec3 &p2 );
|
||||
void DrawLine( const Vec3 &p1,const Vec3 &p2,const CFColor &col1,const CFColor &col2 );
|
||||
void DrawLine( const Vec3 &p1,const Vec3 &p2,COLORREF rgb1,COLORREF rgb2 );
|
||||
void DrawPolyLine( const Vec3 *pnts,int numPoints );
|
||||
|
||||
void DrawWireQuad2d( const CPoint &p1,const CPoint &p2,float z );
|
||||
void DrawLine2d( const CPoint &p1,const CPoint &p2,float z );
|
||||
void DrawWireCircle2d( const CPoint ¢er,float radius,float z );
|
||||
|
||||
//! Draw polygon with texturing.
|
||||
//! @param points Array of polygon vertices, must contain at least numPoints entries.
|
||||
void DrawTexturePolygon( PolyVertex *points,int numPoints );
|
||||
|
||||
// Draw circle from lines on terrain.
|
||||
void DrawTerrainCircle( const Vec3 &pos,float radius,float height );
|
||||
void DrawCircle( const Vec3 &pos,float radius );
|
||||
|
||||
//! Draw rectangle on top of terrain.
|
||||
//! Coordinates are in world space.
|
||||
void DrawTerrainRect( float x1,float y1,float x2,float y2,float height );
|
||||
|
||||
void DrawWireSphere( const Vec3 &pos,float radius );
|
||||
|
||||
void PushMatrix( const Matrix44 &tm );
|
||||
void PopMatrix();
|
||||
|
||||
// Draw special 3D objects.
|
||||
void DrawBall( const Vec3 &pos,float radius );
|
||||
|
||||
//! Draws 3d arrow.
|
||||
void DrawArrow( const Vec3 &src,const Vec3 &trg,float fHeadScale=1 );
|
||||
|
||||
//! Draw 3D icon.
|
||||
void DrawIcon( EIcon icon,const Vec3 &pos,float fScale=1 );
|
||||
|
||||
void RenderObject( int objectType,const Vec3 &pos,float scale );
|
||||
void RenderObject( int objectType,const Matrix44 &tm );
|
||||
|
||||
void DrawTextLabel( const Vec3& pos,float size,const char *text );
|
||||
void Draw2dTextLabel( float x,float y,float size,const char *text );
|
||||
void SetLineWidth( float width );
|
||||
|
||||
//! Is givven bbox visible in this display context.
|
||||
bool IsVisible( const BBox &bounds );
|
||||
|
||||
//! Gets current render state.
|
||||
uint GetState() const;
|
||||
//! Set a new render state.
|
||||
//! @param returns previous render state.
|
||||
uint SetState( uint state );
|
||||
//! Set a new render state flags.
|
||||
//! @param returns previous render state.
|
||||
uint SetStateFlag( uint state );
|
||||
//! Clear specified flags in render state.
|
||||
//! @param returns previous render state.
|
||||
uint ClearStateFlag( uint state );
|
||||
|
||||
private:
|
||||
float m_color[4];
|
||||
uint m_renderState;
|
||||
|
||||
int m_currentMatrix;
|
||||
//! Matrix stack.
|
||||
Matrix44 m_matrixStack[16];
|
||||
};
|
||||
|
||||
#endif // __DisplayContext_h__
|
||||
2332
Editor/Objects/Entity.cpp
Normal file
2332
Editor/Objects/Entity.cpp
Normal file
File diff suppressed because it is too large
Load Diff
382
Editor/Objects/Entity.h
Normal file
382
Editor/Objects/Entity.h
Normal file
@@ -0,0 +1,382 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: Entity.h
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: StaticObject object definition.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __Entity_h__
|
||||
#define __Entity_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "BaseObject.h"
|
||||
#include "EntityScript.h"
|
||||
#include "TrackGizmo.h"
|
||||
|
||||
#include "IMovieSystem.h"
|
||||
#include "EntityPrototype.h"
|
||||
|
||||
#include "Material\Material.h"
|
||||
|
||||
|
||||
/*!
|
||||
* CEntityEventTarget is an Entity event target and type.
|
||||
*/
|
||||
struct CEntityEventTarget
|
||||
{
|
||||
CBaseObject* target; //! Target object.
|
||||
_smart_ptr<CGizmo> pLineGizmo;
|
||||
CString event;
|
||||
CString sourceEvent;
|
||||
};
|
||||
|
||||
/*!
|
||||
* CEntity is an static object on terrain.
|
||||
*
|
||||
*/
|
||||
class CRYEDIT_API CEntity : public CBaseObject,public IAnimNodeCallback
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CEntity)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Return type name of Entity.
|
||||
CString GetTypeDescription() const { return GetEntityClass(); };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool IsSameClass( CBaseObject *obj );
|
||||
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
bool CreateGameObject();
|
||||
void Display( DisplayContext &disp );
|
||||
|
||||
int MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags );
|
||||
|
||||
void SetName( const CString &name );
|
||||
void SetPos( const Vec3d &pos );
|
||||
void SetAngles( const Vec3d &angles );
|
||||
void SetScale( const Vec3d &scale );
|
||||
|
||||
void SetSelected( bool bSelect );
|
||||
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
void BeginEditMultiSelParams( bool bAllOfSameType );
|
||||
void EndEditMultiSelParams();
|
||||
|
||||
void GetBoundBox( BBox &box );
|
||||
void GetLocalBounds( BBox &box );
|
||||
|
||||
bool HitTest( HitContext &hc );
|
||||
void UpdateVisibility( bool visible );
|
||||
bool ConvertFromObject( CBaseObject *object );
|
||||
|
||||
void Serialize( CObjectArchive &ar );
|
||||
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
|
||||
void SetLookAt( CBaseObject *target );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void OnEvent( ObjectEvent event );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual IAnimNode* GetAnimNode() const { return m_animNode; };
|
||||
virtual IPhysicalEntity* GetCollisionEntity() const;
|
||||
|
||||
//! Return entity prototype class if present.
|
||||
virtual CEntityPrototype* GetPrototype() const { return m_prototype; };
|
||||
|
||||
//! Attach new child node.
|
||||
virtual void AttachChild( CBaseObject* child,bool bKeepPos=true );
|
||||
//! Detach all childs of this node.
|
||||
virtual void DetachAll( bool bKeepPos=true );
|
||||
// Detach this node from parent.
|
||||
virtual void DetachThis( bool bKeepPos=true );
|
||||
|
||||
virtual void SetHelperScale( float scale );
|
||||
virtual float GetHelperScale() { return m_helperScale; };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CEntity interface.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual bool LoadScript( const CString &entityClass,bool bForceReload=false,bool bGetScriptProperties=true,XmlNodeRef xmlProperties=XmlNodeRef(),XmlNodeRef xmlProperties2=XmlNodeRef() );
|
||||
virtual void SpawnEntity();
|
||||
virtual void DeleteEntity();
|
||||
virtual void UnloadScript();
|
||||
|
||||
CString GetEntityClass() const { return m_entityClass; };
|
||||
int GetEntityId() const { return m_entityId; };
|
||||
|
||||
//! Get EntityScript object associated with this entity.
|
||||
CEntityScript* GetScript() { return m_script; }
|
||||
//! Reload entity script.
|
||||
void Reload( bool bReloadScript=false );
|
||||
|
||||
//! Return number of event targets of Script.
|
||||
int GetEventTargetCount() const { return m_eventTargets.size(); };
|
||||
CEntityEventTarget& GetEventTarget( int index ) { return m_eventTargets[index]; };
|
||||
//! Add new event target, returns index of created event target.
|
||||
//! Event targets are Always entities.
|
||||
int AddEventTarget( CBaseObject *target,const CString &event,const CString &sourceEvent,bool bUpdateScript=true );
|
||||
//! Remove existing event target by index.
|
||||
void RemoveEventTarget( int index,bool bUpdateScript=true );
|
||||
|
||||
//! Get Game entity interface.
|
||||
IEntity* GetIEntity() { return m_entity; };
|
||||
|
||||
bool IsCastShadow() const { return mv_castShadows; }
|
||||
bool IsSelfShadowing() const { return mv_selfShadowing; }
|
||||
bool IsCastShadowMaps() const { return mv_castShadowMaps; }
|
||||
bool IsRecvShadowMaps() const { return mv_recvShadowMaps; }
|
||||
bool IsCastLightmap() const { return mv_castLightmap; }
|
||||
bool IsRecvLightmap() const { return mv_recvLightmap; }
|
||||
bool IsHideable() const { return mv_recvLightmap; }
|
||||
float GetRatioLod() const { return mv_ratioLOD; };
|
||||
float GetRatioViewDist() const { return mv_ratioViewDist; }
|
||||
|
||||
CVarBlock* GetProperties() const { return m_properties; };
|
||||
CVarBlock* GetProperties2() const { return m_properties2; };
|
||||
// unsigned MemStats();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Override materials.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetMaterial( CMaterial *mtl );
|
||||
virtual CMaterial* GetMaterial() const { return m_pMaterial; };
|
||||
|
||||
void Validate( CErrorReport *report );
|
||||
|
||||
//! Takes position/orientation from the game entity and apply on editor entity.
|
||||
void AcceptPhysicsState();
|
||||
void ResetPhysicsState();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void GatherUsedResources( CUsedResources &resources );
|
||||
virtual bool IsSimilarObject( CBaseObject *pObject );
|
||||
|
||||
protected:
|
||||
bool HitTestEntity( HitContext &hc,bool &bHavePhysics );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Must be called after cloning the object on clone of object.
|
||||
//! This will make sure object references are cloned correctly.
|
||||
virtual void PostClone( CBaseObject *pFromObject,CObjectCloneContext &ctx );
|
||||
|
||||
// Called to create AnimNode for this object.
|
||||
virtual IAnimNode* CreateAnimNode();
|
||||
// overrided from IAnimNodeCallback
|
||||
virtual void OnNodeAnimated();
|
||||
|
||||
void OnLoadFailed();
|
||||
|
||||
CVarBlock* CloneProperties( CVarBlock *srcProperties );
|
||||
void UpdatePropertyPanel();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Callback called when one of entity properties have been modified.
|
||||
void OnPropertyChange( IVariable *var );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void OnEventTargetEvent( CBaseObject *target,int event );
|
||||
void ResolveEventTarget( CBaseObject *object,unsigned int index );
|
||||
void ReleaseEventTargets();
|
||||
void UpdateMaterialInfo();
|
||||
|
||||
//! Dtor must be protected.
|
||||
CEntity();
|
||||
void DeleteThis() { delete this; };
|
||||
|
||||
//overrided from CBaseObject.
|
||||
void InvalidateTM();
|
||||
|
||||
//! Draw target lines.
|
||||
void DrawTargets( DisplayContext &dc );
|
||||
|
||||
//! Recalculate bounding box of entity.
|
||||
void CalcBBox();
|
||||
|
||||
//! Force IEntity to the local position/angles/scale.
|
||||
void XFormGameEntity();
|
||||
|
||||
//! Sets correct binding for IEntity.
|
||||
void BindToParent();
|
||||
void BindIEntityChilds();
|
||||
void UnbindIEntity();
|
||||
|
||||
void DrawAIInfo( DisplayContext &dc,struct IAIObject *aiObj );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Callbacks.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void OnRenderFlagsChange( IVariable *var );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Radius callbacks.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void OnRadiusChange( IVariable *var );
|
||||
void OnInnerRadiusChange( IVariable *var );
|
||||
void OnOuterRadiusChange( IVariable *var );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Entity class.
|
||||
CString m_entityClass;
|
||||
//! Id of spawned entity.
|
||||
int m_entityId;
|
||||
|
||||
IEntity* m_entity;
|
||||
IStatObj* m_visualObject;
|
||||
BBox m_box;
|
||||
|
||||
bool m_loadFailed;
|
||||
bool m_bEntityXfromValid;
|
||||
bool m_bCalcPhysics;
|
||||
|
||||
// Cached quaternion.
|
||||
Quat m_rotate;
|
||||
|
||||
TSmartPtr<CEntityScript> m_script;
|
||||
|
||||
bool m_displayBBox;
|
||||
bool m_visible;
|
||||
//! True if this is static entity.
|
||||
//bool m_staticEntity;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Main entity parameters.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CVariable<bool> mv_castShadows;
|
||||
CVariable<bool> mv_selfShadowing;
|
||||
CVariable<bool> mv_castShadowMaps;
|
||||
CVariable<bool> mv_recvShadowMaps;
|
||||
CVariable<bool> mv_castLightmap;
|
||||
CVariable<bool> mv_recvLightmap;
|
||||
CVariable<int> mv_ratioLOD;
|
||||
CVariable<int> mv_ratioViewDist;
|
||||
CVariable<int> mv_UpdateVisLevel;
|
||||
CVariable<bool> mv_hiddenInGame; // Entity is hidden in game (on start).
|
||||
CVariable<bool> mv_notOnLowSpec;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Temp variables (Not serializable) just to display radiuses from properties.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Used for proximity entities.
|
||||
float m_proximityRadius;
|
||||
float m_innerRadius;
|
||||
float m_outerRadius;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Event Targets.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Array of event targets of this Entity.
|
||||
typedef std::vector<CEntityEventTarget> EventTargets;
|
||||
EventTargets m_eventTargets;
|
||||
|
||||
//! Animation node, assigned to this object.
|
||||
TSmartPtr<IAnimNode> m_animNode;
|
||||
|
||||
//! Entity prototype. only used by EntityPrototypeObject.
|
||||
TSmartPtr<CEntityPrototype> m_prototype;
|
||||
|
||||
//! Per instance properties table.
|
||||
CVarBlockPtr m_properties2;
|
||||
|
||||
//! Entity Properties variables.
|
||||
CVarBlockPtr m_properties;
|
||||
|
||||
// Can keep reference to one track gizmo.
|
||||
CTrackGizmoPtr m_trackGizmo;
|
||||
|
||||
//! Material of this entity.
|
||||
TSmartPtr<CMaterial> m_pMaterial;
|
||||
GUID m_materialGUID;
|
||||
|
||||
// Physics state, as a string.
|
||||
CString m_physicsState;
|
||||
|
||||
|
||||
static int m_rollupId;
|
||||
static class CEntityPanel* m_panel;
|
||||
static float m_helperScale;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of Entity
|
||||
*/
|
||||
class CEntityClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {C80F8AEA-90EF-471f-82C7-D14FA80B9203}
|
||||
static const GUID guid = { 0xc80f8aea, 0x90ef, 0x471f, { 0x82, 0xc7, 0xd1, 0x4f, 0xa8, 0xb, 0x92, 0x3 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_ENTITY; };
|
||||
const char* ClassName() { return "StdEntity"; };
|
||||
const char* Category() { return ""; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CEntity); };
|
||||
const char* GetFileSpec() { return "*EntityClass"; };
|
||||
int GameCreationOrder() { return 200; };
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Simple entity.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CSimpleEntity : public CEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CSimpleEntity)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
bool ConvertFromObject( CBaseObject *object );
|
||||
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
|
||||
void Validate( CErrorReport *report );
|
||||
bool IsSimilarObject( CBaseObject *pObject );
|
||||
|
||||
private:
|
||||
CString GetGeometryFile() const;
|
||||
void SetGeometryFile( const CString &filename );
|
||||
void OnFileChange( CString filename );
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of Entity
|
||||
*/
|
||||
class CSimpleEntityClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {F7820713-E4EE-44b9-867C-C0F9543B4871}
|
||||
static const GUID guid = { 0xf7820713, 0xe4ee, 0x44b9, { 0x86, 0x7c, 0xc0, 0xf9, 0x54, 0x3b, 0x48, 0x71 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_ENTITY; };
|
||||
const char* ClassName() { return "SimpleEntity"; };
|
||||
const char* Category() { return "Simple Entity"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CSimpleEntity); };
|
||||
const char* GetFileSpec() { return "Objects\\*.cgf;*.ccgf;*.cga"; };
|
||||
int GameCreationOrder() { return 201; };
|
||||
};
|
||||
|
||||
#endif // __CEntity_h__
|
||||
939
Editor/Objects/EntityScript.cpp
Normal file
939
Editor/Objects/EntityScript.cpp
Normal file
@@ -0,0 +1,939 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: EntityScript.cpp
|
||||
// Version: v1.00
|
||||
// Created: 10/12/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: CEntityScript class implementation.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "EntityScript.h"
|
||||
#include "Entity.h"
|
||||
|
||||
#include <IScriptSystem.h>
|
||||
#include <IEntitySystem.h>
|
||||
#include <IGame.h>
|
||||
|
||||
struct CScriptMethodsDump : public IScriptObjectDumpSink
|
||||
{
|
||||
std::vector<CString> methods;
|
||||
std::vector<CString> events;
|
||||
virtual void OnElementFound(int nIdx,ScriptVarType type){}
|
||||
virtual void OnElementFound(const char *sName,ScriptVarType type)
|
||||
{
|
||||
if (type == svtFunction)
|
||||
{
|
||||
if (strncmp(sName,EVENT_PREFIX,6) == 0)
|
||||
events.push_back( sName+6 );
|
||||
else
|
||||
methods.push_back( sName );
|
||||
}/* else if (type == svtObject && stricmp(sName,PROPERTIES_TABLE)==0)
|
||||
{
|
||||
// Properties found.
|
||||
}
|
||||
*/
|
||||
}
|
||||
};
|
||||
|
||||
enum EScriptParamFlags
|
||||
{
|
||||
SCRIPTPARAM_POSITIVE = 0x01,
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static struct {
|
||||
const char *prefix;
|
||||
IVariable::EType type;
|
||||
IVariable::EDataType dataType;
|
||||
int flags;
|
||||
} s_paramTypes[] =
|
||||
{
|
||||
{ "n", IVariable::INT, IVariable::DT_SIMPLE, SCRIPTPARAM_POSITIVE },
|
||||
{ "i", IVariable::INT, IVariable::DT_SIMPLE,0 },
|
||||
{ "b", IVariable::BOOL, IVariable::DT_SIMPLE,0 },
|
||||
{ "f", IVariable::FLOAT, IVariable::DT_SIMPLE,0 },
|
||||
{ "s", IVariable::STRING, IVariable::DT_SIMPLE,0 },
|
||||
|
||||
{ "shader", IVariable::STRING, IVariable::DT_SHADER,0 },
|
||||
{ "clr", IVariable::VECTOR, IVariable::DT_COLOR,0 },
|
||||
{ "color", IVariable::VECTOR, IVariable::DT_COLOR,0 },
|
||||
|
||||
{ "vector", IVariable::VECTOR, IVariable::DT_SIMPLE,0 },
|
||||
|
||||
{ "snd", IVariable::STRING, IVariable::DT_SOUND,0 },
|
||||
{ "sound", IVariable::STRING, IVariable::DT_SOUND,0 },
|
||||
|
||||
{ "tex", IVariable::STRING, IVariable::DT_TEXTURE,0 },
|
||||
{ "texture", IVariable::STRING, IVariable::DT_TEXTURE,0 },
|
||||
|
||||
{ "obj", IVariable::STRING, IVariable::DT_OBJECT,0 },
|
||||
{ "object", IVariable::STRING, IVariable::DT_OBJECT,0 },
|
||||
|
||||
{ "file", IVariable::STRING, IVariable::DT_FILE,0 },
|
||||
{ "aibehavior", IVariable::STRING,IVariable::DT_AI_BEHAVIOR,0 },
|
||||
{ "aicharacter",IVariable::STRING,IVariable::DT_AI_CHARACTER,0 },
|
||||
|
||||
{ "text", IVariable::STRING, IVariable::DT_LOCAL_STRING,0 },
|
||||
{ "equip", IVariable::STRING, IVariable::DT_EQUIP,0 },
|
||||
{ "sndpreset",IVariable::STRING, IVariable::DT_SOUNDPRESET,0 },
|
||||
{ "eaxpreset",IVariable::STRING, IVariable::DT_EAXPRESET,0 },
|
||||
|
||||
{ "aianchor",IVariable::STRING,IVariable::DT_AI_ANCHOR,0 },
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct CScriptPropertiesDump : public IScriptObjectDumpSink
|
||||
{
|
||||
private:
|
||||
struct Variable {
|
||||
CString name;
|
||||
ScriptVarType type;
|
||||
};
|
||||
std::vector<Variable> m_elements;
|
||||
|
||||
CVarBlock *m_varBlock;
|
||||
IVariable *m_parentVar;
|
||||
|
||||
public:
|
||||
explicit CScriptPropertiesDump( CVarBlock *pVarBlock,IVariable *pParentVar=NULL )
|
||||
{
|
||||
m_varBlock = pVarBlock;
|
||||
m_parentVar = pParentVar;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
inline bool IsPropertyTypeMatch( const char *type,const char *name,int nameLen )
|
||||
{
|
||||
int typeLen = strlen(type);
|
||||
if (typeLen < nameLen)
|
||||
{
|
||||
// After type name Must follow Upper case or _.
|
||||
if (name[typeLen] != tolower(name[typeLen]) || name[typeLen] == '_' )
|
||||
{
|
||||
if (strncmp(name,type,strlen(type)) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IVariable* CreateVarByType( IVariable::EType type )
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case IVariable::FLOAT: return new CVariable<float>;
|
||||
case IVariable::INT: return new CVariable<int>;
|
||||
case IVariable::STRING: return new CVariable<CString>;
|
||||
case IVariable::BOOL: return new CVariable<bool>;
|
||||
case IVariable::VECTOR: return new CVariable<Vec3>;
|
||||
case IVariable::QUAT: return new CVariable<Quat>;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IVariable* CreateVar( const char *name,IVariable::EType defaultType,const char* &displayName )
|
||||
{
|
||||
displayName = name;
|
||||
// Resolve type from variable name.
|
||||
int nameLen = strlen(name);
|
||||
|
||||
// if starts from capital no type encoded.
|
||||
if (name[0] == tolower(name[0]))
|
||||
{
|
||||
// Try to detect type.
|
||||
for (int i = 0; i < sizeof(s_paramTypes)/sizeof(s_paramTypes[0]); i++)
|
||||
{
|
||||
if (IsPropertyTypeMatch(s_paramTypes[i].prefix,name,nameLen))
|
||||
{
|
||||
//if (s_paramTypes[i].type != var->GetType())
|
||||
//continue;
|
||||
displayName = name + strlen(s_paramTypes[i].prefix);
|
||||
if (displayName[0] == '_')
|
||||
displayName++;
|
||||
|
||||
IVariable *var = CreateVarByType(s_paramTypes[i].type);
|
||||
if (!var)
|
||||
continue;
|
||||
|
||||
var->SetName(name);
|
||||
var->SetHumanName(displayName);
|
||||
var->SetDataType(s_paramTypes[i].dataType);
|
||||
|
||||
if (s_paramTypes[i].flags & SCRIPTPARAM_POSITIVE)
|
||||
{
|
||||
float lmin=0,lmax=10000;
|
||||
var->GetLimits( lmin,lmax );
|
||||
// set min Limit to 0 to make it positive only value.
|
||||
var->SetLimits( 0,lmax );
|
||||
}
|
||||
return var;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (defaultType != IVariable::UNKNOWN)
|
||||
{
|
||||
IVariable *var = CreateVarByType(defaultType);
|
||||
var->SetName(name);
|
||||
return var;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void OnElementFound(int nIdx,ScriptVarType type)
|
||||
{
|
||||
/*ignore non string indexed values*/
|
||||
};
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void OnElementFound(const char *sName,ScriptVarType type)
|
||||
{
|
||||
if (sName && sName[0] != 0)
|
||||
{
|
||||
Variable var;
|
||||
var.name = sName;
|
||||
var.type = type;
|
||||
m_elements.push_back(var);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void Dump( IScriptObject *pObject )
|
||||
{
|
||||
m_elements.reserve(20);
|
||||
pObject->Dump( this );
|
||||
std::map<CString,IVariablePtr> nodes;
|
||||
std::map<CString,IVariablePtr> listNodes;
|
||||
|
||||
for (int i = 0; i < m_elements.size(); i++)
|
||||
{
|
||||
const char *sName = m_elements[i].name;
|
||||
ScriptVarType type = m_elements[i].type;
|
||||
|
||||
const char *sDisplayName = sName;
|
||||
|
||||
if (type == svtNumber)
|
||||
{
|
||||
float fVal;
|
||||
pObject->GetValue( sName,fVal );
|
||||
IVariable *var = CreateVar(sName,IVariable::FLOAT,sDisplayName);
|
||||
if (var)
|
||||
{
|
||||
var->Set(fVal);
|
||||
nodes[sDisplayName] = var;
|
||||
}
|
||||
} else if (type == svtString)
|
||||
{
|
||||
const char *sVal;
|
||||
pObject->GetValue( sName,sVal );
|
||||
IVariable *var = CreateVar(sName,IVariable::STRING,sDisplayName);
|
||||
if (var)
|
||||
{
|
||||
var->Set(sVal);
|
||||
nodes[sDisplayName] = var;
|
||||
}
|
||||
} else if (type == svtFunction)
|
||||
{
|
||||
// Ignore functions.
|
||||
} else if (type == svtObject)
|
||||
{
|
||||
// Some Table.
|
||||
_SmartScriptObject pTable(GetIEditor()->GetSystem()->GetIScriptSystem(),true);
|
||||
if (pObject->GetValue( sName,pTable ))
|
||||
{
|
||||
IVariable *var = CreateVar(sName,IVariable::UNKNOWN,sDisplayName);
|
||||
if (var && var->GetType() == IVariable::VECTOR)
|
||||
{
|
||||
nodes[sDisplayName] = var;
|
||||
float x,y,z;
|
||||
if (pTable->GetValue("x",x) && pTable->GetValue("y",y) && pTable->GetValue("z",z))
|
||||
{
|
||||
var->Set( Vec3(x,y,z) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pTable->GetAt(1,x);
|
||||
pTable->GetAt(2,y);
|
||||
pTable->GetAt(3,z);
|
||||
var->Set( Vec3(x,y,z) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var = new CVariableArray;
|
||||
var->SetName(sName);
|
||||
listNodes[sName] = var;
|
||||
|
||||
CScriptPropertiesDump dump(m_varBlock,var);
|
||||
dump.Dump( *pTable );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (std::map<CString,IVariablePtr>::iterator nit = nodes.begin(); nit != nodes.end(); nit++)
|
||||
{
|
||||
if (m_parentVar)
|
||||
m_parentVar->AddChildVar(nit->second);
|
||||
else
|
||||
m_varBlock->AddVariable(nit->second);
|
||||
}
|
||||
for (std::map<CString,IVariablePtr>::iterator nit1 = listNodes.begin(); nit1 != listNodes.end(); nit1++)
|
||||
{
|
||||
if (m_parentVar)
|
||||
m_parentVar->AddChildVar(nit1->second);
|
||||
else
|
||||
m_varBlock->AddVariable(nit1->second);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CEntityScript::CEntityScript( const EntityClassId ClassId,const char *sName,const char *sFile )
|
||||
{
|
||||
m_ClassId = ClassId;
|
||||
m_valid = false;
|
||||
m_haveEventsTable = false;
|
||||
m_standart = false;
|
||||
m_visibilityMask = 0;
|
||||
m_usable = false;
|
||||
|
||||
m_name = sName;
|
||||
m_file = sFile;
|
||||
m_relFile = sFile;
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CEntityScript::~CEntityScript()
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CEntityScript::GetEventCount()
|
||||
{
|
||||
//return sizeof(sEntityEvents)/sizeof(sEntityEvents[0]);
|
||||
return m_events.size();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CString CEntityScript::GetEvent( int i )
|
||||
{
|
||||
//return sEntityEvents[i].name;
|
||||
return m_events[i];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CEntityScript::Load()
|
||||
{
|
||||
m_valid = false;
|
||||
IGame *pGame = GetIEditor()->GetGame();
|
||||
EntityClass *entCls = pGame->GetClassRegistry()->GetByClassId( m_ClassId );
|
||||
if (!entCls)
|
||||
{
|
||||
m_valid = false;
|
||||
//Warning( "Load of entity script %s failed.",(const char*)m_name );
|
||||
|
||||
CErrorRecord err;
|
||||
err.error.Format( "Entity Script %s Failed to Load",(const char*)m_name );
|
||||
err.file = m_relFile;
|
||||
err.severity = CErrorRecord::ESEVERITY_WARNING;
|
||||
err.flags = CErrorRecord::FLAG_SCRIPT;
|
||||
GetIEditor()->GetErrorReport()->ReportError(err);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_standart = entCls->bReserved;
|
||||
m_relFile = entCls->strScriptFile.c_str();
|
||||
m_file = entCls->strFullScriptFile.c_str();
|
||||
m_ClassId = entCls->ClassId;
|
||||
|
||||
if (m_file.IsEmpty())
|
||||
{
|
||||
m_valid = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return ParseScript();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CEntityScript::ParseScript()
|
||||
{
|
||||
// Parse .lua file.
|
||||
IScriptSystem *script = GetIEditor()->GetSystem()->GetIScriptSystem();
|
||||
|
||||
_SmartScriptObject pEntity(script,true);
|
||||
if (!script->GetGlobalValue( m_name,*pEntity ))
|
||||
return false;
|
||||
|
||||
m_valid = true;
|
||||
|
||||
CScriptMethodsDump dump;
|
||||
pEntity->Dump( &dump );
|
||||
m_methods = dump.methods;
|
||||
m_events = dump.events;
|
||||
|
||||
//! Sort methods and events.
|
||||
std::sort( m_methods.begin(),m_methods.end() );
|
||||
std::sort( m_events.begin(),m_events.end() );
|
||||
|
||||
{
|
||||
// Normal properties.
|
||||
m_properties = 0;
|
||||
_SmartScriptObject pProps(script,true);
|
||||
if (pEntity->GetValue( PROPERTIES_TABLE,*pProps ))
|
||||
{
|
||||
// Properties found in entity.
|
||||
m_properties = new CVarBlock;
|
||||
CScriptPropertiesDump dump(m_properties);
|
||||
dump.Dump( *pProps );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Second set of properties.
|
||||
m_properties2 = 0;
|
||||
_SmartScriptObject pProps(script,true);
|
||||
if (pEntity->GetValue( PROPERTIES2_TABLE,*pProps ))
|
||||
{
|
||||
// Properties found in entity.
|
||||
m_properties2 = new CVarBlock;
|
||||
CScriptPropertiesDump dump(m_properties2);
|
||||
dump.Dump( *pProps );
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy variable block if empty.
|
||||
if (m_properties != 0 && m_properties->GetVarsCount() < 1)
|
||||
m_properties = 0;
|
||||
|
||||
// Destroy variable block if empty.
|
||||
if (m_properties2 != 0 && m_properties2->GetVarsCount() < 1)
|
||||
m_properties2 = 0;
|
||||
|
||||
// Load visual object.
|
||||
_SmartScriptObject pEditorTable(script,true);
|
||||
if (pEntity->GetValue( "Editor",*pEditorTable ))
|
||||
{
|
||||
const char *modelName;
|
||||
if (pEditorTable->GetValue( "Model",modelName ))
|
||||
{
|
||||
m_visualObject = modelName;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEntityScript::Reload()
|
||||
{
|
||||
// First try compiling script and see if it have any errors.
|
||||
bool bLoadScript = CFileUtil::CompileLuaFile( GetFile() );
|
||||
|
||||
if (bLoadScript)
|
||||
{
|
||||
EntityClass *entCls = GetIEditor()->GetGame()->GetClassRegistry()->GetByClassId( m_ClassId );
|
||||
if (entCls)
|
||||
{
|
||||
entCls->bLoaded = false;
|
||||
}
|
||||
else
|
||||
bLoadScript = false;
|
||||
}
|
||||
|
||||
if (bLoadScript)
|
||||
{
|
||||
// Script compiled succesfully.
|
||||
Load();/*
|
||||
if (GetIEditor()->GetSystem()->GetIScriptSystem()->ReloadScript( GetFile(),false ))
|
||||
{
|
||||
ParseScript();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEntityScript::GotoMethod( const CString &method )
|
||||
{
|
||||
CString line;
|
||||
line.Format( "%s:%s",(const char*)GetName(),(const char*)method );
|
||||
|
||||
// Search this line in script file.
|
||||
int lineNum = FindLineNum( line );
|
||||
if (lineNum >= 0)
|
||||
{
|
||||
// Open UltraEdit32 with this line.
|
||||
CFileUtil::EditTextFile( GetFile(),lineNum );
|
||||
}
|
||||
}
|
||||
|
||||
void CEntityScript::AddMethod( const CString &method )
|
||||
{
|
||||
// Add a new method to the file. and start Editing it.
|
||||
FILE *f = fopen( GetFile(),"at" );
|
||||
if (f)
|
||||
{
|
||||
fprintf( f,"\n" );
|
||||
fprintf( f,"-------------------------------------------------------\n" );
|
||||
fprintf( f,"function %s:%s()\n",(const char*)m_name,(const char*)method );
|
||||
fprintf( f,"end\n" );
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CEntityScript::FindLineNum( const CString &line )
|
||||
{
|
||||
FILE *f = fopen( GetFile(),"rb" );
|
||||
if (!f)
|
||||
return -1;
|
||||
|
||||
int lineFound = -1;
|
||||
int lineNum = 1;
|
||||
|
||||
fseek( f,0,SEEK_END );
|
||||
int size = ftell(f);
|
||||
fseek( f,0,SEEK_SET );
|
||||
|
||||
char *text = new char[size+16];
|
||||
fread( text,size,1,f );
|
||||
text[size] = 0;
|
||||
|
||||
char *token = strtok( text,"\n" );
|
||||
while (token)
|
||||
{
|
||||
if (strstr( token,line ) != 0)
|
||||
{
|
||||
lineFound = lineNum;
|
||||
break;
|
||||
}
|
||||
token = strtok( NULL,"\n" );
|
||||
lineNum++;
|
||||
}
|
||||
fclose(f);
|
||||
delete []text;
|
||||
|
||||
return lineFound;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEntityScript::SetProperties( IEntity *ientity,CVarBlock *vars,bool bCallUpdate )
|
||||
{
|
||||
if (!IsValid())
|
||||
return;
|
||||
|
||||
assert( ientity != 0 );
|
||||
assert( vars != 0 );
|
||||
|
||||
IScriptObject *scriptObject = ientity->GetScriptObject();
|
||||
if (!scriptObject)
|
||||
return;
|
||||
|
||||
IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
|
||||
|
||||
_SmartScriptObject pProperties( scriptSystem,true);
|
||||
if (!scriptObject->GetValue( PROPERTIES_TABLE,*pProperties ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < vars->GetVarsCount(); i++)
|
||||
{
|
||||
VarToScriptObject( vars->GetVariable(i),pProperties );
|
||||
}
|
||||
|
||||
if (bCallUpdate)
|
||||
{
|
||||
HSCRIPTFUNCTION pf;
|
||||
if (scriptObject->GetValue( "OnPropertyChange",pf ))
|
||||
{
|
||||
scriptSystem->BeginCall(pf);
|
||||
scriptSystem->PushFuncParam(scriptObject);
|
||||
scriptSystem->EndCall();
|
||||
//Alberto
|
||||
scriptSystem->ReleaseFunc(pf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEntityScript::SetProperties2( IEntity *ientity,CVarBlock *vars,bool bCallUpdate )
|
||||
{
|
||||
if (!IsValid())
|
||||
return;
|
||||
|
||||
assert( ientity != 0 );
|
||||
assert( vars != 0 );
|
||||
|
||||
IScriptObject *scriptObject = ientity->GetScriptObject();
|
||||
if (!scriptObject)
|
||||
return;
|
||||
|
||||
IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
|
||||
|
||||
_SmartScriptObject pProperties( scriptSystem,true);
|
||||
if (!scriptObject->GetValue( PROPERTIES2_TABLE,*pProperties ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < vars->GetVarsCount(); i++)
|
||||
{
|
||||
VarToScriptObject( vars->GetVariable(i),pProperties );
|
||||
}
|
||||
|
||||
if (bCallUpdate)
|
||||
{
|
||||
HSCRIPTFUNCTION pf;
|
||||
if (scriptObject->GetValue( "OnPropertyChange",pf ))
|
||||
{
|
||||
scriptSystem->BeginCall(pf);
|
||||
scriptSystem->PushFuncParam(scriptObject);
|
||||
scriptSystem->EndCall();
|
||||
//Alberto
|
||||
scriptSystem->ReleaseFunc(pf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEntityScript::VarToScriptObject( IVariable *var,IScriptObject *obj )
|
||||
{
|
||||
assert(var);
|
||||
|
||||
if (var->GetType() == IVariable::ARRAY)
|
||||
{
|
||||
int type = obj->GetValueType( var->GetName() );
|
||||
if (type != svtObject)
|
||||
return;
|
||||
|
||||
IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
|
||||
_SmartScriptObject pTableObj( scriptSystem,true );
|
||||
if (obj->GetValue( var->GetName(),*pTableObj ))
|
||||
{
|
||||
for (int i = 0; i < var->NumChildVars(); i++)
|
||||
{
|
||||
IVariable *child = var->GetChildVar(i);
|
||||
VarToScriptObject( child,pTableObj );
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const char *name = var->GetName();
|
||||
int type = obj->GetValueType( name );
|
||||
|
||||
if (type == svtString)
|
||||
{
|
||||
CString value;
|
||||
var->Get(value);
|
||||
obj->SetValue( name,value );
|
||||
}
|
||||
else if (type == svtNumber)
|
||||
{
|
||||
float val = 0;
|
||||
var->Get(val);
|
||||
obj->SetValue( name,val );
|
||||
}
|
||||
else if (type == svtObject)
|
||||
{
|
||||
IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
|
||||
// Probably Color/Vector.
|
||||
_SmartScriptObject pTable( scriptSystem,true );
|
||||
if (obj->GetValue( name,pTable ))
|
||||
{
|
||||
if (var->GetType() == IVariable::VECTOR)
|
||||
{
|
||||
Vec3 vec;
|
||||
var->Get(vec);
|
||||
|
||||
float temp;
|
||||
if (pTable->GetValue( "x",temp ))
|
||||
{
|
||||
// Named vector.
|
||||
pTable->SetValue( "x",vec.x );
|
||||
pTable->SetValue( "y",vec.y );
|
||||
pTable->SetValue( "z",vec.z );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Indexed vector.
|
||||
pTable->SetAt(1,vec.x);
|
||||
pTable->SetAt(2,vec.y);
|
||||
pTable->SetAt(3,vec.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEntityScript::RunMethod( IEntity *ientity,const CString &method )
|
||||
{
|
||||
if (!IsValid())
|
||||
return;
|
||||
|
||||
assert( ientity != 0 );
|
||||
|
||||
IScriptObject *scriptObject = ientity->GetScriptObject();
|
||||
if (!scriptObject)
|
||||
return;
|
||||
|
||||
IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
|
||||
|
||||
scriptSystem->BeginCall( GetName(),method );
|
||||
scriptSystem->PushFuncParam( scriptObject );
|
||||
scriptSystem->EndCall();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEntityScript::SendEvent( IEntity *entity,const CString &method )
|
||||
{
|
||||
RunMethod( entity,CString(EVENT_PREFIX)+method );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEntityScript::SetEventsTable( CEntity *entity )
|
||||
{
|
||||
if (!IsValid())
|
||||
return;
|
||||
assert( entity != 0 );
|
||||
|
||||
IEntity *ientity = entity->GetIEntity();
|
||||
if (!ientity)
|
||||
return;
|
||||
|
||||
IScriptObject *scriptObject = ientity->GetScriptObject();
|
||||
if (!scriptObject)
|
||||
return;
|
||||
|
||||
// If events target table is null, set event table to null either.
|
||||
if (entity->GetEventTargetCount() == 0)
|
||||
{
|
||||
if (m_haveEventsTable)
|
||||
{
|
||||
scriptObject->SetToNull( "Events" );
|
||||
}
|
||||
m_haveEventsTable = false;
|
||||
return;
|
||||
}
|
||||
|
||||
IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
|
||||
_SmartScriptObject pEvents( scriptSystem,false );
|
||||
|
||||
scriptObject->SetValue( "Events",*pEvents );
|
||||
m_haveEventsTable = true;
|
||||
|
||||
std::set<CString> sourceEvents;
|
||||
for (int i = 0; i < entity->GetEventTargetCount(); i++)
|
||||
{
|
||||
CEntityEventTarget &et = entity->GetEventTarget(i);
|
||||
sourceEvents.insert( et.sourceEvent );
|
||||
}
|
||||
for (std::set<CString>::iterator it = sourceEvents.begin(); it != sourceEvents.end(); it++)
|
||||
{
|
||||
_SmartScriptObject pTrgEvents( scriptSystem,false );
|
||||
CString sourceEvent = *it;
|
||||
|
||||
//int srcEventId = EventNameToId( sourceEvent );
|
||||
//pEvents->SetAt( srcEventId,*pTrgEvents );
|
||||
pEvents->SetValue( sourceEvent,*pTrgEvents );
|
||||
|
||||
// Put target events to table.
|
||||
int trgEventIndex = 1;
|
||||
for (int i = 0; i < entity->GetEventTargetCount(); i++)
|
||||
{
|
||||
CEntityEventTarget &et = entity->GetEventTarget(i);
|
||||
if (stricmp(et.sourceEvent,sourceEvent) == 0)
|
||||
{
|
||||
int entityId = 0;
|
||||
if (et.target)
|
||||
{
|
||||
if (et.target->IsKindOf( RUNTIME_CLASS(CEntity) ))
|
||||
entityId = ((CEntity*)et.target)->GetEntityId();
|
||||
}
|
||||
|
||||
_SmartScriptObject pTrgEvent( scriptSystem,false );
|
||||
pTrgEvents->SetAt( trgEventIndex,*pTrgEvent );
|
||||
trgEventIndex++;
|
||||
|
||||
pTrgEvent->SetAt( 1,entityId );
|
||||
pTrgEvent->SetAt( 2,et.event );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CEntityScriptRegistry implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CEntityScriptRegistry* CEntityScriptRegistry::m_instance = 0;
|
||||
|
||||
CEntityScriptRegistry::CEntityScriptRegistry()
|
||||
{
|
||||
m_instance = this;
|
||||
}
|
||||
|
||||
CEntityScriptRegistry::~CEntityScriptRegistry()
|
||||
{
|
||||
m_instance = 0;
|
||||
m_scripts.Clear();
|
||||
}
|
||||
|
||||
CEntityScript* CEntityScriptRegistry::Find( const CString &name )
|
||||
{
|
||||
CEntityScriptPtr script = 0;
|
||||
if (m_scripts.Find( name,script ))
|
||||
{
|
||||
return script;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CEntityScriptRegistry::Insert( CEntityScript *script )
|
||||
{
|
||||
// Check if inserting already exist script, if so ignore.
|
||||
CEntityScriptPtr temp;
|
||||
if (m_scripts.Find( script->GetName(),temp ))
|
||||
{
|
||||
Error( "Inserting duplicate Entity Script %s",(const char*)script->GetName() );
|
||||
return;
|
||||
}
|
||||
m_scripts[script->GetName()] = script;
|
||||
}
|
||||
|
||||
void CEntityScriptRegistry::GetScripts( std::vector<CEntityScript*> &scripts )
|
||||
{
|
||||
std::vector<CEntityScriptPtr> s;
|
||||
m_scripts.GetAsVector( s );
|
||||
|
||||
scripts.resize( s.size() );
|
||||
for (int i = 0; i < s.size(); i++)
|
||||
{
|
||||
scripts[i] = s[i];
|
||||
}
|
||||
}
|
||||
|
||||
void CEntityScriptRegistry::LoadScripts()
|
||||
{
|
||||
IGame *game = GetIEditor()->GetGame();
|
||||
if (!game)
|
||||
return;
|
||||
|
||||
m_scripts.Clear();
|
||||
|
||||
EntityClass *entCls;
|
||||
// Enumerate entity classes inside Game.
|
||||
game->GetClassRegistry()->MoveFirst();
|
||||
do {
|
||||
entCls = game->GetClassRegistry()->Next();
|
||||
if (entCls)
|
||||
{
|
||||
CEntityScript *script = new CEntityScript( entCls->ClassId,entCls->strClassName.c_str(),entCls->strScriptFile.c_str() );
|
||||
if (!entCls->strScriptFile.empty())
|
||||
script->SetUsable( true );
|
||||
Insert( script );
|
||||
}
|
||||
} while (entCls);
|
||||
|
||||
/*
|
||||
int lastClassId = FIRST_ENTITY_CLASS_ID;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Load class registry.
|
||||
// Enumerate all XML files in Editor\ subfolder to look for EntityRegistry.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CString masterCD = GetIEditor()->GetMasterCDFolder();
|
||||
std::vector<CFileUtil::FileDesc> files;
|
||||
CString dir = Path::AddBackslash(masterCD) + "Editor\\";
|
||||
CFileUtil::ScanDirectory( dir,"*.xml",files,false );
|
||||
|
||||
XmlParser parser;
|
||||
|
||||
FILE *file;
|
||||
file = fopen( "Scripts\\classreg1.lua","wt" );
|
||||
|
||||
for (int k = 0; k < files.size(); k++)
|
||||
{
|
||||
// Construct the full filepath of the current file
|
||||
XmlNodeRef registry = parser.parse( dir + files[k].filename );
|
||||
if (registry != 0 && registry->isTag("EntityRegistry"))
|
||||
{
|
||||
for (int i = 0; i < registry->getChildCount(); i++)
|
||||
{
|
||||
XmlNodeRef child = registry->getChild(i);
|
||||
if (child->isTag("EntityDesc"))
|
||||
{
|
||||
const char *fname = child->getAttr( "File" );
|
||||
const char *tableName = child->getAttr( "Name" );
|
||||
// Save new format.
|
||||
fprintf( file,"\t{ \"\",\t\"%s\",\t%.3d,\t\"%s\" },\n",tableName,i+100,fname );
|
||||
|
||||
|
||||
CString file,name;
|
||||
int clsId;
|
||||
if (child->getAttr( "File",file ) &&
|
||||
child->getAttr( "Name",name ))
|
||||
{
|
||||
clsId = lastClassId++;
|
||||
|
||||
CEntityScript* script = Find(name);
|
||||
if (script)
|
||||
{
|
||||
script->Invalidate();
|
||||
}
|
||||
else
|
||||
{
|
||||
script = new CEntityScript( clsId,name,file );
|
||||
|
||||
// Only scripts from entity registry can be used.
|
||||
script->SetUsable( true );
|
||||
Insert( script );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose( file );
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CEntityScriptRegistry* CEntityScriptRegistry::Instance()
|
||||
{
|
||||
if (!m_instance)
|
||||
{
|
||||
m_instance = new CEntityScriptRegistry;
|
||||
}
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEntityScriptRegistry::Release()
|
||||
{
|
||||
if (m_instance)
|
||||
{
|
||||
delete m_instance;
|
||||
}
|
||||
m_instance = 0;
|
||||
}
|
||||
160
Editor/Objects/EntityScript.h
Normal file
160
Editor/Objects/EntityScript.h
Normal file
@@ -0,0 +1,160 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: EntityScript.h
|
||||
// Version: v1.00
|
||||
// Created: 10/12/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: EntityScript definition.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __EntityScript_h__
|
||||
#define __EntityScript_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "IEntitySystem.h" // EntityClassId
|
||||
|
||||
#define PROPERTIES_TABLE "Properties"
|
||||
#define PROPERTIES2_TABLE "PropertiesInstance"
|
||||
#define FIRST_ENTITY_CLASS_ID 200
|
||||
|
||||
// forward declaration
|
||||
class CEntity;
|
||||
struct IScriptObject;
|
||||
|
||||
#define EVENT_PREFIX "Event_"
|
||||
|
||||
/*!
|
||||
* CEntityScript holds information about Entity lua script.
|
||||
*/
|
||||
class CEntityScript : public CRefCountBase
|
||||
{
|
||||
public:
|
||||
CEntityScript( const EntityClassId ClassId,const char *sName,const char *sFile );
|
||||
virtual ~CEntityScript();
|
||||
|
||||
//! Get name of entity script.
|
||||
const CString& GetName() const { return m_name; }
|
||||
const CString& GetFile() const { return m_file; }
|
||||
const CString& GetRelativeFile() const { return m_relFile; }
|
||||
EntityClassId GetClsId() const { return m_ClassId; };
|
||||
|
||||
int GetMethodCount() const { return m_methods.size(); }
|
||||
const CString& GetMethod( int index ) const { return m_methods[index]; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int GetEventCount();
|
||||
CString GetEvent( int i );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Get properties of this sacript.
|
||||
CVarBlock* GetProperties() const { return m_properties; }
|
||||
CVarBlock* GetProperties2() const { return m_properties2; }
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Load();
|
||||
void Reload();
|
||||
bool IsValid() const { return m_valid; };
|
||||
|
||||
//! Marks script not valid, must be loaded on next access.
|
||||
void Invalidate() { m_valid = false; };
|
||||
|
||||
//! Takes current values of properties from Entity and put it to entity table.
|
||||
void SetProperties( IEntity *entity,CVarBlock *properties,bool bCallUpdate );
|
||||
void SetProperties2( IEntity *entity,CVarBlock *properties,bool bCallUpdate );
|
||||
|
||||
//! Setup entity target events table
|
||||
void SetEventsTable( CEntity *entity );
|
||||
|
||||
//! Run method.
|
||||
void RunMethod( IEntity *entity,const CString &method );
|
||||
void SendEvent( IEntity *entity,const CString &event );
|
||||
|
||||
// Edit methods.
|
||||
void GotoMethod( const CString &method );
|
||||
void AddMethod( const CString &method );
|
||||
|
||||
//! Get visual object for this entity script.
|
||||
const CString& GetVisualObject() { return m_visualObject; };
|
||||
|
||||
//! Is Standart class
|
||||
bool IsStandart() const { return m_standart; };
|
||||
int GetVisibilityMask() const { return m_visibilityMask; };
|
||||
|
||||
//! Check if entity of this class can be used in editor.
|
||||
bool IsUsable() const { return m_usable; }
|
||||
|
||||
// Set class as placable or not.
|
||||
void SetUsable( bool usable ) { m_usable = usable; }
|
||||
|
||||
private:
|
||||
bool ParseScript();
|
||||
int FindLineNum( const CString &line );
|
||||
|
||||
//! Put var block to script properties.
|
||||
void VarToScriptObject( IVariable *var,IScriptObject *obj );
|
||||
|
||||
CString m_name;
|
||||
CString m_file;
|
||||
CString m_relFile;
|
||||
EntityClassId m_ClassId;
|
||||
bool m_valid;
|
||||
//! True if standart entity class.
|
||||
bool m_standart;
|
||||
|
||||
bool m_haveEventsTable;
|
||||
|
||||
//! True if entity script have update entity
|
||||
bool m_bUpdatePropertiesImplemented;
|
||||
|
||||
CString m_visualObject;
|
||||
int m_visibilityMask;
|
||||
|
||||
bool m_usable;
|
||||
|
||||
//! Array of methods in this script.
|
||||
std::vector<CString> m_methods;
|
||||
|
||||
//! Array of events supported by this script.
|
||||
std::vector<CString> m_events;
|
||||
|
||||
TSmartPtr<CVarBlock> m_properties;
|
||||
TSmartPtr<CVarBlock> m_properties2;
|
||||
};
|
||||
|
||||
typedef TSmartPtr<CEntityScript> CEntityScriptPtr;
|
||||
|
||||
/*!
|
||||
* CEntityScriptRegistry manages all known CEntityScripts instances.
|
||||
*/
|
||||
class CEntityScriptRegistry
|
||||
{
|
||||
public:
|
||||
CEntityScriptRegistry();
|
||||
~CEntityScriptRegistry();
|
||||
|
||||
CEntityScript* Find( const CString &name );
|
||||
void Insert( CEntityScript *script );
|
||||
|
||||
void LoadScripts();
|
||||
|
||||
//! Get all scripts as array.
|
||||
void GetScripts( std::vector<CEntityScript*> &scripts );
|
||||
|
||||
static CEntityScriptRegistry* Instance();
|
||||
static void Release();
|
||||
|
||||
private:
|
||||
StdMap<CString,CEntityScriptPtr> m_scripts;
|
||||
static CEntityScriptRegistry* m_instance;
|
||||
};
|
||||
|
||||
#endif // __EntityScript_h__
|
||||
54
Editor/Objects/Gizmo.cpp
Normal file
54
Editor/Objects/Gizmo.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: gizmo.cpp
|
||||
// Version: v1.00
|
||||
// Created: 2/7/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "Gizmo.h"
|
||||
|
||||
#include "ObjectManager.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CGizmo implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CGizmo::CGizmo()
|
||||
{
|
||||
m_bDelete = false;
|
||||
m_matrix.SetIdentity();
|
||||
m_flags = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CGizmo::~CGizmo()
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGizmo::SetMatrix( const Matrix44 &tm )
|
||||
{
|
||||
m_matrix = tm;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IGizmoManager* CGizmo::GetGizmoManager() const
|
||||
{
|
||||
return GetIEditor()->GetObjectManager()->GetGizmoManager();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGizmo::DeleteThis()
|
||||
{
|
||||
m_bDelete = true;
|
||||
};
|
||||
87
Editor/Objects/Gizmo.h
Normal file
87
Editor/Objects/Gizmo.h
Normal file
@@ -0,0 +1,87 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: gizmo.h
|
||||
// Version: v1.00
|
||||
// Created: 2/7/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __gizmo_h__
|
||||
#define __gizmo_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// forward declarations.
|
||||
struct DisplayContext;
|
||||
struct HitContext;
|
||||
struct IGizmoManager;
|
||||
|
||||
enum EGizmoFlags
|
||||
{
|
||||
EGIZMO_SELECTABLE = 0x0001, //! If set gizmo can be selected by clicking.
|
||||
EGIZMO_HIDDEN = 0x0002, //! If set gizmo hidden and should not be displayed.
|
||||
};
|
||||
|
||||
/** Any helper object that BaseObjects can use to display some usefull information like tracks.
|
||||
Gizmo's life time should be controlled by thier owning BaseObjects.
|
||||
*/
|
||||
class CGizmo : public CRefCountBase
|
||||
{
|
||||
public:
|
||||
CGizmo();
|
||||
~CGizmo();
|
||||
|
||||
//! Set gizmo object flags.
|
||||
void SetFlags( uint flags ) { m_flags = flags; }
|
||||
//! Get gizmo object flags.
|
||||
uint GetFlags() const { return m_flags; }
|
||||
|
||||
/** Get bounding box of Gizmo in world space.
|
||||
@param bbox Returns bounding box.
|
||||
*/
|
||||
virtual void GetWorldBounds( BBox &bbox ) = 0;
|
||||
|
||||
/** Set transformation matrix of this gizmo.
|
||||
*/
|
||||
virtual void SetMatrix( const Matrix44 &tm );
|
||||
|
||||
/** Get transformation matrix of this gizmo.
|
||||
*/
|
||||
virtual const Matrix44& GetMatrix() const { return m_matrix; }
|
||||
|
||||
/** Display Gizmo in the viewport.
|
||||
*/
|
||||
virtual void Display( DisplayContext &dc ) = 0;
|
||||
|
||||
/** Performs hit testing on gizmo object.
|
||||
*/
|
||||
virtual bool HitTest( HitContext &hc ) { return false; };
|
||||
|
||||
/** Return gizmo manager that owns this gizmo.
|
||||
*/
|
||||
IGizmoManager* GetGizmoManager() const;
|
||||
|
||||
//! Is this gizmo need to be deleted?.
|
||||
bool IsDelete() const { return m_bDelete; }
|
||||
//! Set this gizmo to be deleted.
|
||||
void DeleteThis();
|
||||
|
||||
protected:
|
||||
Matrix44 m_matrix;
|
||||
bool m_bDelete; // This gizmo is marked for deletion.
|
||||
uint m_flags;
|
||||
};
|
||||
|
||||
// Define CGizmoPtr smart pointer.
|
||||
SMARTPTR_TYPEDEF(CGizmo);
|
||||
|
||||
#endif // __gizmo_h__
|
||||
88
Editor/Objects/GizmoManager.cpp
Normal file
88
Editor/Objects/GizmoManager.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: gizmomanager.cpp
|
||||
// Version: v1.00
|
||||
// Created: 2/7/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "GizmoManager.h"
|
||||
#include "DisplayContext.h"
|
||||
#include "ObjectManager.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGizmoManager::Display( DisplayContext &dc )
|
||||
{
|
||||
FUNCTION_PROFILER( GetIEditor()->GetSystem(),PROFILE_EDITOR );
|
||||
|
||||
BBox bbox;
|
||||
std::vector<CGizmo*> todelete;
|
||||
for (Gizmos::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
|
||||
{
|
||||
CGizmo *gizmo = *it;
|
||||
if (gizmo->GetFlags() & EGIZMO_HIDDEN)
|
||||
continue;
|
||||
|
||||
gizmo->GetWorldBounds( bbox );
|
||||
if (dc.IsVisible(bbox))
|
||||
{
|
||||
gizmo->Display( dc );
|
||||
}
|
||||
|
||||
if (gizmo->IsDelete())
|
||||
todelete.push_back(gizmo);
|
||||
}
|
||||
|
||||
// Delete gizmos that needs deletion.
|
||||
for (int i = 0; i < todelete.size(); i++)
|
||||
{
|
||||
RemoveGizmo(todelete[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGizmoManager::AddGizmo( CGizmo *gizmo )
|
||||
{
|
||||
m_gizmos.insert( gizmo );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGizmoManager::RemoveGizmo( CGizmo *gizmo )
|
||||
{
|
||||
m_gizmos.erase( gizmo );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CGizmoManager::HitTest( HitContext &hc )
|
||||
{
|
||||
float mindist = FLT_MAX;
|
||||
|
||||
HitContext ghc = hc;
|
||||
|
||||
BBox bbox;
|
||||
for (Gizmos::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
|
||||
{
|
||||
CGizmo *gizmo = *it;
|
||||
|
||||
if (gizmo->GetFlags() & EGIZMO_SELECTABLE)
|
||||
{
|
||||
if (gizmo->HitTest( ghc ))
|
||||
{
|
||||
if (ghc.dist < mindist)
|
||||
{
|
||||
mindist = ghc.dist;
|
||||
hc = ghc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return hc.object != 0;
|
||||
};
|
||||
42
Editor/Objects/GizmoManager.h
Normal file
42
Editor/Objects/GizmoManager.h
Normal file
@@ -0,0 +1,42 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: gizmomanager.h
|
||||
// Version: v1.00
|
||||
// Created: 2/7/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __gizmomanager_h__
|
||||
#define __gizmomanager_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "IGizmoManager.h"
|
||||
#include "Gizmo.h"
|
||||
|
||||
/** GizmoManager manages set of currently active Gizmo objects.
|
||||
*/
|
||||
class CGizmoManager : public IGizmoManager
|
||||
{
|
||||
public:
|
||||
void AddGizmo( CGizmo *gizmo );
|
||||
void RemoveGizmo( CGizmo *gizmo );
|
||||
|
||||
void Display( DisplayContext &dc );
|
||||
bool HitTest( HitContext &hc );
|
||||
|
||||
private:
|
||||
typedef std::set<CGizmoPtr> Gizmos;
|
||||
Gizmos m_gizmos;
|
||||
};
|
||||
|
||||
#endif // __gizmomanager_h__
|
||||
692
Editor/Objects/Group.cpp
Normal file
692
Editor/Objects/Group.cpp
Normal file
@@ -0,0 +1,692 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: Group.cpp
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: CGroup implementation.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "Group.h"
|
||||
|
||||
#include "ObjectManager.h"
|
||||
|
||||
#include "..\Viewport.h"
|
||||
#include "..\DisplaySettings.h"
|
||||
|
||||
int CGroup::s_groupGeomMergeId = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CBase implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CGroup,CBaseObject)
|
||||
|
||||
/*
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
class CUndoGroupChildsObject : public IUndoObject
|
||||
{
|
||||
public:
|
||||
CUndoGroupChildsObject( CGroup *grp,const char *undoDescription )
|
||||
{
|
||||
// Stores the current state of this object.
|
||||
assert( grp != 0 );
|
||||
m_undoDescription = undoDescription;
|
||||
m_objectId = grp->GetId();
|
||||
for (int i = 0; i < grp->GetChildCount(); i++)
|
||||
m_undo.push_back( grp->GetChild(i)->GetId() );
|
||||
}
|
||||
protected:
|
||||
virtual void Release() { delete this; };
|
||||
virtual int GetSize()
|
||||
{
|
||||
return sizeof(*this) + m_undo.size()*sizeof(int)+ m_redo.size()*sizeof(int) + m_undoDescription.GetLength();
|
||||
}
|
||||
virtual const char* GetDescription() { return m_undoDescription; };
|
||||
|
||||
virtual void Undo( bool bUndo )
|
||||
{
|
||||
CGroup *grp = (CGroup*)GetIEditor()->GetObjectManager()->FindObject( m_objectId );
|
||||
if (!grp || grp->GetType() != OBJTYPE_GROUP)
|
||||
return;
|
||||
|
||||
GetIEditor()->SuspendUndo();
|
||||
if (bUndo)
|
||||
{
|
||||
m_redo.clear();
|
||||
// Save current object state.
|
||||
for (int i = 0; i < grp->GetChildCount(); i++)
|
||||
m_redo.push_back( grp->GetChild(i)->GetId() );
|
||||
}
|
||||
|
||||
grp->DetachAll();
|
||||
// Undo object state.
|
||||
for (int i = 0; i < m_undo.size(); i++)
|
||||
{
|
||||
CBaseObject *obj = GetIEditor()->GetObjectManager()->FindObject( m_undo[i] );
|
||||
if (obj)
|
||||
grp->AddChild( obj );
|
||||
}
|
||||
|
||||
GetIEditor()->ResumeUndo();
|
||||
}
|
||||
virtual void Redo()
|
||||
{
|
||||
CGroup *grp = (CGroup*)GetIEditor()->GetObjectManager()->FindObject( m_objectId );
|
||||
if (!grp || grp->GetType() != OBJTYPE_GROUP)
|
||||
return;
|
||||
|
||||
GetIEditor()->SuspendUndo();
|
||||
|
||||
grp->RemoveAllChilds();
|
||||
// Redo object state.
|
||||
for (int i = 0; i < m_redo.size(); i++)
|
||||
{
|
||||
CBaseObject *obj = GetIEditor()->GetObjectManager()->FindObject( m_redo[i] );
|
||||
if (obj)
|
||||
grp->AddChild( obj );
|
||||
}
|
||||
|
||||
GetIEditor()->ResumeUndo();
|
||||
}
|
||||
|
||||
private:
|
||||
CString m_undoDescription;
|
||||
int m_objectId;
|
||||
std::vector<int> m_undo;
|
||||
std::vector<int> m_redo;
|
||||
};
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CGroup::CGroup()
|
||||
{
|
||||
m_opened = false;
|
||||
m_bAlwaysDrawBox = true;
|
||||
m_ignoreChildModify = false;
|
||||
m_bbox.min = m_bbox.max = Vec3(0,0,0);
|
||||
m_bBBoxValid = false;
|
||||
SetColor( RGB(0,255,0) ); // Green
|
||||
|
||||
m_geomMergeId = ++s_groupGeomMergeId;
|
||||
AddVariable( mv_mergeStaticGeom,"MergeGeom",_T("Merge Static Geometry"),functor(*this,&CGroup::OnMergeStaticGeom) );
|
||||
}
|
||||
|
||||
inline void RecursivelyGetAllChilds( CBaseObject *obj,std::vector<CBaseObjectPtr> &childs )
|
||||
{
|
||||
for (int i = 0; i < obj->GetChildCount(); i++)
|
||||
{
|
||||
CBaseObject *c = obj->GetChild(i);
|
||||
childs.push_back(c);
|
||||
RecursivelyGetAllChilds( c,childs );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::Done()
|
||||
{
|
||||
DeleteAllChilds();
|
||||
CBaseObject::Done();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::DeleteAllChilds()
|
||||
{
|
||||
std::vector<CBaseObjectPtr> childs;
|
||||
RecursivelyGetAllChilds( this,childs );
|
||||
for (int i = 0; i < childs.size(); i++)
|
||||
{
|
||||
GetObjectManager()->DeleteObject(childs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CGroup::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
m_ie = ie;
|
||||
bool res = CBaseObject::Init( ie,prev,file );
|
||||
if (prev)
|
||||
{
|
||||
InvalidateBBox();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::AttachChild( CBaseObject* child,bool bKeepPos )
|
||||
{
|
||||
CBaseObject::AttachChild( child,bKeepPos );
|
||||
// Set Group pointer of all non group child objects to this group.
|
||||
RecursivelySetGroup( child,this );
|
||||
InvalidateBBox();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::RemoveChild( CBaseObject *child )
|
||||
{
|
||||
// Set Group pointer of all non group child objects to parent group if present.
|
||||
RecursivelySetGroup( child,GetGroup() );
|
||||
CBaseObject::RemoveChild( child );
|
||||
InvalidateBBox();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::RecursivelySetGroup( CBaseObject *object,CGroup *pGroup )
|
||||
{
|
||||
object->SetGroup(pGroup);
|
||||
|
||||
if (object->GetType() != OBJTYPE_GROUP)
|
||||
{
|
||||
int numChilds = object->GetChildCount();
|
||||
for (int i = 0; i < numChilds; i++)
|
||||
{
|
||||
RecursivelySetGroup( object->GetChild(i),pGroup );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pGroup)
|
||||
{
|
||||
CGroup *pChildGroup = (CGroup*)object;
|
||||
if (!pGroup->IsOpen())
|
||||
pChildGroup->Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::RecursivelySetFlags( CBaseObject *object,int flags )
|
||||
{
|
||||
object->SetFlags( flags );
|
||||
|
||||
int numChilds = object->GetChildCount();
|
||||
for (int i = 0; i < numChilds; i++)
|
||||
{
|
||||
RecursivelySetFlags( object->GetChild(i),flags );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::RecursivelySetLayer( CBaseObject *object,CObjectLayer *pLayer )
|
||||
{
|
||||
object->SetLayer( pLayer );
|
||||
|
||||
int numChilds = object->GetChildCount();
|
||||
for (int i = 0; i < numChilds; i++)
|
||||
{
|
||||
RecursivelySetLayer( object->GetChild(i),pLayer );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::GetBoundBox( BBox &box )
|
||||
{
|
||||
if (!m_bBBoxValid)
|
||||
CalcBoundBox();
|
||||
box = m_bbox;
|
||||
box.Transform( GetWorldTM() );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::GetLocalBounds( BBox &box )
|
||||
{
|
||||
if (!m_bBBoxValid)
|
||||
CalcBoundBox();
|
||||
box = m_bbox;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CGroup::HitTest( HitContext &hc )
|
||||
{
|
||||
bool selected = false;
|
||||
if (m_opened)
|
||||
{
|
||||
selected = HitTestChilds( hc );
|
||||
}
|
||||
|
||||
if (!selected)
|
||||
{
|
||||
Vec3 p;
|
||||
|
||||
Matrix44 invertWTM = GetWorldTM();
|
||||
Vec3 worldPos = invertWTM.GetTranslationOLD();
|
||||
invertWTM.Invert44();
|
||||
|
||||
Vec3 xformedRaySrc = invertWTM.TransformPointOLD(hc.raySrc);
|
||||
Vec3 xformedRayDir = GetNormalized( invertWTM.TransformVectorOLD(hc.rayDir) );
|
||||
|
||||
float epsilonDist = hc.view->GetScreenScaleFactor( worldPos ) * 0.01f;
|
||||
float hitDist;
|
||||
|
||||
float tr = hc.distanceTollerance/2 + 1;
|
||||
BBox box;
|
||||
box.min = m_bbox.min - Vec3(tr+epsilonDist,tr+epsilonDist,tr+epsilonDist);
|
||||
box.max = m_bbox.max + Vec3(tr+epsilonDist,tr+epsilonDist,tr+epsilonDist);
|
||||
if (box.IsIntersectRay( xformedRaySrc,xformedRayDir,p ))
|
||||
{
|
||||
if (m_bbox.RayEdgeIntersection( xformedRaySrc,xformedRayDir,epsilonDist,hitDist,p ))
|
||||
{
|
||||
hc.dist = GetDistance(xformedRaySrc,p);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if any childs of closed group selected.
|
||||
if (!m_opened)
|
||||
{
|
||||
if (HitTestChilds( hc ))
|
||||
{
|
||||
hc.object = this;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return selected;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CGroup::HitTestChilds( HitContext &hcOrg )
|
||||
{
|
||||
float mindist = FLT_MAX;
|
||||
|
||||
//uint hideMask = GetIEditor()->GetDisplaySettings()->GetObjectHideMask();
|
||||
|
||||
HitContext hc;
|
||||
|
||||
CBaseObject *selected = 0;
|
||||
int numChilds = GetChildCount();
|
||||
for (int i = 0; i < numChilds; i++)
|
||||
{
|
||||
CBaseObject *obj = GetChild(i);
|
||||
|
||||
if (obj->IsHidden())
|
||||
continue;
|
||||
if (obj->IsFrozen())
|
||||
continue;
|
||||
|
||||
hc = hcOrg;
|
||||
|
||||
if (obj->IsSelected())
|
||||
{
|
||||
int axis = obj->HitTestAxis( hc );
|
||||
if (axis != 0)
|
||||
{
|
||||
hcOrg.object = obj;
|
||||
hcOrg.axis = axis;
|
||||
hcOrg.dist = hc.dist;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->HitTest(hc))
|
||||
{
|
||||
if (hc.dist < mindist)
|
||||
{
|
||||
mindist = hc.dist;
|
||||
// If collided object specified, accept it, overwise take tested object itself.
|
||||
if (hc.object)
|
||||
selected = hc.object;
|
||||
else
|
||||
selected = obj;
|
||||
hc.object = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (selected)
|
||||
{
|
||||
hcOrg.object = selected;
|
||||
hcOrg.dist = mindist;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::BeginEditParams( IEditor *ie,int flags )
|
||||
{
|
||||
m_ie = ie;
|
||||
CBaseObject::BeginEditParams( ie,flags );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::EndEditParams( IEditor *ie )
|
||||
{
|
||||
CBaseObject::EndEditParams( ie );
|
||||
}
|
||||
|
||||
void CGroup::SetPos( const Vec3d &pos )
|
||||
{
|
||||
CBaseObject::SetPos(pos);
|
||||
}
|
||||
|
||||
void CGroup::SetAngles( const Vec3d &angles )
|
||||
{
|
||||
CBaseObject::SetAngles(angles);
|
||||
}
|
||||
|
||||
void CGroup::SetScale( const Vec3d &scale )
|
||||
{
|
||||
CBaseObject::SetScale(scale);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::Display( DisplayContext &dc )
|
||||
{
|
||||
bool hideNames = dc.flags & DISPLAY_HIDENAMES;
|
||||
|
||||
DrawDefault(dc,GetColor());
|
||||
|
||||
if (!IsHighlighted())
|
||||
{
|
||||
dc.PushMatrix( GetWorldTM() );
|
||||
|
||||
if (IsSelected())
|
||||
{
|
||||
dc.SetSelectedColor();
|
||||
dc.DrawWireBox( m_bbox.min,m_bbox.max );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_bAlwaysDrawBox)
|
||||
{
|
||||
if (IsFrozen())
|
||||
dc.SetFreezeColor();
|
||||
else
|
||||
dc.SetColor( GetColor() );
|
||||
dc.DrawWireBox( m_bbox.min,m_bbox.max );
|
||||
}
|
||||
}
|
||||
dc.PopMatrix();
|
||||
}
|
||||
|
||||
/*
|
||||
uint hideMask = GetIEditor()->GetDisplaySettings()->GetObjectHideMask();
|
||||
CObjectManager *objMan = GetObjectManager();
|
||||
int numChilds = GetChildCount();
|
||||
for (int i = 0; i < numChilds; i++)
|
||||
{
|
||||
CBaseObject *obj = GetChild(i);
|
||||
if (!m_opened)
|
||||
{
|
||||
dc.flags |= DISPLAY_HIDENAMES;
|
||||
}
|
||||
// Check if object hidden.
|
||||
if (obj->IsHidden())
|
||||
{
|
||||
obj->UpdateVisibility(false);
|
||||
continue;
|
||||
}
|
||||
obj->Display( dc );
|
||||
obj->UpdateVisibility(true);
|
||||
}
|
||||
if (hideNames)
|
||||
dc.flags |= DISPLAY_HIDENAMES;
|
||||
else
|
||||
dc.flags &= ~DISPLAY_HIDENAMES;
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::Serialize( CObjectArchive &ar )
|
||||
{
|
||||
CBaseObject::Serialize( ar );
|
||||
|
||||
if (ar.bLoading)
|
||||
{
|
||||
// Loading.
|
||||
ar.node->getAttr( "Opened",m_opened );
|
||||
if (!ar.bUndo)
|
||||
SerializeChilds( ar );
|
||||
}
|
||||
else
|
||||
{
|
||||
ar.node->setAttr( "Opened",m_opened );
|
||||
if (!ar.bUndo)
|
||||
SerializeChilds( ar );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::SerializeChilds( CObjectArchive &ar )
|
||||
{
|
||||
XmlNodeRef xmlNode = ar.node;
|
||||
if (ar.bLoading)
|
||||
{
|
||||
// Loading.
|
||||
DetachAll();
|
||||
|
||||
// Loading.
|
||||
XmlNodeRef childsRoot = xmlNode->findChild( "Objects" );
|
||||
if (childsRoot)
|
||||
{
|
||||
// Load all childs from XML archive.
|
||||
ar.LoadObjects( childsRoot );
|
||||
InvalidateBBox();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetChildCount() > 0)
|
||||
{
|
||||
// Saving.
|
||||
XmlNodeRef root = xmlNode->newChild( "Objects" );
|
||||
ar.node = root;
|
||||
|
||||
// Save all child objects to XML.
|
||||
int num = GetChildCount();
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
CBaseObject *obj = GetChild(i);
|
||||
ar.SaveObject( obj );
|
||||
}
|
||||
}
|
||||
}
|
||||
ar.node = xmlNode;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
XmlNodeRef CGroup::Export( const CString &levelPath,XmlNodeRef &xmlNode )
|
||||
{
|
||||
/*
|
||||
// Saving.
|
||||
XmlNodeRef root( "Objects" );
|
||||
xmlNode->addChild( root );
|
||||
|
||||
// Save all child objects to XML.
|
||||
for (int i = 0; i < m_childs.size(); i++)
|
||||
{
|
||||
CBaseObject *obj = m_childs[i];
|
||||
|
||||
XmlNodeRef objNode( "Object" );
|
||||
objNode->setAttr( "Type",obj->GetTypeName() );
|
||||
root->addChild( objNode );
|
||||
|
||||
obj->Serialize( objNode,false );
|
||||
}
|
||||
*/
|
||||
|
||||
return CBaseObject::Export( levelPath,xmlNode );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::Ungroup()
|
||||
{
|
||||
std::vector<CBaseObjectPtr> childs;
|
||||
for (int i = 0; i < GetChildCount(); i++)
|
||||
{
|
||||
childs.push_back(GetChild(i));
|
||||
}
|
||||
DetachAll();
|
||||
// Select ungrouped objects.
|
||||
for (int i = 0; i < childs.size(); i++)
|
||||
{
|
||||
GetObjectManager()->SelectObject( childs[i] );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::Open()
|
||||
{
|
||||
if (!m_opened)
|
||||
{
|
||||
}
|
||||
m_opened = true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::Close()
|
||||
{
|
||||
if (m_opened)
|
||||
{
|
||||
}
|
||||
m_opened = false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::RecursivelyGetBoundBox( CBaseObject *object,BBox &box )
|
||||
{
|
||||
BBox b;
|
||||
object->GetBoundBox( b );
|
||||
box.Add(b.min);
|
||||
box.Add(b.max);
|
||||
|
||||
int numChilds = object->GetChildCount();
|
||||
for (int i = 0; i < numChilds; i++)
|
||||
{
|
||||
RecursivelyGetBoundBox( object->GetChild(i),box );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::CalcBoundBox()
|
||||
{
|
||||
Matrix44 ltm = GetLocalTM();
|
||||
Matrix44 tm;
|
||||
tm.SetIdentity();
|
||||
SetWorldTM(tm);
|
||||
|
||||
// Calc local bounds box..
|
||||
BBox box;
|
||||
box.Reset();
|
||||
|
||||
int numChilds = GetChildCount();
|
||||
for (int i = 0; i < numChilds; i++)
|
||||
{
|
||||
RecursivelyGetBoundBox( GetChild(i),box );
|
||||
}
|
||||
|
||||
if (numChilds == 0)
|
||||
{
|
||||
box.min = Vec3(-1,-1,-1);
|
||||
box.max = Vec3(1,1,1);
|
||||
}
|
||||
|
||||
SetLocalTM(ltm);
|
||||
|
||||
m_bbox = box;
|
||||
m_bBBoxValid = true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::OnChildModified()
|
||||
{
|
||||
if (m_ignoreChildModify)
|
||||
return;
|
||||
|
||||
InvalidateBBox();
|
||||
}
|
||||
|
||||
//! Select objects withing specified distance from givven position.
|
||||
int CGroup::SelectObjects( const BBox &box,bool bUnselect )
|
||||
{
|
||||
int numSel = 0;
|
||||
|
||||
BBox objBounds;
|
||||
uint hideMask = GetIEditor()->GetDisplaySettings()->GetObjectHideMask();
|
||||
int num = GetChildCount();
|
||||
for (int i = 0; i < num; ++i)
|
||||
{
|
||||
CBaseObject *obj = GetChild(i);
|
||||
|
||||
if (obj->IsHidden())
|
||||
continue;
|
||||
|
||||
if (obj->IsFrozen())
|
||||
continue;
|
||||
|
||||
if (obj->GetGroup())
|
||||
continue;
|
||||
|
||||
obj->GetBoundBox( objBounds );
|
||||
if (box.IsIntersectBox(objBounds))
|
||||
{
|
||||
numSel++;
|
||||
if (!bUnselect)
|
||||
GetObjectManager()->SelectObject( obj );
|
||||
else
|
||||
GetObjectManager()->UnselectObject( obj );
|
||||
}
|
||||
// If its group.
|
||||
if (obj->GetRuntimeClass() == RUNTIME_CLASS(CGroup))
|
||||
{
|
||||
numSel += ((CGroup*)obj)->SelectObjects( box,bUnselect );
|
||||
}
|
||||
}
|
||||
return numSel;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::OnEvent( ObjectEvent event )
|
||||
{
|
||||
CBaseObject::OnEvent(event);
|
||||
|
||||
int i;
|
||||
switch (event)
|
||||
{
|
||||
case EVENT_DBLCLICK:
|
||||
if (IsOpen())
|
||||
{
|
||||
int numChilds = GetChildCount();
|
||||
for (i = 0; i < numChilds; i++)
|
||||
{
|
||||
GetObjectManager()->SelectObject( GetChild(i) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
int numChilds = GetChildCount();
|
||||
for (int i = 0; i < numChilds; i++)
|
||||
{
|
||||
GetChild(i)->OnEvent( event );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGroup::OnMergeStaticGeom( IVariable *pVar )
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CGroup::GetGeomMergeId() const
|
||||
{
|
||||
if (mv_mergeStaticGeom)
|
||||
{
|
||||
return m_geomMergeId;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
149
Editor/Objects/Group.h
Normal file
149
Editor/Objects/Group.h
Normal file
@@ -0,0 +1,149 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: Group.h
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: Group object definition.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __Group_h__
|
||||
#define __Group_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "BaseObject.h"
|
||||
|
||||
/*!
|
||||
* CGroup groups object together.
|
||||
* Object can only be assigned to one group.
|
||||
*
|
||||
*/
|
||||
class CGroup : public CBaseObject
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CGroup)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
|
||||
void Display( DisplayContext &disp );
|
||||
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
|
||||
virtual void SetPos( const Vec3d &pos );
|
||||
virtual void SetAngles( const Vec3d &angles );
|
||||
virtual void SetScale( const Vec3d &scale );
|
||||
|
||||
//! Attach new child node.
|
||||
void AttachChild( CBaseObject* child,bool bKeepPos=true );
|
||||
|
||||
void GetBoundBox( BBox &box );
|
||||
void GetLocalBounds( BBox &box );
|
||||
bool HitTest( HitContext &hc );
|
||||
|
||||
void Serialize( CObjectArchive &ar );
|
||||
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
|
||||
//! Ovveride event handler from CBaseObject.
|
||||
void OnEvent( ObjectEvent event );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Group interface
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Select objects withing specified distance from givven position.
|
||||
//! Return number of selected objects.
|
||||
int SelectObjects( const BBox &box,bool bUnselect=false );
|
||||
|
||||
//! Remove all childs from this group.
|
||||
void Ungroup();
|
||||
|
||||
//! Open group.
|
||||
//! Make childs accesseble from top user interface.
|
||||
void Open();
|
||||
|
||||
//! Close group.
|
||||
//! Make childs unacesseble from top user interface.
|
||||
//! In Closed state group only display objects but not allow to select them.
|
||||
void Close();
|
||||
|
||||
//! Return true if group is in Opened.
|
||||
bool IsOpen() const { return m_opened; };
|
||||
|
||||
//! Called by child object, when it changes.
|
||||
void OnChildModified();
|
||||
|
||||
void DeleteAllChilds();
|
||||
|
||||
//! If of this group used for geometry merging.
|
||||
int GetGeomMergeId() const;
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CGroup();
|
||||
void InvalidateBBox() { m_bBBoxValid = false; };
|
||||
|
||||
bool HitTestChilds( HitContext &hc );
|
||||
void SerializeChilds( CObjectArchive &ar );
|
||||
virtual void CalcBoundBox();
|
||||
|
||||
static void RecursivelySetGroup( CBaseObject *object,CGroup *pGroup );
|
||||
static void RecursivelySetFlags( CBaseObject *object,int flags );
|
||||
static void RecursivelySetLayer( CBaseObject *object,CObjectLayer *pLayer );
|
||||
//! Get combined bounding box of all childs in hierarchy.
|
||||
static void RecursivelyGetBoundBox( CBaseObject *object,BBox &box );
|
||||
|
||||
// Ovveriden from CBaseObject.
|
||||
void RemoveChild( CBaseObject *node );
|
||||
void DeleteThis() { delete this; };
|
||||
void OnMergeStaticGeom( IVariable *pVar );
|
||||
|
||||
BBox m_bbox;
|
||||
bool m_bBBoxValid;
|
||||
bool m_opened;
|
||||
bool m_bAlwaysDrawBox;
|
||||
bool m_ignoreChildModify;
|
||||
|
||||
CVariable<bool> mv_mergeStaticGeom;
|
||||
|
||||
// Geometry merging group assigned to this Group.
|
||||
int m_geomMergeId;
|
||||
|
||||
static int s_groupGeomMergeId;
|
||||
|
||||
IEditor *m_ie;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of Group.
|
||||
*/
|
||||
class CGroupClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {1ED5BF40-BECA-4ba1-8E90-0906FF862A75}
|
||||
static const GUID guid = { 0x1ed5bf40, 0xbeca, 0x4ba1, { 0x8e, 0x90, 0x9, 0x6, 0xff, 0x86, 0x2a, 0x75 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_GROUP; };
|
||||
const char* ClassName() { return "Group"; };
|
||||
const char* Category() { return ""; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CGroup); };
|
||||
};
|
||||
|
||||
#endif // __Group_h__
|
||||
244
Editor/Objects/LineGizmo.cpp
Normal file
244
Editor/Objects/LineGizmo.cpp
Normal file
@@ -0,0 +1,244 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001-2004.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: LineGizmo.cpp
|
||||
// Version: v1.00
|
||||
// Created: 6/11/2003 by Timur.
|
||||
// Compilers: Visual Studio.NET 2003
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "LineGizmo.h"
|
||||
|
||||
#include "DisplayContext.h"
|
||||
|
||||
#include "..\Viewport.h"
|
||||
#include "..\DisplaySettings.h"
|
||||
#include "ObjectManager.h"
|
||||
|
||||
#include "GizmoManager.h"
|
||||
#include "Settings.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CLineGizmo::CLineGizmo()
|
||||
{
|
||||
m_color[0] = CFColor(0,1,1,1);
|
||||
m_color[1] = CFColor(0,1,1,1);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CLineGizmo::~CLineGizmo()
|
||||
{
|
||||
if (m_object[0])
|
||||
m_object[0]->RemoveEventListener( functor(*this,&CLineGizmo::OnObjectEvent) );
|
||||
if (m_object[1])
|
||||
m_object[1]->RemoveEventListener( functor(*this,&CLineGizmo::OnObjectEvent) );
|
||||
m_object[0] = 0;
|
||||
m_object[1] = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CLineGizmo::SetObjects( CBaseObject *pObject1,CBaseObject *pObject2 )
|
||||
{
|
||||
assert( pObject1 );
|
||||
assert( pObject2 );
|
||||
m_object[0] = pObject1;
|
||||
m_object[1] = pObject2;
|
||||
|
||||
m_object[0]->AddEventListener( functor(*this,&CLineGizmo::OnObjectEvent) );
|
||||
m_object[1]->AddEventListener( functor(*this,&CLineGizmo::OnObjectEvent) );
|
||||
CalcBounds();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CLineGizmo::OnObjectEvent( CBaseObject *object,int event )
|
||||
{
|
||||
if (event == CBaseObject::ON_TRANSFORM)
|
||||
{
|
||||
// One of objects transformed, recalc gizmo bounds.
|
||||
CalcBounds();
|
||||
return;
|
||||
}
|
||||
if (event == CBaseObject::ON_DELETE)
|
||||
{
|
||||
// This gizmo must be deleted as well if one of the objects is deleted.
|
||||
GetGizmoManager()->RemoveGizmo(this);
|
||||
return;
|
||||
}
|
||||
if (event == CBaseObject::ON_VISIBILITY)
|
||||
{
|
||||
// Check visibility of gizmo.
|
||||
bool bVisible = m_object[0]->CheckFlags(OBJFLAG_VISIBLE) && m_object[1]->CheckFlags(OBJFLAG_VISIBLE);
|
||||
if (bVisible)
|
||||
SetFlags( GetFlags() & (~EGIZMO_HIDDEN));
|
||||
else
|
||||
SetFlags( GetFlags() | EGIZMO_HIDDEN );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CLineGizmo::Display( DisplayContext &dc )
|
||||
{
|
||||
if (dc.flags & DISPLAY_LINKS)
|
||||
{
|
||||
if (m_object[0]->CheckFlags(OBJFLAG_PREFAB) && m_object[1]->CheckFlags(OBJFLAG_PREFAB))
|
||||
return;
|
||||
|
||||
// Draw line between objects.
|
||||
dc.DrawLine( m_point[0],m_point[1],m_color[0],m_color[1] );
|
||||
|
||||
if (!(dc.flags & DISPLAY_HIDENAMES))
|
||||
{
|
||||
Vec3 pos = 0.5f*(m_point[0] + m_point[1]);
|
||||
//dc.renderer->DrawLabelEx( p3+Vec3(0,0,0.3f),1.2f,col,true,true,m_name );
|
||||
|
||||
float camDist = GetDistance(dc.camera->GetPos(), pos );
|
||||
float maxDist = dc.settings->GetLabelsDistance();
|
||||
if (camDist < dc.settings->GetLabelsDistance())
|
||||
{
|
||||
float range = maxDist / 2.0f;
|
||||
float col[4] = { m_color[0].r,m_color[0].g,m_color[0].b,m_color[0].a };
|
||||
if (camDist > range)
|
||||
{
|
||||
col[3] = col[3] * (1.0f - (camDist - range)/range);
|
||||
}
|
||||
dc.SetColor( col[0],col[1],col[2],col[3] );
|
||||
dc.DrawTextLabel( pos+Vec3(0,0,0.2f),1.2f,m_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CLineGizmo::CalcBounds()
|
||||
{
|
||||
m_bbox.Reset();
|
||||
|
||||
BBox box;
|
||||
m_object[0]->GetBoundBox( box );
|
||||
m_point[0] = 0.5f*Vec3(box.max+box.min);
|
||||
m_object[1]->GetBoundBox( box );
|
||||
m_point[1] = 0.5f*Vec3(box.max+box.min);
|
||||
|
||||
m_bbox.Add( m_point[0] );
|
||||
m_bbox.Add( m_point[1] );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CLineGizmo::GetWorldBounds( BBox &bbox )
|
||||
{
|
||||
bbox = m_bbox;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CLineGizmo::SetColor( const Vec3 &color1,const Vec3 &color2,float alpha1,float alpha2 )
|
||||
{
|
||||
m_color[0] = CFColor(color1.x,color1.y,color1.z,alpha1);
|
||||
m_color[1] = CFColor(color2.x,color2.y,color2.z,alpha2);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CLineGizmo::SetName( const char *sName )
|
||||
{
|
||||
m_name = sName;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CLineGizmo::HitTest( HitContext &hc )
|
||||
{
|
||||
return 0;
|
||||
/*
|
||||
if (hc.distanceTollerance != 0)
|
||||
return 0;
|
||||
|
||||
Vec3 org = m_object->GetWorldPos();
|
||||
|
||||
float fScreenScale = hc.view->GetScreenScaleFactor(org);
|
||||
float size = gSettings.gizmo.axisGizmoSize * fScreenScale;
|
||||
|
||||
Vec3 x(size,0,0);
|
||||
Vec3 y(0,size,0);
|
||||
Vec3 z(0,0,size);
|
||||
|
||||
float hitDist = 0.01f * fScreenScale;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Calculate ray in local space of axis.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
Matrix44 tm;
|
||||
RefCoordSys refCoordSys = GetIEditor()->GetReferenceCoordSys();
|
||||
if (refCoordSys == COORDS_LOCAL)
|
||||
{
|
||||
tm = m_object->GetWorldTM();
|
||||
tm.NoScale();
|
||||
}
|
||||
else
|
||||
{
|
||||
tm.SetIdentity();
|
||||
tm.SetTranslationOLD( m_object->GetWorldPos() );
|
||||
}
|
||||
tm.Invert44();
|
||||
Vec3 raySrc = tm.TransformPointOLD( hc.raySrc );
|
||||
//CHANGED_BY_IVO
|
||||
//Vec3 rayDir = tm.TransformVector( hc.rayDir );
|
||||
Vec3 rayDir = GetTransposed44(tm) * ( hc.rayDir );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Vec3 pnt;
|
||||
BBox box;
|
||||
box.min = - Vec3(hitDist*2,hitDist*2,hitDist*2);
|
||||
box.max = Vec3(size+hitDist*2,size+hitDist*2,size+hitDist*2);
|
||||
if (!box.IsIntersectRay( raySrc,rayDir,pnt ))
|
||||
{
|
||||
m_highlightAxis = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
float axisdist[10];
|
||||
Vec3 np[10];
|
||||
|
||||
Vec3 rayTrg = raySrc + rayDir*10000.0f;
|
||||
|
||||
size *= 0.3f;
|
||||
Vec3 p1(size,size,0);
|
||||
Vec3 p2(size,0,size);
|
||||
Vec3 p3(0,size,size);
|
||||
|
||||
axisdist[AXIS_X] = RayToLineDistance( raySrc,rayTrg,Vec3(0,0,0),x,np[AXIS_X] );
|
||||
axisdist[AXIS_Y] = RayToLineDistance( raySrc,rayTrg,Vec3(0,0,0),y,np[AXIS_Y] );
|
||||
axisdist[AXIS_Z] = RayToLineDistance( raySrc,rayTrg,Vec3(0,0,0),z,np[AXIS_Z] );
|
||||
axisdist[AXIS_XY] = RayToLineDistance( raySrc,rayTrg,p1,p1-x*0.3f,np[AXIS_XY] );
|
||||
axisdist[AXIS_XZ] = RayToLineDistance( raySrc,rayTrg,p2,p2-x*0.3f,np[AXIS_XZ] );
|
||||
axisdist[AXIS_YZ] = RayToLineDistance( raySrc,rayTrg,p3,p3-y*0.3f,np[AXIS_YZ] );
|
||||
|
||||
float mindist = hitDist;
|
||||
int axis = 0;
|
||||
for (int i = AXIS_X; i <= AXIS_XZ; i++)
|
||||
{
|
||||
if (axisdist[i] < mindist)
|
||||
{
|
||||
mindist = axisdist[i];
|
||||
axis = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (axis != 0)
|
||||
{
|
||||
hc.axis = axis;
|
||||
hc.object = m_object;
|
||||
hc.dist = GetDistance(raySrc,np[axis]);
|
||||
}
|
||||
|
||||
m_highlightAxis = axis;
|
||||
|
||||
return axis != 0;
|
||||
*/
|
||||
}
|
||||
58
Editor/Objects/LineGizmo.h
Normal file
58
Editor/Objects/LineGizmo.h
Normal file
@@ -0,0 +1,58 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001-2004.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: LineGizmo.h
|
||||
// Version: v1.00
|
||||
// Created: 6/11/2003 by Timur.
|
||||
// Compilers: Visual Studio.NET 2003
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __LineGizmo_h__
|
||||
#define __LineGizmo_h__
|
||||
#pragma once
|
||||
|
||||
#include "BaseObject.h"
|
||||
#include "Gizmo.h"
|
||||
|
||||
// forward declarations.
|
||||
struct DisplayContext;
|
||||
|
||||
/** Gizmo of link line connecting two Objects.
|
||||
*/
|
||||
class CLineGizmo : public CGizmo
|
||||
{
|
||||
public:
|
||||
CLineGizmo();
|
||||
~CLineGizmo();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CGizmo
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void GetWorldBounds( BBox &bbox );
|
||||
virtual void Display( DisplayContext &dc );
|
||||
virtual bool HitTest( HitContext &hc );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SetObjects( CBaseObject *pObject1,CBaseObject *pObject2 );
|
||||
void SetColor( const Vec3 &color1,const Vec3 &color2,float alpha1=1.0f,float alpha2=1.0f );
|
||||
void SetName( const char *sName );
|
||||
|
||||
private:
|
||||
void OnObjectEvent( CBaseObject *object,int event );
|
||||
void CalcBounds();
|
||||
|
||||
CBaseObjectPtr m_object[2];
|
||||
Vec3 m_point[2];
|
||||
BBox m_bbox;
|
||||
CFColor m_color[2];
|
||||
CString m_name;
|
||||
};
|
||||
|
||||
#endif // __LineGizmo_h__
|
||||
|
||||
214
Editor/Objects/ObjectLayer.cpp
Normal file
214
Editor/Objects/ObjectLayer.cpp
Normal file
@@ -0,0 +1,214 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: objectlayer.cpp
|
||||
// Version: v1.00
|
||||
// Created: 9/4/2002 by Timur.
|
||||
// Compilers: Visual C++ 7.0
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "ObjectLayer.h"
|
||||
|
||||
#include "ObjectManager.h"
|
||||
#include "ObjectLayerManager.h"
|
||||
|
||||
#define LAYER_ID(x) ((x)>>16)
|
||||
#define OBJECT_ID(x) ((x)&0xFFFF)
|
||||
#define MAKE_ID(layerId,objectId) (((layerId)<<16)|(objectId))
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CObjectLayer::CObjectLayer( CObjectLayerManager *pLayerManager )
|
||||
{
|
||||
assert( pLayerManager != 0 );
|
||||
m_pLayerManager = pLayerManager;
|
||||
m_pObjectManager = pLayerManager->GetObjectManager();
|
||||
m_hidden = false;
|
||||
m_frozen = false;
|
||||
m_removable = true;
|
||||
m_parent = NULL;
|
||||
m_external = false;
|
||||
m_exportable = true;
|
||||
m_expanded = false;
|
||||
ZeroStruct(m_parentGUID);
|
||||
|
||||
CoCreateGuid( &m_guid );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayer::Serialize( XmlNodeRef &node,bool bLoading )
|
||||
{
|
||||
if (bLoading)
|
||||
{
|
||||
bool bHidden = m_hidden;
|
||||
bool bFrozen = m_frozen;
|
||||
bool bExternal = false;
|
||||
// Loading.
|
||||
node->getAttr( "Name",m_name );
|
||||
node->getAttr( "GUID",m_guid );
|
||||
node->getAttr( "Hidden",bHidden );
|
||||
node->getAttr( "Frozen",bFrozen );
|
||||
node->getAttr( "External",bExternal );
|
||||
node->getAttr( "Exportable",m_exportable );
|
||||
|
||||
ZeroStruct(m_parentGUID);
|
||||
node->getAttr( "ParentGUID",m_parentGUID );
|
||||
|
||||
SetExternal( bExternal );
|
||||
SetVisible( !bHidden );
|
||||
SetFrozen( bFrozen );
|
||||
m_pObjectManager->InvalidateVisibleList();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Saving.
|
||||
node->setAttr( "Name",m_name );
|
||||
node->setAttr( "GUID",m_guid );
|
||||
node->setAttr( "Hidden",m_hidden );
|
||||
node->setAttr( "Frozen",m_frozen );
|
||||
node->setAttr( "External",m_external );
|
||||
node->setAttr( "Exportable",m_exportable );
|
||||
|
||||
GUID parentGUID = m_parentGUID;
|
||||
if (m_parent == m_pLayerManager->GetMainLayer())
|
||||
ZeroStruct(parentGUID);
|
||||
if (!GuidUtil::IsEmpty(parentGUID))
|
||||
node->setAttr( "ParentGUID",parentGUID );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayer::SetName( const CString &name )
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayer::AddChild( CObjectLayer *pLayer )
|
||||
{
|
||||
assert( pLayer );
|
||||
if (IsChildOf(pLayer))
|
||||
return;
|
||||
if (pLayer->GetParent())
|
||||
pLayer->GetParent()->RemoveChild(pLayer);
|
||||
stl::push_back_unique( m_childLayers,pLayer );
|
||||
pLayer->m_parent = this;
|
||||
pLayer->m_parentGUID = GetGUID();
|
||||
m_pObjectManager->InvalidateVisibleList();
|
||||
|
||||
// Notify layer manager on layer modification.
|
||||
m_pLayerManager->NotifyLayerChange(this);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayer::RemoveChild( CObjectLayer *pLayer )
|
||||
{
|
||||
assert( pLayer );
|
||||
pLayer->m_parent = 0;
|
||||
ZeroStruct(pLayer->m_parentGUID);
|
||||
stl::find_and_erase( m_childLayers,pLayer );
|
||||
m_pObjectManager->InvalidateVisibleList();
|
||||
|
||||
// Notify layer manager on layer modification.
|
||||
m_pLayerManager->NotifyLayerChange(this);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CObjectLayer* CObjectLayer::GetChild( int index ) const
|
||||
{
|
||||
assert( index >= 0 && index < m_childLayers.size() );
|
||||
return m_childLayers[index];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CObjectLayer* CObjectLayer::FindChildLayer( REFGUID guid )
|
||||
{
|
||||
if (m_guid == guid)
|
||||
return this;
|
||||
|
||||
for (int i = 0; i < GetChildCount(); i++)
|
||||
{
|
||||
CObjectLayer *pLayer = GetChild(i)->FindChildLayer(guid);
|
||||
if (pLayer)
|
||||
return pLayer;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CObjectLayer::IsChildOf( CObjectLayer *pParent )
|
||||
{
|
||||
if (m_parent == pParent)
|
||||
return true;
|
||||
if (m_parent)
|
||||
{
|
||||
return m_parent->IsChildOf(pParent);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayer::SetVisible( bool b,bool bRecursive )
|
||||
{
|
||||
bool bChange = m_hidden != !b;
|
||||
m_hidden = !b;
|
||||
|
||||
if (bChange)
|
||||
{
|
||||
// Notify layer manager on layer modification.
|
||||
m_pLayerManager->NotifyLayerChange(this);
|
||||
m_pObjectManager->InvalidateVisibleList();
|
||||
}
|
||||
if (bRecursive)
|
||||
{
|
||||
for (int i = 0; i < GetChildCount(); i++)
|
||||
{
|
||||
GetChild(i)->SetVisible( b,bRecursive );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayer::SetFrozen( bool b,bool bRecursive )
|
||||
{
|
||||
bool bChange = m_frozen != b;
|
||||
m_frozen = b;
|
||||
|
||||
if (bChange)
|
||||
{
|
||||
// Notify layer manager on layer modification.
|
||||
m_pLayerManager->NotifyLayerChange(this);
|
||||
m_pObjectManager->InvalidateVisibleList();
|
||||
}
|
||||
if (bRecursive)
|
||||
{
|
||||
for (int i = 0; i < GetChildCount(); i++)
|
||||
{
|
||||
GetChild(i)->SetFrozen( b,bRecursive );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayer::Expand( bool bExpand )
|
||||
{
|
||||
m_expanded = bExpand;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CObjectLayer::IsParentExternal() const
|
||||
{
|
||||
if (m_parent)
|
||||
{
|
||||
if (m_parent->IsExternal())
|
||||
return true;
|
||||
return m_parent->IsParentExternal();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
131
Editor/Objects/ObjectLayer.h
Normal file
131
Editor/Objects/ObjectLayer.h
Normal file
@@ -0,0 +1,131 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: objectlayer.h
|
||||
// Version: v1.00
|
||||
// Created: 9/4/2002 by Timur.
|
||||
// Compilers: Visual C++ 7.0
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __objectlayer_h__
|
||||
#define __objectlayer_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// forward declarations.
|
||||
class CObjectLayerManager;
|
||||
class CObjectManager;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Object Layer.
|
||||
All objects are orginized in hierarchical layers.
|
||||
Every layer can be made hidden/frozen or can be exported or imported back.
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CObjectLayer : public CRefCountBase
|
||||
{
|
||||
public:
|
||||
CObjectLayer( CObjectLayerManager *pLayerManager );
|
||||
|
||||
//! Set layer name.
|
||||
void SetName( const CString &name );
|
||||
//! Get layer name.
|
||||
const CString& GetName() const { return m_name; }
|
||||
|
||||
//! Get GUID assigned to this layer.
|
||||
REFGUID GetGUID() const { return m_guid; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Query layer status.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool IsVisible() const { return !m_hidden; }
|
||||
bool IsFrozen() const { return m_frozen; }
|
||||
bool IsRemovable() const { return m_removable; };
|
||||
bool IsExternal() const { return m_external; };
|
||||
bool IsExportable() const { return m_exportable; };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Set layer status.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SetVisible( bool b,bool bRecursive=false );
|
||||
void SetFrozen( bool b,bool bRecursive=false );
|
||||
void SetRemovable( bool b ) { m_removable = b; };
|
||||
void SetExternal( bool b ) { m_external = b; };
|
||||
void SetExportable( bool b ) { m_exportable = b; };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Save/Load layer to/from xml node.
|
||||
void Serialize( XmlNodeRef &node,bool bLoading );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Child layers.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void AddChild( CObjectLayer *pLayer );
|
||||
void RemoveChild( CObjectLayer *pLayer );
|
||||
int GetChildCount() const { return m_childLayers.size(); }
|
||||
CObjectLayer* GetChild( int index ) const;
|
||||
CObjectLayer* GetParent() const { return m_parent; }
|
||||
|
||||
//! Check if specified layer is direct or indirect parent of this layer.
|
||||
bool IsChildOf( CObjectLayer *pParent );
|
||||
//! Find child layer with specified GUID.
|
||||
//! Search done recursively, so it find child layer in any depth.
|
||||
CObjectLayer* FindChildLayer( REFGUID guid );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool IsParentExternal() const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// User interface support.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void Expand( bool bExpand );
|
||||
bool IsExpanded() const { return m_expanded; };
|
||||
|
||||
private:
|
||||
friend CObjectLayerManager;
|
||||
//! GUID of this layer.
|
||||
GUID m_guid;
|
||||
//! Layer Name.
|
||||
CString m_name;
|
||||
|
||||
// Layer state.
|
||||
//! If true Object of this layer is hidden.
|
||||
bool m_hidden;
|
||||
//! If true Object of this layer is frozen (not selectable).
|
||||
bool m_frozen;
|
||||
//! True if this layer can be deleted.
|
||||
bool m_removable;
|
||||
//! True if layer is stored externally to project file.
|
||||
bool m_external;
|
||||
//! True if objects on this layer must be exported to the game.
|
||||
bool m_exportable;
|
||||
|
||||
//! True when layer is expanded in GUI. (Should not be serialized)
|
||||
bool m_expanded;
|
||||
|
||||
// List of child layers.
|
||||
typedef std::vector<TSmartPtr<CObjectLayer> > ChildLayers;
|
||||
ChildLayers m_childLayers;
|
||||
|
||||
//! Pointer to parent layer.
|
||||
CObjectLayer *m_parent;
|
||||
//! Parent layer GUID.
|
||||
GUID m_parentGUID;
|
||||
|
||||
// Object manager owning this layer.
|
||||
CObjectManager *m_pObjectManager;
|
||||
|
||||
//! Manager of object layers.
|
||||
CObjectLayerManager* m_pLayerManager;
|
||||
};
|
||||
|
||||
#endif // __objectlayer_h__
|
||||
512
Editor/Objects/ObjectLayerManager.cpp
Normal file
512
Editor/Objects/ObjectLayerManager.cpp
Normal file
@@ -0,0 +1,512 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: objectlayermanager.cpp
|
||||
// Version: v1.00
|
||||
// Created: 9/5/2003 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "ObjectLayerManager.h"
|
||||
#include "ObjectLoader.h"
|
||||
#include "ObjectManager.h"
|
||||
#include "GameEngine.h"
|
||||
#include "ErrorReport.h"
|
||||
#include "Settings.h"
|
||||
|
||||
#define LAYER_FILE_EXTENSION ".lyr"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CObjectLayerManager::CObjectLayerManager( CObjectManager *pObjectManager )
|
||||
{
|
||||
m_pObjectManager = pObjectManager;
|
||||
m_layersPath = "Layers\\";
|
||||
|
||||
// Create main root level.
|
||||
m_pMainLayer = new CObjectLayer( this );
|
||||
m_layersMap[m_pMainLayer->GetGUID()] = m_pMainLayer;
|
||||
m_pMainLayer->SetRemovable(false);
|
||||
m_pMainLayer->SetExternal(false);
|
||||
m_pMainLayer->SetName( "Main" );
|
||||
m_pMainLayer->Expand(true);
|
||||
m_pCurrentLayer = m_pMainLayer;
|
||||
m_bOverwriteDuplicates = false;
|
||||
}
|
||||
|
||||
void CObjectLayerManager::GetLayers( std::vector<CObjectLayer*> &layers ) const
|
||||
{
|
||||
layers.clear();
|
||||
layers.reserve( m_layersMap.size() );
|
||||
for (LayersMap::const_iterator it = m_layersMap.begin(); it != m_layersMap.end(); ++it)
|
||||
{
|
||||
layers.push_back( it->second );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayerManager::ClearLayers()
|
||||
{
|
||||
// Erase all removable layers.
|
||||
LayersMap::iterator it,itnext;
|
||||
for (LayersMap::iterator it = m_layersMap.begin(); it != m_layersMap.end(); it = itnext)
|
||||
{
|
||||
CObjectLayer *pLayer = it->second;
|
||||
itnext = it;
|
||||
itnext++;
|
||||
|
||||
if (pLayer->IsRemovable())
|
||||
{
|
||||
NotifyListeners( ON_LAYER_REMOVE,pLayer );
|
||||
m_layersMap.erase( it );
|
||||
}
|
||||
}
|
||||
m_pCurrentLayer = 0;
|
||||
if (!m_layersMap.empty())
|
||||
{
|
||||
SetCurrentLayer( m_layersMap.begin()->second );
|
||||
}
|
||||
NotifyListeners( ON_LAYER_UPDATEALL,NULL );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CObjectLayer* CObjectLayerManager::CreateLayer()
|
||||
{
|
||||
CObjectLayer *pLayer = new CObjectLayer( this );
|
||||
m_layersMap[pLayer->GetGUID()] = pLayer;
|
||||
//m_pMainLayer->AddChild( pLayer );
|
||||
NotifyListeners( ON_LAYER_ADD,pLayer );
|
||||
// pLayer->SetExternal(true);
|
||||
return pLayer;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayerManager::AddLayer( CObjectLayer *pLayer )
|
||||
{
|
||||
assert(pLayer);
|
||||
|
||||
if (!m_bOverwriteDuplicates)
|
||||
{
|
||||
CObjectLayer *pPrevLayer = FindLayerByName( pLayer->GetName() );
|
||||
if (pPrevLayer)
|
||||
{
|
||||
CErrorRecord err;
|
||||
err.error.Format( _T("Duplicate Layer Name <%s>"),(const char*)pLayer->GetName() );
|
||||
err.severity = CErrorRecord::ESEVERITY_ERROR;
|
||||
GetIEditor()->GetErrorReport()->ReportError(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_layersMap.find(pLayer->GetGUID()) != m_layersMap.end())
|
||||
{
|
||||
pPrevLayer = FindLayer(pLayer->GetGUID());
|
||||
|
||||
CErrorRecord err;
|
||||
err.error.Format( _T("Duplicate Layer GUID,Layer <%s> collides with layer <%s>"),
|
||||
(const char*)pPrevLayer->GetName(),(const char*)pLayer->GetName() );
|
||||
err.severity = CErrorRecord::ESEVERITY_ERROR;
|
||||
GetIEditor()->GetErrorReport()->ReportError(err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_layersMap[pLayer->GetGUID()] = pLayer;
|
||||
NotifyListeners( ON_LAYER_ADD,pLayer );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayerManager::DeleteLayer( CObjectLayer *pLayer )
|
||||
{
|
||||
assert( pLayer );
|
||||
// cannot remove non removable layer.
|
||||
if (!pLayer->IsRemovable())
|
||||
return;
|
||||
|
||||
// First delete all child layers.
|
||||
for (int i = 0; i < pLayer->GetChildCount(); i++)
|
||||
{
|
||||
DeleteLayer( pLayer->GetChild(i) );
|
||||
}
|
||||
|
||||
// prevent reference counted layer to be released before this function ends.
|
||||
TSmartPtr<CObjectLayer> pLayerHolder = pLayer;
|
||||
|
||||
if (pLayer->GetParent())
|
||||
pLayer->GetParent()->RemoveChild( pLayer );
|
||||
|
||||
// Delete all objects for this layer.
|
||||
std::vector<CBaseObjectPtr> objects;
|
||||
m_pObjectManager->GetAllObjects( objects );
|
||||
for (int k = 0; k < objects.size(); k++)
|
||||
{
|
||||
if (objects[k]->GetLayer() == pLayer)
|
||||
m_pObjectManager->DeleteObject(objects[k]);
|
||||
}
|
||||
|
||||
if (m_pCurrentLayer == pLayer)
|
||||
m_pCurrentLayer = pLayer->GetParent();
|
||||
m_layersMap.erase( pLayer->GetGUID() );
|
||||
|
||||
if (!m_pCurrentLayer)
|
||||
m_pCurrentLayer = m_pMainLayer;
|
||||
|
||||
NotifyListeners( ON_LAYER_REMOVE,pLayer );
|
||||
NotifyListeners( ON_LAYER_SELECT,m_pCurrentLayer );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CObjectLayer* CObjectLayerManager::FindLayer( REFGUID guid ) const
|
||||
{
|
||||
CObjectLayer *pLayer = stl::find_in_map( m_layersMap,guid,(CObjectLayer*)0 );
|
||||
return pLayer;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CObjectLayer* CObjectLayerManager::FindLayerByName( const CString &layerName ) const
|
||||
{
|
||||
for (LayersMap::const_iterator it = m_layersMap.begin(); it != m_layersMap.end(); ++it)
|
||||
{
|
||||
if (stricmp(it->second->GetName(),layerName) == 0)
|
||||
return it->second;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayerManager::NotifyLayerChange( CObjectLayer *pLayer )
|
||||
{
|
||||
assert(pLayer);
|
||||
// check if this layers is already registered in manager.
|
||||
if (m_layersMap.find(pLayer->GetGUID()) != m_layersMap.end())
|
||||
{
|
||||
// Notify listeners of this change.
|
||||
NotifyListeners( ON_LAYER_MODIFY,pLayer );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayerManager::AddUpdateListener( const LayersUpdateCallback &cb )
|
||||
{
|
||||
m_listeners.Add( cb );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayerManager::RemoveUpdateListener( const LayersUpdateCallback &cb )
|
||||
{
|
||||
m_listeners.Remove(cb);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayerManager::NotifyListeners( EUpdateType type,CObjectLayer *pLayer )
|
||||
{
|
||||
m_listeners.Call( type,pLayer );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayerManager::Serialize( CObjectArchive &ar,bool bIgnoreExternalLayers )
|
||||
{
|
||||
XmlNodeRef xmlNode = ar.node;
|
||||
if (ar.bLoading)
|
||||
{
|
||||
ClearLayers();
|
||||
// Loading from archive.
|
||||
XmlNodeRef layers = xmlNode->findChild( "ObjectLayers" );
|
||||
if (layers)
|
||||
{
|
||||
for (int i = 0; i < layers->getChildCount(); i++)
|
||||
{
|
||||
XmlNodeRef layerNode = layers->getChild(i);
|
||||
TSmartPtr<CObjectLayer> pLayer = new CObjectLayer( this );
|
||||
pLayer->Serialize( layerNode,true );
|
||||
if (pLayer->IsExternal())
|
||||
{
|
||||
if (!bIgnoreExternalLayers)
|
||||
LoadExternalLayer( pLayer->GetName(),ar );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if this layer is alyeady loaded.
|
||||
if (!FindLayer( pLayer->GetGUID() ))
|
||||
AddLayer( pLayer );
|
||||
}
|
||||
}
|
||||
|
||||
GUID currentLayerGUID;
|
||||
if (layers->getAttr( "CurrentGUID",currentLayerGUID ))
|
||||
{
|
||||
CObjectLayer *pLayer = FindLayer( currentLayerGUID );
|
||||
if (pLayer)
|
||||
SetCurrentLayer( pLayer );
|
||||
}
|
||||
}
|
||||
ResolveLayerLinks();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Saving to archive.
|
||||
XmlNodeRef layersNode = xmlNode->newChild( "ObjectLayers" );
|
||||
|
||||
//! Store currently selected layer.
|
||||
if (m_pCurrentLayer)
|
||||
{
|
||||
layersNode->setAttr( "Current",m_pCurrentLayer->GetName() );
|
||||
layersNode->setAttr( "CurrentGUID",m_pCurrentLayer->GetGUID() );
|
||||
}
|
||||
|
||||
for (LayersMap::const_iterator it = m_layersMap.begin(); it != m_layersMap.end(); ++it)
|
||||
{
|
||||
CObjectLayer *pLayer = it->second;
|
||||
if (!pLayer->IsRemovable())
|
||||
continue;
|
||||
|
||||
XmlNodeRef layerNode = layersNode->newChild("Layer");
|
||||
pLayer->Serialize( layerNode,false );
|
||||
|
||||
if (pLayer->IsExternal() && !bIgnoreExternalLayers)
|
||||
{
|
||||
// Save external level additionally to file.
|
||||
SaveExternalLayer( pLayer,ar );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
ar.node = xmlNode;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayerManager::SaveExternalLayer( CObjectLayer *pLayer,CObjectArchive &ar )
|
||||
{
|
||||
// Form file name from layer name.
|
||||
CString path = Path::AddBackslash( GetIEditor()->GetGameEngine()->GetLevelPath() ) + m_layersPath;
|
||||
CString file = path + pLayer->GetName() + LAYER_FILE_EXTENSION;
|
||||
|
||||
CFileUtil::CreateDirectory( path );
|
||||
|
||||
// Make a backup of file.
|
||||
if (gSettings.bBackupOnSave)
|
||||
CFileUtil::BackupFile( file );
|
||||
|
||||
// Serialize this layer.
|
||||
XmlNodeRef rootFileNode = new CXmlNode( "ObjectLayer" );
|
||||
XmlNodeRef layerNode = rootFileNode->newChild( "Layer" );
|
||||
ar.node = layerNode;
|
||||
ExportLayer( pLayer,ar,false ); // Also save all childs but not external layers.
|
||||
// Save xml file to disk.
|
||||
rootFileNode->saveToFile( file );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayerManager::LoadExternalLayer( const CString &layerName,CObjectArchive &archive )
|
||||
{
|
||||
// Form file name from layer name.
|
||||
CString file = Path::AddBackslash( GetIEditor()->GetGameEngine()->GetLevelPath() );
|
||||
file += m_layersPath + layerName + LAYER_FILE_EXTENSION;
|
||||
|
||||
XmlParser parser;
|
||||
XmlNodeRef root = parser.parse( file );
|
||||
if (!root)
|
||||
{
|
||||
CErrorRecord err;
|
||||
err.error.Format( _T("Failed to import external object layer <%s> from File %s"),(const char*)layerName,(const char*)file );
|
||||
err.file = file;
|
||||
err.severity = CErrorRecord::ESEVERITY_ERROR;
|
||||
archive.ReportError(err);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
XmlNodeRef layerDesc = root->findChild("Layer");
|
||||
if (layerDesc)
|
||||
{
|
||||
XmlNodeRef prevRoot = archive.node;
|
||||
archive.node = layerDesc;
|
||||
m_bOverwriteDuplicates = true;
|
||||
ImportLayer( archive,false );
|
||||
m_bOverwriteDuplicates = false;
|
||||
archive.node = prevRoot;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayerManager::ExportLayer( CObjectLayer *pLayer,CObjectArchive &ar,bool bExportExternalChilds )
|
||||
{
|
||||
pLayer->Serialize( ar.node,false );
|
||||
|
||||
XmlNodeRef orgNode = ar.node;
|
||||
XmlNodeRef layerObjects = ar.node->newChild("LayerObjects");
|
||||
ar.node = layerObjects;
|
||||
|
||||
std::vector<CBaseObject*> objects;
|
||||
GetIEditor()->GetObjectManager()->GetObjects( objects,pLayer );
|
||||
// Save all objects to XML.
|
||||
for (int i = 0; i < objects.size(); i++)
|
||||
{
|
||||
ar.SaveObject( objects[i] );
|
||||
}
|
||||
|
||||
if (pLayer->GetChildCount() > 0)
|
||||
{
|
||||
XmlNodeRef childLayers = orgNode->newChild("ChildLayers");
|
||||
// Export layer childs.
|
||||
for (int i = 0; i < pLayer->GetChildCount(); i++)
|
||||
{
|
||||
CObjectLayer *pChildLayer = pLayer->GetChild(i);
|
||||
if (pChildLayer->IsExternal() && !bExportExternalChilds)
|
||||
continue;
|
||||
|
||||
XmlNodeRef childLayer = childLayers->newChild("Layer");
|
||||
ar.node = childLayer;
|
||||
ExportLayer( pChildLayer,ar,bExportExternalChilds );
|
||||
}
|
||||
}
|
||||
|
||||
ar.node = orgNode;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CObjectLayer* CObjectLayerManager::ImportLayer( CObjectArchive &ar,bool bResolveObjects )
|
||||
{
|
||||
XmlNodeRef layerNode = ar.node;
|
||||
if (stricmp(layerNode->getTag(),"Layer") != 0)
|
||||
{
|
||||
CErrorRecord err;
|
||||
err.error.Format( _T("Not a valid Layer XML Node %s, Must be \"Layer\""),(const char*)layerNode->getTag() );
|
||||
err.severity = CErrorRecord::ESEVERITY_WARNING;
|
||||
ar.ReportError(err);
|
||||
|
||||
//Warning( "Not a valid Layer XML Node" );
|
||||
// Bad layer,Import fails.
|
||||
return 0;
|
||||
}
|
||||
TSmartPtr<CObjectLayer> pLayer = new CObjectLayer( this );
|
||||
pLayer->Serialize( layerNode,true );
|
||||
|
||||
CString layerName = pLayer->GetName();
|
||||
|
||||
bool bRemoveLayer = false;
|
||||
CObjectLayer *pPrevLayer = FindLayer( pLayer->GetGUID() );
|
||||
if (pPrevLayer)
|
||||
{
|
||||
if (m_bOverwriteDuplicates)
|
||||
{
|
||||
pLayer = pPrevLayer;
|
||||
pLayer->Serialize( layerNode,true ); // Serialize it again.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Duplicate layer imported.
|
||||
CString layerName = pPrevLayer->GetName();
|
||||
bRemoveLayer = true;
|
||||
CString str;
|
||||
str.Format( _T("Replace Layer %s?\r\nAll object of replaced layer will be deleted."),(const char*)layerName );
|
||||
if (AfxGetMainWnd()->MessageBox( str,_T("Confirm Replace Layer"),MB_YESNO|MB_ICONQUESTION) == IDNO)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
DeleteLayer(pPrevLayer);
|
||||
}
|
||||
}
|
||||
|
||||
if (pLayer)
|
||||
{
|
||||
AddLayer( pLayer );
|
||||
}
|
||||
|
||||
XmlNodeRef layerObjects = layerNode->findChild("LayerObjects");
|
||||
if (layerObjects)
|
||||
{
|
||||
int numObjects = layerObjects->getChildCount();
|
||||
if (bResolveObjects)
|
||||
m_pObjectManager->StartObjectsLoading( numObjects );
|
||||
//ar.node = layerObjects;
|
||||
//m_pObjectManager->LoadObjects( ar,false );
|
||||
ar.LoadObjects( layerObjects );
|
||||
|
||||
if (bResolveObjects)
|
||||
m_pObjectManager->EndObjectsLoading();
|
||||
}
|
||||
|
||||
XmlNodeRef childLayers = layerNode->findChild("ChildLayers");
|
||||
if (childLayers)
|
||||
{
|
||||
// Import child layers.
|
||||
for (int i = 0; i < childLayers->getChildCount(); i++)
|
||||
{
|
||||
XmlNodeRef childLayer = childLayers->getChild(i);
|
||||
ar.node = childLayer;
|
||||
CObjectLayer *pChildLayer = ImportLayer( ar,false );
|
||||
if (pChildLayer)
|
||||
{
|
||||
// Import child layers.
|
||||
pLayer->AddChild( pChildLayer );
|
||||
}
|
||||
}
|
||||
ar.node = layerNode;
|
||||
}
|
||||
|
||||
if (bResolveObjects)
|
||||
{
|
||||
ResolveLayerLinks();
|
||||
ar.ResolveObjects();
|
||||
}
|
||||
|
||||
return pLayer;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayerManager::SetCurrentLayer( CObjectLayer* pCurrLayer )
|
||||
{
|
||||
assert( pCurrLayer );
|
||||
if (pCurrLayer == m_pCurrentLayer)
|
||||
return;
|
||||
m_pCurrentLayer = pCurrLayer;
|
||||
NotifyListeners( ON_LAYER_SELECT,m_pCurrentLayer );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectLayerManager::ResolveLayerLinks()
|
||||
{
|
||||
for (LayersMap::const_iterator it = m_layersMap.begin(); it != m_layersMap.end(); ++it)
|
||||
{
|
||||
CObjectLayer *pLayer = it->second;
|
||||
if (!pLayer->IsRemovable())
|
||||
continue;
|
||||
|
||||
// Try to connect to parent layer.
|
||||
CObjectLayer *pNewParent = FindLayer( pLayer->m_parentGUID );
|
||||
|
||||
/*
|
||||
if (pNewParent == NULL && pLayer->GetParent() == m_pMainLayer)
|
||||
{
|
||||
// If parent is already main layer, skip.
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
if (pLayer->GetParent() != NULL && pLayer->GetParent() != pNewParent)
|
||||
{
|
||||
// Deatch from old parent layer.
|
||||
pLayer->GetParent()->RemoveChild( pLayer );
|
||||
}
|
||||
if (pNewParent)
|
||||
{
|
||||
// Attach to new parent layer.
|
||||
pNewParent->AddChild( pLayer );
|
||||
}
|
||||
|
||||
/*
|
||||
if (pLayer->GetParent() == NULL)
|
||||
{
|
||||
// all removable layers without parent must be attached to main layer.
|
||||
m_pMainLayer->AddChild( pLayer );
|
||||
}
|
||||
*/
|
||||
}
|
||||
NotifyListeners( ON_LAYER_UPDATEALL,0 );
|
||||
}
|
||||
115
Editor/Objects/ObjectLayerManager.h
Normal file
115
Editor/Objects/ObjectLayerManager.h
Normal file
@@ -0,0 +1,115 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: objectlayermanager.h
|
||||
// Version: v1.00
|
||||
// Created: 9/5/2003 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description: Manages objects layers.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __objectlayermanager_h__
|
||||
#define __objectlayermanager_h__
|
||||
#pragma once
|
||||
|
||||
#include "ObjectLayer.h"
|
||||
|
||||
class CObjectManager;
|
||||
class CObjectArchive;
|
||||
|
||||
/** Manager of objects layers.
|
||||
Instance of these hosted by CObjectManager class.
|
||||
*/
|
||||
class CObjectLayerManager
|
||||
{
|
||||
public:
|
||||
enum EUpdateType {
|
||||
ON_LAYER_ADD,
|
||||
ON_LAYER_REMOVE,
|
||||
ON_LAYER_MODIFY,
|
||||
ON_LAYER_SELECT,
|
||||
ON_LAYER_UPDATEALL
|
||||
};
|
||||
//! Update callback, first integer is one of EUpdateType enums.
|
||||
typedef Functor2<int,CObjectLayer*> LayersUpdateCallback;
|
||||
|
||||
CObjectLayerManager( CObjectManager *pObjectManager );
|
||||
|
||||
//! Creates a new layer, and associate it with layer manager.
|
||||
CObjectLayer* CreateLayer();
|
||||
//! Add already created layer to manager.
|
||||
void AddLayer( CObjectLayer *pLayer );
|
||||
//! Delete layer from layer manager.
|
||||
void DeleteLayer( CObjectLayer *pLayer );
|
||||
//! Delete all layers from layer manager.
|
||||
void ClearLayers();
|
||||
|
||||
//! Find layer by layer GUID.
|
||||
CObjectLayer* FindLayer( REFGUID guid ) const;
|
||||
|
||||
//! Search for layer by name.
|
||||
CObjectLayer* FindLayerByName( const CString &layerName ) const;
|
||||
|
||||
//! Get a list of all managed layers.
|
||||
void GetLayers( std::vector<CObjectLayer*> &layers ) const;
|
||||
|
||||
//! Set this layer is current.
|
||||
void SetCurrentLayer( CObjectLayer* pCurrLayer );
|
||||
CObjectLayer* GetCurrentLayer() const { return m_pCurrentLayer; };
|
||||
|
||||
//! Return root main layer.
|
||||
CObjectLayer* GetMainLayer() const { return m_pMainLayer; }
|
||||
|
||||
//! Associate On Layers update listener.
|
||||
//! This callback will be called everytime layers are added/removed or modified.
|
||||
void AddUpdateListener( const LayersUpdateCallback &cb );
|
||||
//! Remove update listeners.
|
||||
void RemoveUpdateListener( const LayersUpdateCallback &cb );
|
||||
|
||||
//! Called when some layers gets modified.
|
||||
void NotifyLayerChange( CObjectLayer *pLayer );
|
||||
|
||||
//! Get pointer to object manager who owns this layer manager.
|
||||
CObjectManager* GetObjectManager() const { return m_pObjectManager; }
|
||||
|
||||
//! Export layer to objects archive.
|
||||
void ExportLayer( CObjectLayer *pLayer,CObjectArchive &ar,bool bExportExternalChilds );
|
||||
//! Import layer from objects archive.
|
||||
CObjectLayer* ImportLayer( CObjectArchive &ar,bool bResolveObject );
|
||||
|
||||
// Serialize layer manager (called from object manager).
|
||||
void Serialize( CObjectArchive &ar,bool bIgnoreExternalLayers );
|
||||
|
||||
//! Resolve links between layers.
|
||||
void ResolveLayerLinks();
|
||||
|
||||
private:
|
||||
void SaveExternalLayer( CObjectLayer *pLayer,CObjectArchive &archive );
|
||||
void LoadExternalLayer( const CString &layerName,CObjectArchive &archive );
|
||||
void NotifyListeners( EUpdateType type,CObjectLayer *pLayer );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Map of layer GUID to layer pointer.
|
||||
typedef std::map<GUID,TSmartPtr<CObjectLayer>,guid_less_predicate> LayersMap;
|
||||
LayersMap m_layersMap;
|
||||
|
||||
//! Pointer to currently active layer.
|
||||
TSmartPtr<CObjectLayer> m_pCurrentLayer;
|
||||
//! Main layer, root for all other layers.
|
||||
TSmartPtr<CObjectLayer> m_pMainLayer;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CFunctorsList<LayersUpdateCallback> m_listeners;
|
||||
CObjectManager *m_pObjectManager;
|
||||
//! Layers path relative to level folder.
|
||||
CString m_layersPath;
|
||||
|
||||
bool m_bOverwriteDuplicates;
|
||||
};
|
||||
|
||||
#endif // __objectlayermanager_h__
|
||||
234
Editor/Objects/ObjectLoader.cpp
Normal file
234
Editor/Objects/ObjectLoader.cpp
Normal file
@@ -0,0 +1,234 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: objectloader.cpp
|
||||
// Version: v1.00
|
||||
// Created: 15/8/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "ObjectLoader.h"
|
||||
#include "ObjectManager.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CObjectArchive Implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CObjectArchive::CObjectArchive( IObjectManager *objMan,XmlNodeRef xmlRoot,bool loading )
|
||||
{
|
||||
m_objectManager = objMan;
|
||||
bLoading = loading;
|
||||
bUndo = false;
|
||||
m_bMakeNewIds = false;
|
||||
node = xmlRoot;
|
||||
m_pCurrentErrorReport = GetIEditor()->GetErrorReport();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CObjectArchive::~CObjectArchive()
|
||||
{
|
||||
// Always make sure objects are resolved when loading from archive.
|
||||
if (bLoading)
|
||||
{
|
||||
ResolveObjects();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectArchive::SetResolveCallback( CBaseObject *fromObject,REFGUID objectId,ResolveObjRefFunctor1 &func )
|
||||
{
|
||||
if (objectId == GUID_NULL)
|
||||
{
|
||||
func( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
CBaseObject *object = m_objectManager->FindObject( objectId );
|
||||
if (object && !m_bMakeNewIds)
|
||||
{
|
||||
// Object is already resolved. immidiatly call callback.
|
||||
func( object );
|
||||
}
|
||||
else
|
||||
{
|
||||
Callback cb;
|
||||
cb.fromObject = fromObject;
|
||||
cb.func1 = func;
|
||||
m_resolveCallbacks.insert( Callbacks::value_type(objectId,cb) );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectArchive::SetResolveCallback( CBaseObject *fromObject,REFGUID objectId,ResolveObjRefFunctor2 &func,uint userData )
|
||||
{
|
||||
if (objectId == GUID_NULL)
|
||||
{
|
||||
func( 0,userData );
|
||||
return;
|
||||
}
|
||||
|
||||
CBaseObject *object = m_objectManager->FindObject( objectId );
|
||||
if (object && !m_bMakeNewIds)
|
||||
{
|
||||
// Object is already resolved. immidiatly call callback.
|
||||
func( object,userData );
|
||||
}
|
||||
else
|
||||
{
|
||||
Callback cb;
|
||||
cb.fromObject = fromObject;
|
||||
cb.func2 = func;
|
||||
cb.userData = userData;
|
||||
m_resolveCallbacks.insert( Callbacks::value_type(objectId,cb) );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectArchive::ResolveObjects()
|
||||
{
|
||||
for (Callbacks::iterator it = m_resolveCallbacks.begin(); it != m_resolveCallbacks.end(); it++)
|
||||
{
|
||||
Callback &cb = it->second;
|
||||
GUID objectId = it->first;
|
||||
if (!m_IdRemap.empty())
|
||||
{
|
||||
objectId = stl::find_in_map( m_IdRemap,objectId,objectId );
|
||||
}
|
||||
CBaseObject *object = m_objectManager->FindObject(objectId);
|
||||
if (!object)
|
||||
{
|
||||
CString from;
|
||||
if (cb.fromObject)
|
||||
{
|
||||
from = cb.fromObject->GetName();
|
||||
}
|
||||
// Cannot resolve this object id.
|
||||
CErrorRecord err;
|
||||
err.error.Format( _T("Unresolved ObjectID: %s, Referenced from Object %s"),GuidUtil::ToString(objectId),
|
||||
(const char*)from );
|
||||
err.severity = CErrorRecord::ESEVERITY_ERROR;
|
||||
err.flags = CErrorRecord::FLAG_OBJECTID;
|
||||
err.pObject = cb.fromObject;
|
||||
GetIEditor()->GetErrorReport()->ReportError(err);
|
||||
|
||||
//Warning( "Cannot resolve ObjectID: %s\r\nObject with this ID was not present in loaded file.\r\nFor instance Trigger referencing another object which is not loaded in Level.",GuidUtil::ToString(objectId) );
|
||||
continue;
|
||||
}
|
||||
m_pCurrentErrorReport->SetCurrentValidatorObject( object );
|
||||
// Call callback with this object.
|
||||
if (cb.func1)
|
||||
(cb.func1)( object );
|
||||
if (cb.func2)
|
||||
(cb.func2)( object,cb.userData );
|
||||
}
|
||||
m_resolveCallbacks.clear();
|
||||
|
||||
/*
|
||||
// Send After Load event for all loaded objects.
|
||||
for (SavedObjects::iterator it = m_savedObjects.begin(); it != m_savedObjects.end(); ++it)
|
||||
{
|
||||
CBaseObject *pObject = *it;
|
||||
if (!pObject->GetGroup())
|
||||
pObject->OnEvent( EVENT_AFTER_LOAD );
|
||||
}
|
||||
*/
|
||||
|
||||
// Create GameObject for all loaded objects.
|
||||
for (OrderedObjects::iterator it = m_orderedObjects.begin(); it != m_orderedObjects.end(); ++it)
|
||||
{
|
||||
CBaseObject *pObject = it->second;
|
||||
m_pCurrentErrorReport->SetCurrentValidatorObject( pObject );
|
||||
pObject->CreateGameObject();
|
||||
}
|
||||
m_pCurrentErrorReport->SetCurrentValidatorObject( NULL );
|
||||
|
||||
// Send After Load event for all loaded objects.
|
||||
m_objectManager->SendEvent( EVENT_AFTER_LOAD );
|
||||
|
||||
m_objectsSet.clear();
|
||||
m_orderedObjects.clear();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectArchive::SaveObject( CBaseObject *pObject )
|
||||
{
|
||||
if (m_objectsSet.find(pObject) == m_objectsSet.end())
|
||||
{
|
||||
m_objectsSet.insert( pObject );
|
||||
// If this object was not saved before.
|
||||
XmlNodeRef objNode = node->newChild( "Object" );
|
||||
XmlNodeRef prevRoot = node;
|
||||
node = objNode;
|
||||
pObject->Serialize( *this );
|
||||
node = prevRoot;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CBaseObject* CObjectArchive::LoadObject( XmlNodeRef &objNode,CBaseObject *pPrevObject )
|
||||
{
|
||||
XmlNodeRef prevNode = node;
|
||||
node = objNode;
|
||||
CBaseObject *pObject;
|
||||
|
||||
pObject = m_objectManager->NewObject( *this,pPrevObject,m_bMakeNewIds );
|
||||
if (pObject)
|
||||
{
|
||||
m_objectsSet.insert( pObject );
|
||||
int sortOrder = pObject->GetClassDesc()->GameCreationOrder();
|
||||
m_orderedObjects.insert( OrderedObjects::value_type(sortOrder,pObject) );
|
||||
}
|
||||
node = prevNode;
|
||||
return pObject;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectArchive::LoadObjects( XmlNodeRef &rootObjectsNode )
|
||||
{
|
||||
int numObjects = rootObjectsNode->getChildCount();
|
||||
for (int i = 0; i < numObjects; i++)
|
||||
{
|
||||
XmlNodeRef objNode = rootObjectsNode->getChild(i);
|
||||
LoadObject( objNode );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectArchive::ReportError( CErrorRecord &err )
|
||||
{
|
||||
if (m_pCurrentErrorReport)
|
||||
m_pCurrentErrorReport->ReportError( err );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectArchive::SetErrorReport( CErrorReport *errReport )
|
||||
{
|
||||
if (errReport)
|
||||
m_pCurrentErrorReport = errReport;
|
||||
else
|
||||
m_pCurrentErrorReport = GetIEditor()->GetErrorReport();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectArchive::ShowErrors()
|
||||
{
|
||||
GetIEditor()->GetErrorReport()->Display();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectArchive::MakeNewIds( bool bEnable )
|
||||
{
|
||||
m_bMakeNewIds = bEnable;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CObjectArchive::RemapID( REFGUID oldId,REFGUID newId )
|
||||
{
|
||||
m_IdRemap[oldId] = newId;
|
||||
}
|
||||
104
Editor/Objects/ObjectLoader.h
Normal file
104
Editor/Objects/ObjectLoader.h
Normal file
@@ -0,0 +1,104 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: objectloader.h
|
||||
// Version: v1.00
|
||||
// Created: 15/8/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __objectloader_h__
|
||||
#define __objectloader_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "ErrorReport.h"
|
||||
|
||||
/** CObjectLoader used to load Bas Object and resolve ObjectId references while loading.
|
||||
*/
|
||||
class CObjectArchive
|
||||
{
|
||||
public:
|
||||
XmlNodeRef node; //!< Current archive node.
|
||||
bool bLoading;
|
||||
bool bUndo;
|
||||
|
||||
CObjectArchive( IObjectManager *objMan,XmlNodeRef xmlRoot,bool loading );
|
||||
~CObjectArchive();
|
||||
|
||||
//! Resolve callback with only one parameter of CBaseObject.
|
||||
typedef Functor1<CBaseObject*> ResolveObjRefFunctor1;
|
||||
//! Resolve callback with two parameters one is pointer to CBaseObject and second use data integer.
|
||||
typedef Functor2<CBaseObject*,unsigned int> ResolveObjRefFunctor2;
|
||||
|
||||
/** Register Object id.
|
||||
@param objectId Original object id from the file.
|
||||
@param realObjectId Changed object id.
|
||||
*/
|
||||
//void RegisterObjectId( int objectId,int realObjectId );
|
||||
|
||||
//! Set object resolve callback, it will be called once object with specified Id is loaded.
|
||||
void SetResolveCallback( CBaseObject *fromObject,REFGUID objectId,ResolveObjRefFunctor1 &func );
|
||||
//! Set object resolve callback, it will be called once object with specified Id is loaded.
|
||||
void SetResolveCallback( CBaseObject *fromObject,REFGUID objectId,ResolveObjRefFunctor2 &func,uint userData );
|
||||
//! Resolve all object ids and call callbacks on resolved objects.
|
||||
void ResolveObjects();
|
||||
|
||||
// Save object to archive.
|
||||
void SaveObject( CBaseObject *pObject );
|
||||
|
||||
//! Load multiple objects from archive.
|
||||
void LoadObjects( XmlNodeRef &rootObjectsNode );
|
||||
|
||||
//! Load one object from archive.
|
||||
CBaseObject* LoadObject( XmlNodeRef &objNode,CBaseObject *pPrevObject=NULL );
|
||||
|
||||
//! If true new loaded objects will be assigned new GUIDs.
|
||||
void MakeNewIds( bool bEnable );
|
||||
|
||||
//! Remap object ids.
|
||||
void RemapID( REFGUID oldId,REFGUID newId );
|
||||
|
||||
//! Report error during loading.
|
||||
void ReportError( CErrorRecord &err );
|
||||
//! Assigner different error report class.
|
||||
void SetErrorReport( CErrorReport *errReport );
|
||||
//! Display collected error reports.
|
||||
void ShowErrors();
|
||||
|
||||
private:
|
||||
IObjectManager* m_objectManager;
|
||||
struct Callback {
|
||||
ResolveObjRefFunctor1 func1;
|
||||
ResolveObjRefFunctor2 func2;
|
||||
uint userData;
|
||||
TSmartPtr<CBaseObject> fromObject;
|
||||
Callback() { func1 = 0; func2 = 0; userData = 0; };
|
||||
};
|
||||
typedef std::multimap<GUID,Callback,guid_less_predicate> Callbacks;
|
||||
Callbacks m_resolveCallbacks;
|
||||
|
||||
// Set of all saved objects to this archive.
|
||||
typedef std::set<CBaseObject*> ObjectsSet;
|
||||
ObjectsSet m_objectsSet;
|
||||
|
||||
typedef std::multimap<int,CBaseObject*> OrderedObjects;
|
||||
OrderedObjects m_orderedObjects;
|
||||
|
||||
// Loaded objects IDs, used for remapping of GUIDs.
|
||||
std::map<GUID,GUID,guid_less_predicate> m_IdRemap;
|
||||
|
||||
//! If true new loaded objects will be assigned new GUIDs.
|
||||
bool m_bMakeNewIds;
|
||||
CErrorReport *m_pCurrentErrorReport;
|
||||
};
|
||||
|
||||
#endif // __objectloader_h__
|
||||
1879
Editor/Objects/ObjectManager.cpp
Normal file
1879
Editor/Objects/ObjectManager.cpp
Normal file
File diff suppressed because it is too large
Load Diff
308
Editor/Objects/ObjectManager.h
Normal file
308
Editor/Objects/ObjectManager.h
Normal file
@@ -0,0 +1,308 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: ObjectManager.h
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: ObjectManager definition.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __ObjectManager_h__
|
||||
#define __ObjectManager_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "IObjectManager.h"
|
||||
#include "BaseObject.h"
|
||||
#include "SelectionGroup.h"
|
||||
#include "ClassDesc.h"
|
||||
#include "ObjectLayer.h"
|
||||
#include "ObjectLayerManager.h"
|
||||
|
||||
// forward declarations.
|
||||
class CGizmoManager;
|
||||
class CCameraObject;
|
||||
|
||||
/*!
|
||||
* CObjectManager is a singleton object that
|
||||
* manages global set of objects in level.
|
||||
*/
|
||||
class CObjectManager : public IObjectManager
|
||||
{
|
||||
public:
|
||||
//! Selection functor callback.
|
||||
//! Callback function must return a boolean value.
|
||||
//! Return true if selection should proceed, or false to abort object selection.
|
||||
CObjectManager();
|
||||
~CObjectManager();
|
||||
|
||||
void RegisterObjectClasses();
|
||||
|
||||
CBaseObject* NewObject( CObjectClassDesc *cls,CBaseObject *prev=0,const CString &file="" );
|
||||
CBaseObject* NewObject( const CString &typeName,CBaseObject *prev=0,const CString &file="" );
|
||||
|
||||
/** Creates and serialize object from xml node.
|
||||
@param objectNode Xml node to serialize object info from.
|
||||
@param pUndoObject Pointer to deleted object for undo.
|
||||
*/
|
||||
CBaseObject* NewObject( CObjectArchive &archive,CBaseObject *pUndoObject=0,bool bMakeNewId=false );
|
||||
|
||||
void DeleteObject( CBaseObject *obj );
|
||||
void DeleteAllObjects();
|
||||
CBaseObject* CloneObject( CBaseObject *obj );
|
||||
|
||||
void BeginEditParams( CBaseObject *obj,int flags );
|
||||
void EndEditParams( int flags=0 );
|
||||
|
||||
//! Get number of objects manager by ObjectManager, (not contain sub objects of groups).
|
||||
int GetObjectCount() const;
|
||||
|
||||
//! Get array of objects, managed by manager, (not contain sub objects of groups).
|
||||
//! @param layer if 0 get objects for all layers, or layer to get objects from.
|
||||
void GetObjects( CBaseObjectsArray &objects,CObjectLayer *layer=0 );
|
||||
|
||||
//! Get all camera sources in object manager
|
||||
void GetCameras( std::vector<CCameraObject*> &objects );
|
||||
|
||||
//! Update objects.
|
||||
void Update();
|
||||
|
||||
//! Display objects on display context.
|
||||
void Display( DisplayContext &dc );
|
||||
|
||||
//! Check intersection with objects.
|
||||
//! Find intersection with nearest to ray origin object hit by ray.
|
||||
//! If distance tollerance is specified certain relaxation applied on collision test.
|
||||
//! @return true if hit any object, and fills hitInfo structure.
|
||||
bool HitTest( Vec3 &raySrc,Vec3 &rayDir,float distanceTollerance,ObjectHitInfo &hitInfo );
|
||||
|
||||
//! Send event to all objects.
|
||||
//! Will cause OnEvent handler to be called on all objects.
|
||||
void SendEvent( ObjectEvent event );
|
||||
|
||||
//! Send event to all objects within givven bounding box.
|
||||
//! Will cause OnEvent handler to be called on objects withing bounding box.
|
||||
void SendEvent( ObjectEvent event,const BBox &bounds );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Find object by ID.
|
||||
CBaseObject* FindObject( REFGUID guid ) const;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Find object by name.
|
||||
CBaseObject* FindObject( const CString &sName ) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Find BaseObject who is owner of specified animation node.
|
||||
CBaseObject* FindAnimNodeOwner( IAnimNode* node ) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Operations on objects.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Makes object visible or invisible.
|
||||
void HideObject( CBaseObject *obj,bool hide );
|
||||
//! Freeze object, making it unselectable.
|
||||
void FreezeObject( CBaseObject *obj,bool freeze );
|
||||
//! Unhide all hidden objects.
|
||||
void UnhideAll();
|
||||
//! Unfreeze all frozen objects.
|
||||
void UnfreezeAll();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Object Selection.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool SelectObject( CBaseObject *obj );
|
||||
void UnselectObject( CBaseObject *obj );
|
||||
|
||||
//! Select objects withing specified distance from givven position.
|
||||
//! Return number of selected objects.
|
||||
int SelectObjects( const BBox &box,bool bUnselect=false );
|
||||
|
||||
//! Selects/Unselects all objects within 2d rectangle in given viewport.
|
||||
void SelectObjectsInRect( CViewport *view,const CRect &rect,bool bSelect );
|
||||
|
||||
//! Clear default selection set.
|
||||
//! @Return number of objects removed from selection.
|
||||
int ClearSelection();
|
||||
|
||||
//! Deselect all current selected objects and selects object that were unselected.
|
||||
//! @Return number of selected objects.
|
||||
int InvertSelection();
|
||||
|
||||
//! Get current selection.
|
||||
CSelectionGroup* GetSelection() const { return m_currSelection; };
|
||||
//! Get named selection.
|
||||
CSelectionGroup* GetSelection( const CString &name ) const;
|
||||
//! Change name of current selection group.
|
||||
//! And store it in list.
|
||||
void NameSelection( const CString &name );
|
||||
//! Set one of name selections as current selection.
|
||||
void SetSelection( const CString &name );
|
||||
void RemoveSelection( const CString &name );
|
||||
|
||||
//! Delete all objects in selection group.
|
||||
void DeleteSelection();
|
||||
|
||||
//! Generates uniq name base on type name of object.
|
||||
CString GenUniqObjectName( const CString &typeName );
|
||||
//! Register object name in object manager, needed for generating uniq names.
|
||||
void RegisterObjectName( const CString &name );
|
||||
//! Enable/Disable generating of unique object names (Enabled by default).
|
||||
//! Return previous value.
|
||||
bool EnableUniqObjectNames( bool bEnable );
|
||||
|
||||
//! Register XML template of runtime class.
|
||||
void RegisterClassTemplate( XmlNodeRef &templ );
|
||||
//! Load class templates for specified directory,
|
||||
void LoadClassTemplates( const CString &path );
|
||||
|
||||
//! Find object class by name.
|
||||
CObjectClassDesc* FindClass( const CString &className );
|
||||
void GetClassCategories( std::vector<CString> &categories );
|
||||
void GetClassTypes( const CString &category,std::vector<CString> &types );
|
||||
|
||||
//! Export objects to xml.
|
||||
//! When onlyShared is true ony objects with shared flags exported, overwise only not shared object exported.
|
||||
void Export( const CString &levelPath,XmlNodeRef &rootNode,bool onlyShared );
|
||||
|
||||
//! Serialize Objects in manager to specified XML Node.
|
||||
//! @param flags Can be one of SerializeFlags.
|
||||
void Serialize( XmlNodeRef &rootNode,bool bLoading,int flags=SERIALIZE_ALL );
|
||||
|
||||
//! Load objects from object archive.
|
||||
//! @param bSelect if set newly loaded object will be selected.
|
||||
void LoadObjects( CObjectArchive &ar,bool bSelect );
|
||||
|
||||
//! Delete from Object manager all objects without SHARED flag.
|
||||
void DeleteNotSharedObjects();
|
||||
//! Delete from Object manager all objects with SHARED flag.
|
||||
void DeleteSharedObjects();
|
||||
|
||||
bool AddObject( CBaseObject *obj );
|
||||
void RemoveObject( CBaseObject *obj );
|
||||
void ChangeObjectId( CBaseObject *obj,int newId );
|
||||
void ChangeObjectName( CBaseObject *obj,const CString &newName );
|
||||
|
||||
//! Convert object of one type to object of another type.
|
||||
//! Original object is deleted.
|
||||
bool ConvertToType( CBaseObject *object,ObjectType objectType );
|
||||
|
||||
//! Set new selection callback.
|
||||
//! @return previous selection callback.
|
||||
IObjectSelectCallback* SetSelectCallback( IObjectSelectCallback* callback );
|
||||
|
||||
// Enables/Disables creating of game objects.
|
||||
void SetCreateGameObject( bool enable ) { m_createGameObjects = enable; };
|
||||
//! Return true if objects loaded from xml should immidiatly create game objects associated with them.
|
||||
bool IsCreateGameObjects() const { return m_createGameObjects; };
|
||||
|
||||
//void ExportLayer( CObjectLayer *pLayer,CObjectArchive &ar );
|
||||
//CObjectLayer* ImportLayer( CObjectArchive &ar );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Get access to gizmo manager.
|
||||
IGizmoManager* GetGizmoManager();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Get acess to object layers manager.
|
||||
CObjectLayerManager* GetLayersManager() const { return m_pLayerManager; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Invalidate visibily settings of objects.
|
||||
void InvalidateVisibleList();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ObjectManager notification Callbacks.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void AddObjectEventListener( const EventCallback &cb );
|
||||
void RemoveObjectEventListener( const EventCallback &cb );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Used to indicate starting and ending of objects loading.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void StartObjectsLoading( int numObjects );
|
||||
void EndObjectsLoading();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Gathers all resources used by all objects.
|
||||
void GatherUsedResources( CUsedResources &resources );
|
||||
|
||||
private:
|
||||
//! Update visibility of all objects.
|
||||
void UpdateVisibilityList();
|
||||
//! Get array of all objects in manager.
|
||||
void GetAllObjects( std::vector<CBaseObjectPtr> &objects ) const;
|
||||
|
||||
void UnselectCurrent();
|
||||
void SelectCurrent();
|
||||
void SetObjectSelected( CBaseObject* pObject,bool bSelect );
|
||||
|
||||
void SaveRegistry();
|
||||
void LoadRegistry();
|
||||
|
||||
void NotifyObjectListeners( CBaseObject *pObject,CBaseObject::EObjectListenerEvent event );
|
||||
|
||||
private:
|
||||
typedef std::map<GUID,CBaseObjectPtr,guid_less_predicate> Objects;
|
||||
Objects m_objects;
|
||||
|
||||
std::map<CString,CSelectionGroup*> m_selections;
|
||||
|
||||
//! Array of currently visible objects.
|
||||
std::vector<CBaseObjectPtr> m_visibleObjects;
|
||||
bool m_bVisibleObjectValid;
|
||||
unsigned int m_lastHideMask;
|
||||
//! List of objects that was displayed at last frame.
|
||||
std::vector<CBaseObject*> m_displayedObjects;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Selection.
|
||||
//! Current selection group.
|
||||
CSelectionGroup* m_currSelection;
|
||||
int m_nLastSelCount;
|
||||
bool m_bSelectionChanged;
|
||||
IObjectSelectCallback* m_selectCallback;
|
||||
|
||||
//! Default selection.
|
||||
CSelectionGroup m_defaultSelection;
|
||||
|
||||
CBaseObjectPtr m_currEditObject;
|
||||
bool m_bSingleSelection;
|
||||
|
||||
bool m_createGameObjects;
|
||||
bool m_bGenUniqObjectNames;
|
||||
|
||||
// Object manager also handles Gizmo manager.
|
||||
CGizmoManager* m_gizmoManager;
|
||||
|
||||
friend CObjectLayerManager;
|
||||
//! Manager of object layers.
|
||||
CObjectLayerManager* m_pLayerManager;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Loading progress.
|
||||
CWaitProgress *m_pLoadProgress;
|
||||
int m_loadedObjects;
|
||||
int m_totalObjectsToLoad;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Numbering for names.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
typedef std::map<CString,int,stl::less_stricmp<CString> > NameNumbersMap;
|
||||
NameNumbersMap m_nameNumbersMap;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Listeners.
|
||||
std::list<EventCallback> m_objectEventListeners;
|
||||
};
|
||||
|
||||
#endif // __ObjectManager_h__
|
||||
495
Editor/Objects/PrefabObject.cpp
Normal file
495
Editor/Objects/PrefabObject.cpp
Normal file
@@ -0,0 +1,495 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001-2004.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: PrefabObject.cpp
|
||||
// Version: v1.00
|
||||
// Created: 13/11/2003 by Timur.
|
||||
// Compilers: Visual Studio.NET 2003
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "PrefabObject.h"
|
||||
|
||||
#include "ObjectManager.h"
|
||||
#include "Prefabs\PrefabManager.h"
|
||||
#include "Prefabs\PrefabItem.h"
|
||||
#include "PrefabPanel.h"
|
||||
|
||||
#include "..\Viewport.h"
|
||||
#include "..\DisplaySettings.h"
|
||||
#include "Settings.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CPrefabObject implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CPrefabObject,CBaseObject)
|
||||
|
||||
namespace
|
||||
{
|
||||
int s_rollupId = 0;
|
||||
CPrefabPanel *s_panel = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CPrefabObject::CPrefabObject()
|
||||
{
|
||||
SetColor( RGB(255,220,0) ); // Yellowish
|
||||
ZeroStruct(m_prefabGUID);
|
||||
|
||||
m_bbox.min = m_bbox.max = Vec3(0,0,0);
|
||||
m_bBBoxValid = false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::Done()
|
||||
{
|
||||
GetIEditor()->SuspendUndo();
|
||||
DeleteAllPrefabObjects();
|
||||
GetIEditor()->ResumeUndo();
|
||||
CBaseObject::Done();
|
||||
|
||||
ZeroStruct(m_prefabGUID);
|
||||
m_prefabName = "";
|
||||
m_pPrefabItem = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CPrefabObject::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
bool res = CBaseObject::Init( ie,prev,file );
|
||||
if (prev)
|
||||
{
|
||||
// Cloning.
|
||||
SetPrefab( ((CPrefabObject*)prev)->m_pPrefabItem,false );
|
||||
}
|
||||
else if (!file.IsEmpty())
|
||||
{
|
||||
SetPrefab( GuidUtil::FromString(file),false );
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::BeginEditParams( IEditor *ie,int flags )
|
||||
{
|
||||
CBaseObject::BeginEditParams( ie,flags );
|
||||
|
||||
if (!s_panel)
|
||||
{
|
||||
s_panel = new CPrefabPanel;
|
||||
s_rollupId = ie->AddRollUpPage( ROLLUP_OBJECTS,"Prefab Parameters",s_panel );
|
||||
}
|
||||
if (s_panel)
|
||||
s_panel->SetObject( this );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::EndEditParams( IEditor *ie )
|
||||
{
|
||||
if (s_panel)
|
||||
{
|
||||
ie->RemoveRollUpPage( ROLLUP_OBJECTS,s_rollupId );
|
||||
}
|
||||
s_rollupId = 0;
|
||||
s_panel = 0;
|
||||
|
||||
CBaseObject::EndEditParams( ie );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::GetBoundBox( BBox &box )
|
||||
{
|
||||
if (!m_bBBoxValid)
|
||||
CalcBoundBox();
|
||||
box = m_bbox;
|
||||
box.Transform( GetWorldTM() );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::GetLocalBounds( BBox &box )
|
||||
{
|
||||
if (!m_bBBoxValid)
|
||||
CalcBoundBox();
|
||||
box = m_bbox;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::Display( DisplayContext &dc )
|
||||
{
|
||||
DrawDefault(dc,GetColor());
|
||||
|
||||
dc.PushMatrix( GetWorldTM() );
|
||||
|
||||
bool bSelected = IsSelected();
|
||||
if (bSelected)
|
||||
{
|
||||
dc.SetSelectedColor();
|
||||
dc.DrawWireBox( m_bbox.min,m_bbox.max );
|
||||
|
||||
int rstate = dc.ClearStateFlag( GS_DEPTHWRITE );
|
||||
dc.SetSelectedColor( 0.2f );
|
||||
dc.DrawSolidBox( m_bbox.min,m_bbox.max );
|
||||
dc.SetState( rstate );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gSettings.viewports.bAlwaysDrawPrefabBox)
|
||||
{
|
||||
if (IsFrozen())
|
||||
dc.SetFreezeColor();
|
||||
else
|
||||
dc.SetColor( GetColor(),0.2f );
|
||||
|
||||
int rstate = dc.ClearStateFlag( GS_DEPTHWRITE );
|
||||
dc.DrawSolidBox( m_bbox.min,m_bbox.max );
|
||||
dc.SetState( rstate );
|
||||
}
|
||||
if (IsFrozen())
|
||||
dc.SetFreezeColor();
|
||||
else
|
||||
dc.SetColor( GetColor() );
|
||||
dc.DrawWireBox( m_bbox.min,m_bbox.max );
|
||||
}
|
||||
dc.PopMatrix();
|
||||
|
||||
if (bSelected || gSettings.viewports.bAlwaysDrawPrefabInternalObjects || IsHighlighted())
|
||||
{
|
||||
if (HaveChilds())
|
||||
{
|
||||
int numObjects = GetChildCount();
|
||||
for (int i = 0; i < numObjects; i++)
|
||||
{
|
||||
RecursivelyDisplayObject( GetChild(i),dc );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::RecursivelyDisplayObject( CBaseObject *obj,DisplayContext &dc )
|
||||
{
|
||||
if (!obj->CheckFlags(OBJFLAG_PREFAB))
|
||||
return;
|
||||
|
||||
BBox bbox;
|
||||
obj->GetBoundBox( bbox );
|
||||
if (dc.flags & DISPLAY_2D)
|
||||
{
|
||||
if (dc.box.IsIntersectBox( bbox ))
|
||||
{
|
||||
obj->Display( dc );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dc.camera && dc.camera->IsAABBVisibleFast( AABB(bbox.min,bbox.max) ))
|
||||
//if (camera.CheckOverlap(AABB(bbox.min,bbox.max)) != CULL_EXCLUSION)
|
||||
{
|
||||
obj->Display( dc );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int numObjects = obj->GetChildCount();
|
||||
for (int i = 0; i < numObjects; i++)
|
||||
{
|
||||
RecursivelyDisplayObject( obj->GetChild(i),dc );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::Serialize( CObjectArchive &ar )
|
||||
{
|
||||
CBaseObject::Serialize( ar );
|
||||
|
||||
if (ar.bLoading)
|
||||
{
|
||||
// Loading.
|
||||
CString prefabName = m_prefabName;
|
||||
GUID prefabGUID = m_prefabGUID;
|
||||
ar.node->getAttr( "PrefabName",prefabName );
|
||||
ar.node->getAttr( "PrefabGUID",prefabGUID );
|
||||
SetPrefab( prefabGUID,false );
|
||||
}
|
||||
else
|
||||
{
|
||||
ar.node->setAttr( "PrefabGUID",m_prefabGUID );
|
||||
ar.node->setAttr( "PrefabName",m_prefabName );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
XmlNodeRef CPrefabObject::Export( const CString &levelPath,XmlNodeRef &xmlNode )
|
||||
{
|
||||
// Do not export.
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::OnEvent( ObjectEvent event )
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case EVENT_PREFAB_REMAKE:
|
||||
if (m_pPrefabItem)
|
||||
SetPrefab( m_pPrefabItem,true );
|
||||
break;
|
||||
};
|
||||
CBaseObject::OnEvent( event );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
inline void RecursivelyGetAllPrefabChilds( CBaseObject *obj,std::vector<CBaseObjectPtr> &childs )
|
||||
{
|
||||
for (int i = 0; i < obj->GetChildCount(); i++)
|
||||
{
|
||||
CBaseObject *c = obj->GetChild(i);
|
||||
if (c->CheckFlags(OBJFLAG_PREFAB))
|
||||
{
|
||||
childs.push_back(c);
|
||||
RecursivelyGetAllPrefabChilds( c,childs );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::DeleteAllPrefabObjects()
|
||||
{
|
||||
std::vector<CBaseObjectPtr> childs;
|
||||
RecursivelyGetAllPrefabChilds( this,childs );
|
||||
for (int i = 0; i < childs.size(); i++)
|
||||
{
|
||||
GetObjectManager()->DeleteObject(childs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::SetPrefab( REFGUID guid,bool bForceReload )
|
||||
{
|
||||
if (m_prefabGUID == guid && bForceReload == false)
|
||||
return;
|
||||
|
||||
m_prefabGUID = guid;
|
||||
|
||||
//m_fullPrototypeName = prototypeName;
|
||||
CPrefabManager *pManager = GetIEditor()->GetPrefabManager();
|
||||
CPrefabItem *pPrefab = (CPrefabItem*)pManager->FindItem( guid );
|
||||
if (pPrefab)
|
||||
{
|
||||
SetPrefab( pPrefab,bForceReload );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_prefabName.IsEmpty())
|
||||
m_prefabName = "Unknown Prefab";
|
||||
|
||||
CErrorRecord err;
|
||||
err.error.Format( "Cannot find Prefab %s with GUID: %s for Object %s",(const char*)m_prefabName,GuidUtil::ToString(guid),(const char*)GetName() );
|
||||
err.pObject = this;
|
||||
err.severity = CErrorRecord::ESEVERITY_WARNING;
|
||||
GetIEditor()->GetErrorReport()->ReportError(err);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::SetPrefab( CPrefabItem *pPrefab,bool bForceReload )
|
||||
{
|
||||
assert( pPrefab );
|
||||
|
||||
if (pPrefab == m_pPrefabItem && !bForceReload)
|
||||
return;
|
||||
|
||||
StoreUndo( "Set Prefab" );
|
||||
|
||||
// Delete all child objects.
|
||||
DeleteAllPrefabObjects();
|
||||
|
||||
m_pPrefabItem = pPrefab;
|
||||
m_prefabGUID = pPrefab->GetGUID();
|
||||
m_prefabName = pPrefab->GetFullName();
|
||||
|
||||
// Make objects from this prefab.
|
||||
XmlNodeRef objects = pPrefab->GetObjectsNode();
|
||||
if (!objects)
|
||||
{
|
||||
CErrorRecord err;
|
||||
err.error.Format( "Prefab %s does not contain objects",(const char*)m_prefabName );
|
||||
err.pObject = this;
|
||||
err.severity = CErrorRecord::ESEVERITY_WARNING;
|
||||
GetIEditor()->GetErrorReport()->ReportError(err);
|
||||
return;
|
||||
}
|
||||
|
||||
CObjectLayer *pThisLayer = GetLayer();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Spawn objects.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CObjectArchive ar( GetObjectManager(),objects,true );
|
||||
ar.MakeNewIds( true );
|
||||
int numObjects = objects->getChildCount();
|
||||
for (int i = 0; i < numObjects; i++)
|
||||
{
|
||||
ar.node = objects->getChild(i);
|
||||
CBaseObject *obj = ar.LoadObject( ar.node );
|
||||
if (obj)
|
||||
{
|
||||
AttachChild( obj,false );
|
||||
RecursivelySetObjectInPrefab( obj );
|
||||
}
|
||||
}
|
||||
InvalidateBBox();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CPrefabItem* CPrefabObject::GetPrefab() const
|
||||
{
|
||||
return m_pPrefabItem;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::RecursivelySetObjectInPrefab( CBaseObject *object )
|
||||
{
|
||||
object->SetFlags( OBJFLAG_PREFAB );
|
||||
object->SetLayer( GetLayer() );
|
||||
|
||||
int numChilds = object->GetChildCount();
|
||||
for (int i = 0; i < numChilds; i++)
|
||||
{
|
||||
RecursivelySetObjectInPrefab( object->GetChild(i) );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::PostClone( CBaseObject *pFromObject,CObjectCloneContext &ctx )
|
||||
{
|
||||
CBaseObject *pFromParent = pFromObject->GetParent();
|
||||
if (pFromParent)
|
||||
{
|
||||
CBaseObject *pChildParent = ctx.FindClone( pFromParent );
|
||||
if (pChildParent)
|
||||
pChildParent->AttachChild( this,false );
|
||||
else
|
||||
pFromParent->AttachChild( this,false );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CPrefabObject::HitTest( HitContext &hc )
|
||||
{
|
||||
Vec3 pnt;
|
||||
|
||||
Vec3 raySrc = hc.raySrc;
|
||||
Vec3 rayDir = hc.rayDir;
|
||||
|
||||
Matrix44 invertTM = GetWorldTM();
|
||||
invertTM.Invert44();
|
||||
raySrc = invertTM.TransformPointOLD( raySrc );
|
||||
rayDir = GetNormalized( invertTM.TransformVectorOLD( rayDir ) );
|
||||
|
||||
if (m_bbox.IsIntersectRay( raySrc,rayDir,pnt ))
|
||||
{
|
||||
// World space distance.
|
||||
float dist = GetDistance(hc.raySrc, GetWorldTM().TransformPointOLD(pnt));
|
||||
hc.dist = dist;
|
||||
hc.object = this;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::ExtractAll()
|
||||
{
|
||||
int i;
|
||||
// Clone all child objects.
|
||||
CSelectionGroup sel;
|
||||
for (i = 0; i < GetChildCount(); i++)
|
||||
{
|
||||
sel.AddObject( GetChild(i) );
|
||||
}
|
||||
CSelectionGroup newSel;
|
||||
sel.Clone( newSel );
|
||||
|
||||
GetIEditor()->ClearSelection();
|
||||
for (i = 0; i < newSel.GetCount(); i++)
|
||||
{
|
||||
CBaseObject *pClone = newSel.GetObject(i);
|
||||
pClone->DetachThis(); // Detach from parent.
|
||||
GetIEditor()->SelectObject( pClone );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::ExtractObject( CBaseObject *pObj )
|
||||
{
|
||||
int i;
|
||||
// Clone all child objects.
|
||||
CSelectionGroup sel;
|
||||
sel.AddObject( pObj );
|
||||
|
||||
CSelectionGroup newSel;
|
||||
sel.Clone( newSel );
|
||||
|
||||
GetIEditor()->ClearSelection();
|
||||
for (i = 0; i < newSel.GetCount(); i++)
|
||||
{
|
||||
CBaseObject *pClone = newSel.GetObject(i);
|
||||
pClone->DetachThis(); // Detach from parent.
|
||||
GetIEditor()->SelectObject( pClone );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
inline void RecursivelyGetPrefabBoundBox( CBaseObject *object,BBox &box )
|
||||
{
|
||||
BBox b;
|
||||
object->GetBoundBox( b );
|
||||
box.Add(b.min);
|
||||
box.Add(b.max);
|
||||
|
||||
int numChilds = object->GetChildCount();
|
||||
for (int i = 0; i < numChilds; i++)
|
||||
{
|
||||
if (object->GetChild(i)->CheckFlags(OBJFLAG_PREFAB))
|
||||
RecursivelyGetPrefabBoundBox( object->GetChild(i),box );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPrefabObject::CalcBoundBox()
|
||||
{
|
||||
Matrix44 ltm = GetLocalTM();
|
||||
Matrix44 tm;
|
||||
tm.SetIdentity();
|
||||
SetWorldTM(tm);
|
||||
|
||||
// Calc local bounds box..
|
||||
BBox box;
|
||||
box.Reset();
|
||||
|
||||
int numChilds = GetChildCount();
|
||||
for (int i = 0; i < numChilds; i++)
|
||||
{
|
||||
if (GetChild(i)->CheckFlags(OBJFLAG_PREFAB))
|
||||
RecursivelyGetPrefabBoundBox( GetChild(i),box );
|
||||
}
|
||||
|
||||
if (numChilds == 0)
|
||||
{
|
||||
box.min = Vec3(-1,-1,-1);
|
||||
box.max = Vec3(1,1,1);
|
||||
}
|
||||
|
||||
SetLocalTM(ltm);
|
||||
|
||||
m_bbox = box;
|
||||
m_bBBoxValid = true;
|
||||
}
|
||||
120
Editor/Objects/PrefabObject.h
Normal file
120
Editor/Objects/PrefabObject.h
Normal file
@@ -0,0 +1,120 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001-2004.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: PrefabObject.h
|
||||
// Version: v1.00
|
||||
// Created: 13/11/2003 by Timur.
|
||||
// Compilers: Visual Studio.NET 2003
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __PrefabObject_h__
|
||||
#define __PrefabObject_h__
|
||||
#pragma once
|
||||
|
||||
#include "Group.h"
|
||||
|
||||
class CPrefabItem;
|
||||
|
||||
#define PREFAB_OBJECT_CLASS_NAME "Prefab"
|
||||
|
||||
/*!
|
||||
* CPrefabObject is prefabricated object which can contain multiple other objects, in a group like manner,
|
||||
but internal objects can not be modified, they are only created from PrefabItem.
|
||||
*/
|
||||
class CPrefabObject : public CBaseObject
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CPrefabObject)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
|
||||
void Display( DisplayContext &disp );
|
||||
bool HitTest( HitContext &hc );
|
||||
void GetBoundBox( BBox &box );
|
||||
void GetLocalBounds( BBox &box );
|
||||
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
|
||||
void OnEvent( ObjectEvent event );
|
||||
|
||||
void Serialize( CObjectArchive &ar );
|
||||
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CPrefabObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetPrefab( REFGUID guid,bool bForceReload );
|
||||
virtual void SetPrefab( CPrefabItem *pPrefab,bool bForceReload );
|
||||
CPrefabItem* GetPrefab() const;
|
||||
|
||||
// Extract all objects inside.
|
||||
void ExtractAll();
|
||||
void ExtractObject( CBaseObject *pObj );
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CPrefabObject();
|
||||
|
||||
virtual void PostClone( CBaseObject *pFromObject,CObjectCloneContext &ctx );
|
||||
virtual void CalcBoundBox();
|
||||
void DeleteThis() { delete this; };
|
||||
|
||||
void RecursivelySetObjectInPrefab( CBaseObject *object );
|
||||
void RecursivelyDisplayObject( CBaseObject *object,DisplayContext &dc );
|
||||
void DeleteAllPrefabObjects();
|
||||
|
||||
void InvalidateBBox() { m_bBBoxValid = false; };
|
||||
|
||||
protected:
|
||||
_smart_ptr<CPrefabItem> m_pPrefabItem;
|
||||
|
||||
CString m_prefabName;
|
||||
GUID m_prefabGUID;
|
||||
|
||||
BBox m_bbox;
|
||||
bool m_bBBoxValid;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Per Instance Entity events.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of Group.
|
||||
*/
|
||||
class CPrefabObjectClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {931962ED-450F-443e-BFA4-1BBDAA061202}
|
||||
static const GUID guid = { 0x931962ed, 0x450f, 0x443e, { 0xbf, 0xa4, 0x1b, 0xbd, 0xaa, 0x6, 0x12, 0x2 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_PREFAB; };
|
||||
const char* ClassName() { return PREFAB_OBJECT_CLASS_NAME; };
|
||||
const char* Category() { return "Prefabs"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CPrefabObject); };
|
||||
|
||||
//! Select all prefabs.
|
||||
//! ObjectTreeBrowser object can recognize this hardcoded name.
|
||||
const char* GetFileSpec() { return "*Prefabs"; };
|
||||
int GameCreationOrder() { return 210; };
|
||||
};
|
||||
|
||||
#endif // __PrefabObject_h__
|
||||
|
||||
201
Editor/Objects/ProtEntityObject.cpp
Normal file
201
Editor/Objects/ProtEntityObject.cpp
Normal file
@@ -0,0 +1,201 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: protentityobject.cpp
|
||||
// Version: v1.00
|
||||
// Created: 24/1/2003 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "ProtEntityObject.h"
|
||||
|
||||
#include "EntityPrototype.h"
|
||||
#include "EntityPrototypeManager.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CProtEntityObject,CEntity)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CProtEntityObject implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CProtEntityObject::CProtEntityObject()
|
||||
{
|
||||
ZeroStruct(m_prototypeGUID);
|
||||
m_prototypeName = "Unknown Archetype";
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CProtEntityObject::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
bool result = CEntity::Init( ie,prev,"" );
|
||||
|
||||
if (prev)
|
||||
{
|
||||
CProtEntityObject *pe = (CProtEntityObject*)prev;
|
||||
SetPrototype( pe->m_prototype,true );
|
||||
}
|
||||
else if (!file.IsEmpty())
|
||||
{
|
||||
SetPrototype( GuidUtil::FromString(file) );
|
||||
SetUniqName( m_prototypeName );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CProtEntityObject::Done()
|
||||
{
|
||||
if (m_prototype)
|
||||
m_prototype->RemoveUpdateListener( functor(*this,&CProtEntityObject::OnPrototypeUpdate) );
|
||||
m_prototype = 0;
|
||||
ZeroStruct(m_prototypeGUID);
|
||||
CEntity::Done();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CProtEntityObject::CreateGameObject()
|
||||
{
|
||||
if (m_prototype)
|
||||
{
|
||||
return CEntity::CreateGameObject();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CProtEntityObject::SpawnEntity()
|
||||
{
|
||||
if (m_prototype)
|
||||
{
|
||||
CEntity::SpawnEntity();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CProtEntityObject::SetPrototype( REFGUID guid,bool bForceReload )
|
||||
{
|
||||
if (m_prototypeGUID == guid && bForceReload == false)
|
||||
return;
|
||||
|
||||
m_prototypeGUID = guid;
|
||||
|
||||
//m_fullPrototypeName = prototypeName;
|
||||
CEntityPrototypeManager *protMan = GetIEditor()->GetEntityProtManager();
|
||||
CEntityPrototype *prototype = protMan->FindPrototype( guid );
|
||||
if (!prototype)
|
||||
{
|
||||
m_prototypeName = "Unknown Archetype";
|
||||
|
||||
CErrorRecord err;
|
||||
err.error.Format( "Cannot find Entity Archetype: %s for Entity %s",GuidUtil::ToString(guid),(const char*)GetName() );
|
||||
err.pObject = this;
|
||||
err.severity = CErrorRecord::ESEVERITY_WARNING;
|
||||
GetIEditor()->GetErrorReport()->ReportError(err);
|
||||
//Warning( "Cannot find Entity Archetype: %s for Entity %s",GuidUtil::ToString(guid),(const char*)GetName() );
|
||||
return;
|
||||
}
|
||||
SetPrototype( prototype,bForceReload );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CProtEntityObject::BeginEditParams( IEditor *ie,int flags )
|
||||
{
|
||||
CEntity::BeginEditParams( ie,flags );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CProtEntityObject::EndEditParams( IEditor *ie )
|
||||
{
|
||||
CEntity::EndEditParams( ie );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CProtEntityObject::BeginEditMultiSelParams( bool bAllOfSameType )
|
||||
{
|
||||
CEntity::BeginEditMultiSelParams( bAllOfSameType );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CProtEntityObject::EndEditMultiSelParams()
|
||||
{
|
||||
CEntity::EndEditMultiSelParams();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CProtEntityObject::Serialize( CObjectArchive &ar )
|
||||
{
|
||||
if (ar.bLoading)
|
||||
{
|
||||
// Serialize name at first.
|
||||
CString name;
|
||||
ar.node->getAttr( "Name",name );
|
||||
SetName( name );
|
||||
|
||||
// Loading.
|
||||
GUID guid;
|
||||
ar.node->getAttr( "Prototype",guid );
|
||||
SetPrototype( guid );
|
||||
if (ar.bUndo)
|
||||
{
|
||||
SpawnEntity();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Saving.
|
||||
ar.node->setAttr( "Prototype",m_prototypeGUID );
|
||||
}
|
||||
CEntity::Serialize( ar );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
XmlNodeRef CProtEntityObject::Export( const CString &levelPath,XmlNodeRef &xmlNode )
|
||||
{
|
||||
return CEntity::Export( levelPath,xmlNode );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CProtEntityObject::OnPrototypeUpdate()
|
||||
{
|
||||
// Callback from prototype.
|
||||
OnPropertyChange(0);
|
||||
|
||||
if (m_prototype)
|
||||
{
|
||||
m_prototypeName = m_prototype->GetName();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CProtEntityObject::SetPrototype( CEntityPrototype *prototype,bool bForceReload )
|
||||
{
|
||||
assert( prototype );
|
||||
|
||||
if (prototype == m_prototype)
|
||||
return;
|
||||
|
||||
bool bRespawn = m_entity != 0;
|
||||
|
||||
StoreUndo( "Set Archetype" );
|
||||
|
||||
if (m_prototype)
|
||||
m_prototype->RemoveUpdateListener( functor(*this,&CProtEntityObject::OnPrototypeUpdate) );
|
||||
|
||||
m_prototype = prototype;
|
||||
m_prototype->AddUpdateListener( functor(*this,&CProtEntityObject::OnPrototypeUpdate) );
|
||||
m_properties = m_prototype->GetProperties();
|
||||
m_prototypeGUID = m_prototype->GetGUID();
|
||||
m_prototypeName = m_prototype->GetName();
|
||||
|
||||
LoadScript( m_prototype->GetEntityClassName(),bForceReload,true );
|
||||
if (bRespawn)
|
||||
SpawnEntity();
|
||||
}
|
||||
92
Editor/Objects/ProtEntityObject.h
Normal file
92
Editor/Objects/ProtEntityObject.h
Normal file
@@ -0,0 +1,92 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: protentityobject.h
|
||||
// Version: v1.00
|
||||
// Created: 24/1/2003 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __protentityobject_h__
|
||||
#define __protentityobject_h__
|
||||
#pragma once
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
class CEntityPrototype;
|
||||
/*!
|
||||
* Prototype entity object.
|
||||
*
|
||||
*/
|
||||
class CProtEntityObject : public CEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CProtEntityObject)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
bool CreateGameObject();
|
||||
|
||||
CString GetTypeDescription() const { return m_prototypeName; };
|
||||
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
void BeginEditMultiSelParams( bool bAllOfSameType );
|
||||
void EndEditMultiSelParams();
|
||||
|
||||
void Serialize( CObjectArchive &ar );
|
||||
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SetPrototype( REFGUID guid,bool bForceReload=false );
|
||||
void SetPrototype( CEntityPrototype *prototype,bool bForceReload );
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CProtEntityObject();
|
||||
|
||||
virtual void SpawnEntity();
|
||||
|
||||
//! Callback called by prototype when its updated.
|
||||
void OnPrototypeUpdate();
|
||||
|
||||
//! Entity prototype name.
|
||||
CString m_prototypeName;
|
||||
//! Full prototype name.
|
||||
GUID m_prototypeGUID;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of StaticObject
|
||||
*/
|
||||
class CProtEntityObjectClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {B9FB3D0B-ADA8-4380-A96F-A091E66E6EC1}
|
||||
static const GUID guid = { 0xb9fb3d0b, 0xada8, 0x4380, { 0xa9, 0x6f, 0xa0, 0x91, 0xe6, 0x6e, 0x6e, 0xc1 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_ENTITY; };
|
||||
const char* ClassName() { return "PrototypeEntity"; };
|
||||
const char* Category() { return "Archetype Entity"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CProtEntityObject); };
|
||||
|
||||
//! Select all entity prototypes.
|
||||
//! ObjectTreeBrowser object can recognize this hardcoded name.
|
||||
const char* GetFileSpec() { return "*EntityPrototype"; };
|
||||
int GameCreationOrder() { return 205; };
|
||||
};
|
||||
|
||||
#endif // __protentityobject_h__
|
||||
76
Editor/Objects/SafeObjectsArray.cpp
Normal file
76
Editor/Objects/SafeObjectsArray.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: safeobjectsarray.cpp
|
||||
// Version: v1.00
|
||||
// Created: 28/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "SafeObjectsArray.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CSafeObjectsArray::~CSafeObjectsArray()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSafeObjectsArray::Clear()
|
||||
{
|
||||
int num = m_objects.size();
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
m_objects[i]->RemoveEventListener( functor(*this,&CSafeObjectsArray::OnTargetEvent) );
|
||||
}
|
||||
m_objects.clear();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSafeObjectsArray::Add( CBaseObject *obj )
|
||||
{
|
||||
// Not add NULL object.
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
// Check if object is unique in array.
|
||||
if (!stl::find( m_objects,obj ))
|
||||
{
|
||||
m_objects.push_back(obj);
|
||||
// Make reference on this object.
|
||||
obj->AddEventListener( functor(*this,&CSafeObjectsArray::OnTargetEvent) );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSafeObjectsArray::Remove( CBaseObject *obj )
|
||||
{
|
||||
// Find this object.
|
||||
if (stl::find_and_erase( m_objects,obj ))
|
||||
{
|
||||
obj->RemoveEventListener( functor(*this,&CSafeObjectsArray::OnTargetEvent) );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CBaseObject* CSafeObjectsArray::Get( int index ) const
|
||||
{
|
||||
assert( index >= 0 && index < m_objects.size() );
|
||||
return m_objects[index];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSafeObjectsArray::OnTargetEvent( CBaseObject *target,int event )
|
||||
{
|
||||
if (event == CBaseObject::ON_DELETE)
|
||||
{
|
||||
Remove(target);
|
||||
}
|
||||
}
|
||||
49
Editor/Objects/SafeObjectsArray.h
Normal file
49
Editor/Objects/SafeObjectsArray.h
Normal file
@@ -0,0 +1,49 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: safeobjectsarray.h
|
||||
// Version: v1.00
|
||||
// Created: 28/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __safeobjectsarray_h__
|
||||
#define __safeobjectsarray_h__
|
||||
#pragma once
|
||||
|
||||
#include "BaseObject.h"
|
||||
|
||||
/** This class used as a safe collction of references to CBaseObject instances.
|
||||
Target objects in this collection can be safely removed or added,
|
||||
This object makes references to added objects and recieve back event when theose objects are deleted.
|
||||
*/
|
||||
class CSafeObjectsArray
|
||||
{
|
||||
public:
|
||||
CSafeObjectsArray() {};
|
||||
~CSafeObjectsArray();
|
||||
|
||||
void Add( CBaseObject *obj );
|
||||
void Remove( CBaseObject *obj );
|
||||
|
||||
bool IsEmpty() const { return m_objects.empty(); }
|
||||
int GetCount() const { return m_objects.size(); }
|
||||
CBaseObject* Get( int index ) const;
|
||||
|
||||
// Clear array.
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
void OnTargetEvent( CBaseObject *target,int event );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
std::vector<CBaseObjectPtr> m_objects;
|
||||
};
|
||||
|
||||
#endif // __safeobjectsarray_h__
|
||||
441
Editor/Objects/SelectionGroup.cpp
Normal file
441
Editor/Objects/SelectionGroup.cpp
Normal file
@@ -0,0 +1,441 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: SelectionGroup.cpp
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: CSelectionGroup implementation.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "SelectionGroup.h"
|
||||
|
||||
#include "BaseObject.h"
|
||||
#include "ObjectManager.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::AddObject( CBaseObject *obj )
|
||||
{
|
||||
if (!IsContainObject(obj))
|
||||
{
|
||||
m_objects.push_back(obj);
|
||||
m_objectsSet.insert(obj);
|
||||
m_filtered.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::RemoveObject( CBaseObject *obj )
|
||||
{
|
||||
for (Objects::iterator it = m_objects.begin(); it != m_objects.end(); ++it)
|
||||
{
|
||||
if (*it == obj)
|
||||
{
|
||||
m_objects.erase(it);
|
||||
m_objectsSet.erase(obj);
|
||||
m_filtered.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::RemoveAll()
|
||||
{
|
||||
m_objects.clear();
|
||||
m_objectsSet.clear();
|
||||
m_filtered.clear();
|
||||
}
|
||||
|
||||
bool CSelectionGroup::IsContainObject( CBaseObject *obj )
|
||||
{
|
||||
return (m_objectsSet.find(obj) != m_objectsSet.end());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CSelectionGroup::IsEmpty() const
|
||||
{
|
||||
return m_objects.empty();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CSelectionGroup::SameObjectType()
|
||||
{
|
||||
if (IsEmpty())
|
||||
return false;
|
||||
CBaseObjectPtr pFirst=(*(m_objects.begin()));
|
||||
for (Objects::iterator it = m_objects.begin(); it != m_objects.end(); ++it)
|
||||
{
|
||||
if ((*it)->GetRuntimeClass()!=pFirst->GetRuntimeClass())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CSelectionGroup::GetCount() const
|
||||
{
|
||||
return m_objects.size();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CBaseObject* CSelectionGroup::GetObject( int index ) const
|
||||
{
|
||||
ASSERT( index >= 0 && index < m_objects.size() );
|
||||
return m_objects[index];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::Copy( const CSelectionGroup &from )
|
||||
{
|
||||
m_name = from.m_name;
|
||||
m_objects = from.m_objects;
|
||||
m_objectsSet = from.m_objectsSet;
|
||||
m_filtered = from.m_filtered;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
Vec3 CSelectionGroup::GetCenter() const
|
||||
{
|
||||
Vec3 c(0,0,0);
|
||||
for (int i = 0; i < GetCount(); i++)
|
||||
{
|
||||
c += GetObject(i)->GetWorldPos();
|
||||
}
|
||||
c /= GetCount();
|
||||
return c;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
BBox CSelectionGroup::GetBounds() const
|
||||
{
|
||||
BBox b;
|
||||
BBox box;
|
||||
box.Reset();
|
||||
for (int i = 0; i < GetCount(); i++)
|
||||
{
|
||||
GetObject(i)->GetBoundBox( b );
|
||||
box.Add( b.min );
|
||||
box.Add( b.max );
|
||||
}
|
||||
return box;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::FilterParents()
|
||||
{
|
||||
if (!m_filtered.empty())
|
||||
return;
|
||||
|
||||
m_filtered.reserve( m_objects.size() );
|
||||
for (int i = 0; i < m_objects.size(); i++)
|
||||
{
|
||||
CBaseObject *obj = m_objects[i];
|
||||
CBaseObject *parent = obj->GetParent();
|
||||
bool bParentInSet = false;
|
||||
while (parent)
|
||||
{
|
||||
if (m_objectsSet.find(parent) != m_objectsSet.end())
|
||||
{
|
||||
bParentInSet = true;
|
||||
break;
|
||||
}
|
||||
parent = parent->GetParent();
|
||||
}
|
||||
if (!bParentInSet)
|
||||
{
|
||||
m_filtered.push_back(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::Move( const Vec3 &offset,bool keepHeight,bool inWorldSpace )
|
||||
{
|
||||
if (offset.x == 0 && offset.y == 0 && offset.z == 0)
|
||||
return;
|
||||
|
||||
FilterParents();
|
||||
|
||||
Vec3 newPos;
|
||||
for (int i = 0; i < GetFilteredCount(); i++)
|
||||
{
|
||||
CBaseObject *obj = GetFilteredObject(i);
|
||||
|
||||
Matrix44 wtm = obj->GetWorldTM();
|
||||
Vec3 wp = wtm.GetTranslationOLD();
|
||||
newPos = wp + offset;
|
||||
if (keepHeight)
|
||||
{
|
||||
// Make sure object keeps it height.
|
||||
float height = wp.z - GetIEditor()->GetTerrainElevation( wp.x,wp.y );
|
||||
newPos.z = GetIEditor()->GetTerrainElevation( newPos.x,newPos.y ) + height;
|
||||
}
|
||||
wtm.SetTranslationOLD( newPos );
|
||||
|
||||
obj->SetWorldTM( wtm );
|
||||
//obj->SetPos(newPos); // this is better i guess
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::Rotate( const Vec3 &angles,bool inWorldSpace )
|
||||
{
|
||||
if (angles.x == 0 && angles.y == 0 && angles.z == 0)
|
||||
return;
|
||||
/*
|
||||
if (sel.GetCount() == 1)
|
||||
{
|
||||
// If rotating only one object, assume angles are absolute angles of this object.
|
||||
|
||||
CBaseObject *obj = sel.GetObject(0);
|
||||
Quat q1,q2;
|
||||
q1.SetEulerAngles( obj->GetAngles()*PI/180.0f );
|
||||
q2.SetEulerAngles( angles*PI/180.0f );
|
||||
q1 = q1 * q2;
|
||||
Vec3 angles = q1.GetEulerAngles() * 180.0f/PI;
|
||||
|
||||
//obj->SetAngles( angles );
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
// Rotate selection about selection center.
|
||||
Vec3 center = GetCenter();
|
||||
|
||||
Matrix44 rotateTM;
|
||||
rotateTM.SetIdentity();
|
||||
//rotateTM.RotateMatrix_fix( angles );
|
||||
rotateTM=Matrix44::CreateRotationZYX(-angles*gf_DEGTORAD)*rotateTM; //NOTE: angles in radians and negated
|
||||
|
||||
Matrix44 ToOrigin;
|
||||
Matrix44 FromOrigin;
|
||||
|
||||
ToOrigin.SetIdentity();
|
||||
FromOrigin.SetIdentity();
|
||||
|
||||
if (inWorldSpace)
|
||||
{
|
||||
ToOrigin.SetTranslationOLD( -center );
|
||||
FromOrigin.SetTranslationOLD( center );
|
||||
}
|
||||
|
||||
FilterParents();
|
||||
|
||||
for (int i = 0; i < GetFilteredCount(); i++)
|
||||
{
|
||||
CBaseObject *obj = GetFilteredObject(i);
|
||||
|
||||
Matrix44 m = obj->GetWorldTM();
|
||||
if (inWorldSpace)
|
||||
{
|
||||
m = m * ToOrigin * rotateTM * FromOrigin;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = rotateTM * m;
|
||||
}
|
||||
obj->SetWorldTM( m );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::Scale( const Vec3 &scale,bool inWorldSpace )
|
||||
{
|
||||
if (scale.x == 1 && scale.y == 1 && scale.z == 1)
|
||||
return;
|
||||
|
||||
Vec3 scl = scale;
|
||||
if (scl.x == 0) scl.x = 0.01f;
|
||||
if (scl.y == 0) scl.y = 0.01f;
|
||||
if (scl.z == 0) scl.z = 0.01f;
|
||||
|
||||
// Scale selection relative to selection center.
|
||||
Vec3 center = GetCenter();
|
||||
|
||||
Matrix44 scaleTM;
|
||||
scaleTM.SetIdentity();
|
||||
|
||||
scaleTM=Matrix33::CreateScale( Vec3d(scl.x,scl.y,scl.z) ) * scaleTM;
|
||||
|
||||
Matrix44 ToOrigin;
|
||||
Matrix44 FromOrigin;
|
||||
|
||||
ToOrigin.SetIdentity();
|
||||
FromOrigin.SetIdentity();
|
||||
|
||||
if (inWorldSpace)
|
||||
{
|
||||
ToOrigin.SetTranslationOLD( -center );
|
||||
FromOrigin.SetTranslationOLD( center );
|
||||
}
|
||||
|
||||
FilterParents();
|
||||
|
||||
for (int i = 0; i < GetFilteredCount(); i++)
|
||||
{
|
||||
CBaseObject *obj = GetFilteredObject(i);
|
||||
|
||||
Matrix44 m = obj->GetWorldTM();
|
||||
if (inWorldSpace)
|
||||
m = m * ToOrigin * scaleTM * FromOrigin;
|
||||
else
|
||||
m = scaleTM * m;
|
||||
obj->SetWorldTM( m );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::Clone( CSelectionGroup &newGroup )
|
||||
{
|
||||
IObjectManager *pObjMan = GetIEditor()->GetObjectManager();
|
||||
assert( pObjMan );
|
||||
|
||||
int i;
|
||||
CObjectCloneContext cloneContext;
|
||||
|
||||
FilterParents();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Clone every object.
|
||||
for (i = 0; i < GetFilteredCount(); i++)
|
||||
{
|
||||
CBaseObject *pFromObject = GetFilteredObject(i);
|
||||
CBaseObject *newObj = pObjMan->CloneObject( pFromObject );
|
||||
assert( newObj );
|
||||
|
||||
cloneContext.AddClone( pFromObject,newObj );
|
||||
newGroup.AddObject( newObj );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Only after everything was cloned, call PostClone on all cloned objects.
|
||||
for (i = 0; i < GetFilteredCount(); i++)
|
||||
{
|
||||
CBaseObject *pFromObject = GetFilteredObject(i);
|
||||
CBaseObject *pClonedObject = newGroup.GetObject(i);
|
||||
pClonedObject->PostClone( pFromObject,cloneContext );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static void RecursiveFlattenHierarchy( CBaseObject *pObj,CSelectionGroup &newGroup )
|
||||
{
|
||||
if (pObj->CheckFlags(OBJFLAG_PREFAB))
|
||||
return;
|
||||
|
||||
newGroup.AddObject( pObj );
|
||||
|
||||
for (int i = 0; i < pObj->GetChildCount(); i++)
|
||||
{
|
||||
RecursiveFlattenHierarchy( pObj->GetChild(i),newGroup );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::FlattenHierarchy( CSelectionGroup &newGroup )
|
||||
{
|
||||
for (int i = 0; i < GetCount(); i++)
|
||||
{
|
||||
RecursiveFlattenHierarchy( GetObject(i),newGroup );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CAttachToParentPickCallback : public IPickObjectCallback
|
||||
{
|
||||
public:
|
||||
CAttachToParentPickCallback() { m_bActive = true; };
|
||||
//! Called when object picked.
|
||||
virtual void OnPick( CBaseObject *picked )
|
||||
{
|
||||
CUndo undo( "Attach Selection" );
|
||||
|
||||
CSelectionGroup *selGroup = GetIEditor()->GetSelection();
|
||||
selGroup->FilterParents();
|
||||
|
||||
for (int i = 0; i < selGroup->GetFilteredCount(); i++)
|
||||
{
|
||||
if (ChildIsValid( picked,selGroup->GetFilteredObject(i) ))
|
||||
picked->AttachChild( selGroup->GetFilteredObject(i) );
|
||||
}
|
||||
m_bActive = false;
|
||||
delete this;
|
||||
}
|
||||
//! Called when pick mode cancelled.
|
||||
virtual void OnCancelPick()
|
||||
{
|
||||
m_bActive = false;
|
||||
delete this;
|
||||
}
|
||||
//! Return true if specified object is pickable.
|
||||
virtual bool OnPickFilter( CBaseObject *filterObject )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool ChildIsValid(CBaseObject *pParent, CBaseObject *pChild, int nDir=3)
|
||||
{
|
||||
if (!pParent)
|
||||
return false;
|
||||
if (!pChild)
|
||||
return false;
|
||||
if (pParent==pChild)
|
||||
return false;
|
||||
CBaseObject *pObj;
|
||||
if (nDir & 1)
|
||||
{
|
||||
if (pObj=pChild->GetParent())
|
||||
{
|
||||
if (!ChildIsValid(pParent, pObj, 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nDir & 2)
|
||||
{
|
||||
for (int i=0;i<pChild->GetChildCount();i++)
|
||||
{
|
||||
if (pObj=pChild->GetChild(i))
|
||||
{
|
||||
if (!ChildIsValid(pParent, pObj, 2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool IsActive() { return m_bActive; }
|
||||
private:
|
||||
static bool m_bActive;
|
||||
};
|
||||
bool CAttachToParentPickCallback::m_bActive = false;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::PickAndAttach()
|
||||
{
|
||||
CAttachToParentPickCallback *pCallback = new CAttachToParentPickCallback;
|
||||
GetIEditor()->PickObject( pCallback,0,"Attach Selection To Parent" );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::SendEvent( ObjectEvent event )
|
||||
{
|
||||
for (int i = 0; i < m_objects.size(); i++)
|
||||
{
|
||||
CBaseObject *obj = m_objects[i];
|
||||
obj->OnEvent( event );
|
||||
}
|
||||
}
|
||||
105
Editor/Objects/SelectionGroup.h
Normal file
105
Editor/Objects/SelectionGroup.h
Normal file
@@ -0,0 +1,105 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: SelectionGroup.h
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: CSelection group definition.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __SelectionGroup_h__
|
||||
#define __SelectionGroup_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class CBaseObject;
|
||||
|
||||
#include "ObjectEvent.h"
|
||||
|
||||
/*!
|
||||
* CSelectionGroup is a named selection group of objects.
|
||||
*/
|
||||
class CSelectionGroup
|
||||
{
|
||||
public:
|
||||
//! Set name of selection.
|
||||
void SetName( const CString &name ) { m_name = name; };
|
||||
//! Get name of selection.
|
||||
const CString& GetName() const { return m_name; };
|
||||
|
||||
//! Adds object into selection list.
|
||||
void AddObject( CBaseObject *obj );
|
||||
//! Remove object from selection list.
|
||||
void RemoveObject( CBaseObject *obj );
|
||||
//! Remove all objects from selection.
|
||||
void RemoveAll();
|
||||
//! Check if object contained in selection list.
|
||||
bool IsContainObject( CBaseObject *obj );
|
||||
//! Return true if selection doesnt contain any object.
|
||||
bool IsEmpty() const;
|
||||
//! Check if all selected objects are of same type
|
||||
bool SameObjectType();
|
||||
//! Number of selected object.
|
||||
int GetCount() const;
|
||||
//! Get object at givven index.
|
||||
CBaseObject* GetObject( int index ) const;
|
||||
|
||||
//! Get mass center of selected objects.
|
||||
Vec3 GetCenter() const;
|
||||
|
||||
//! Get Bounding box of selection.
|
||||
BBox GetBounds() const;
|
||||
|
||||
void Copy( const CSelectionGroup &from );
|
||||
|
||||
//! Remove from selection group all objects which have parent also in selection group.
|
||||
//! And save resulting objects to saveTo selection.
|
||||
void FilterParents();
|
||||
//! Get number of child filtered objects.
|
||||
int GetFilteredCount() const { return m_filtered.size(); }
|
||||
CBaseObject* GetFilteredObject( int i ) const { return m_filtered[i]; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Operations on selection group.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Move objects in selection by offset.
|
||||
void Move( const Vec3 &offset,bool keepHeight,bool inWorldSpace );
|
||||
//! Rotate objects in selection by givven angle.
|
||||
void Rotate( const Vec3 &angles,bool inWorldSpace );
|
||||
//! Scale objects in selection by givven scale.
|
||||
void Scale( const Vec3 &scale,bool inWorldSpace );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Clone objects in this group and add cloned objects to new selection group.
|
||||
//! Only topmost parent objects will be added to this selection group.
|
||||
void Clone( CSelectionGroup &newGroup );
|
||||
|
||||
//! Same as Copy but will copy all objects from hierarchy of current selection to new selection group.
|
||||
void FlattenHierarchy( CSelectionGroup &newGroup );
|
||||
|
||||
//! Pick new parent and attach selection to it.
|
||||
void PickAndAttach();
|
||||
|
||||
// Send event to all objects in selection group.
|
||||
void SendEvent( ObjectEvent event );
|
||||
|
||||
private:
|
||||
CString m_name;
|
||||
typedef std::vector<TSmartPtr<CBaseObject> > Objects;
|
||||
Objects m_objects;
|
||||
// Objects set, for fast searches.
|
||||
std::set<CBaseObject*> m_objectsSet;
|
||||
|
||||
//! Selection list with child objecs filtered out.
|
||||
std::vector<CBaseObject*> m_filtered;
|
||||
};
|
||||
|
||||
#endif // __SelectionGroup_h__
|
||||
1218
Editor/Objects/ShapeObject.cpp
Normal file
1218
Editor/Objects/ShapeObject.cpp
Normal file
File diff suppressed because it is too large
Load Diff
330
Editor/Objects/ShapeObject.h
Normal file
330
Editor/Objects/ShapeObject.h
Normal file
@@ -0,0 +1,330 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: ShapeObject.h
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: ShapeObject object definition.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __ShapeObject_h__
|
||||
#define __ShapeObject_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "BaseObject.h"
|
||||
#include "SafeObjectsArray.h"
|
||||
|
||||
#define SHAPE_CLOSE_DISTANCE 0.8f
|
||||
#define SHAPE_Z_OFFSET 0.1f
|
||||
|
||||
/*!
|
||||
* CShapeObject is an object that represent named 3d position in world.
|
||||
*
|
||||
*/
|
||||
class CShapeObject : public CBaseObject
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CShapeObject)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
bool CreateGameObject();
|
||||
|
||||
void Display( DisplayContext &dc );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SetName( const CString &name );
|
||||
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
|
||||
//! Called when object is being created.
|
||||
int MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags );
|
||||
|
||||
void GetBoundBox( BBox &box );
|
||||
void GetLocalBounds( BBox &box );
|
||||
|
||||
bool HitTest( HitContext &hc );
|
||||
bool HitTestRect( HitContext &hc );
|
||||
|
||||
void OnEvent( ObjectEvent event );
|
||||
|
||||
void Serialize( CObjectArchive &ar );
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int GetAreaId();
|
||||
|
||||
void SetClosed( bool bClosed );
|
||||
bool IsClosed() { return mv_closed; };
|
||||
|
||||
//! Insert new point to shape at givven index.
|
||||
//! @return index of newly inserted point.
|
||||
int InsertPoint( int index,const Vec3 &point );
|
||||
//! Remve point from shape at givven index.
|
||||
void RemovePoint( int index );
|
||||
|
||||
//! Get number of points in shape.
|
||||
int GetPointCount() { return m_points.size(); };
|
||||
//! Get point at index.
|
||||
const Vec3& GetPoint( int index ) const { return m_points[index]; };
|
||||
//! Set point position at specified index.
|
||||
void SetPoint( int index,const Vec3 &pos );
|
||||
|
||||
void SelectPoint( int index );
|
||||
int GetSelectedPoint() const { return m_selectedPoint;};
|
||||
|
||||
//! Set shape width.
|
||||
float GetWidth() const { return mv_width; };
|
||||
|
||||
//! Set shape height.
|
||||
float GetHeight() const { return mv_height; };
|
||||
|
||||
//! Find shape point nearest to givven point.
|
||||
int GetNearestPoint( const Vec3 &raySrc,const Vec3 &rayDir,float &distance );
|
||||
|
||||
//! Find shape edge nearest to givven point.
|
||||
void GetNearestEdge( const Vec3 &pos,int &p1,int &p2,float &distance,Vec3 &intersectPoint );
|
||||
|
||||
//! Find shape edge nearest to givven ray.
|
||||
void GetNearestEdge( const Vec3 &raySrc,const Vec3 &rayDir,int &p1,int &p2,float &distance,Vec3 &intersectPoint );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetSelected( bool bSelect );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Binded entities.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Bind entity to this shape.
|
||||
void AddEntity( CBaseObject *entity );
|
||||
void RemoveEntity( int index );
|
||||
CBaseObject* GetEntity( int index );
|
||||
int GetEntityCount() { return m_entities.GetCount(); }
|
||||
|
||||
void CalcBBox();
|
||||
|
||||
protected:
|
||||
virtual void PostClone( CBaseObject *pFromObject,CObjectCloneContext &ctx );
|
||||
|
||||
bool RayToLineDistance( const Vec3 &rayLineP1,const Vec3 &rayLineP2,const Vec3 &pi,const Vec3 &pj,float &distance,Vec3 &intPnt );
|
||||
virtual bool IsOnlyUpdateOnUnselect() const { return false; }
|
||||
virtual int GetMaxPoints() const { return 1000; };
|
||||
////! Calculate distance between
|
||||
//float DistanceToShape( const Vec3 &pos );
|
||||
void DrawTerrainLine( DisplayContext &dc,const Vec3 &p1,const Vec3 &p2 );
|
||||
|
||||
// Ignore default draw highlight.
|
||||
void DrawHighlight( DisplayContext &dc ) {};
|
||||
|
||||
void EndCreation();
|
||||
|
||||
//! Update game area.
|
||||
virtual void UpdateGameArea( bool bRemove=false );
|
||||
|
||||
//overrided from CBaseObject.
|
||||
void InvalidateTM();
|
||||
|
||||
//! Called when shape variable changes.
|
||||
void OnShapeChange( IVariable *var );
|
||||
|
||||
//! Dtor must be protected.
|
||||
CShapeObject();
|
||||
|
||||
void DeleteThis() { delete this; };
|
||||
|
||||
IEditor *m_ie;
|
||||
BBox m_bbox;
|
||||
|
||||
std::vector<Vec3> m_points;
|
||||
|
||||
struct IXArea *m_IArea;
|
||||
|
||||
bool m_bIgnoreGameUpdate;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! List of binded entities.
|
||||
//std::vector<uint> m_entities;
|
||||
|
||||
// Entities.
|
||||
CSafeObjectsArray m_entities;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Shape parameters.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CVariable<float> mv_width;
|
||||
CVariable<float> mv_height;
|
||||
CVariable<int> mv_areaId;
|
||||
CVariable<int> mv_groupId;
|
||||
CVariable<bool> mv_closed;
|
||||
//! Display triangles filling closed shape.
|
||||
CVariable<bool> mv_displayFilled;
|
||||
|
||||
int m_selectedPoint;
|
||||
float m_lowestHeight;
|
||||
bool m_bAreaModified;
|
||||
//! Forces shape to be always 2D. (all vertices lie on XY plane).
|
||||
bool m_bForce2D;
|
||||
bool m_bDisplayFilledWhenSelected;
|
||||
|
||||
static int m_rollupId;
|
||||
static class CShapePanel* m_panel;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of ShapeObject.
|
||||
*/
|
||||
class CShapeObjectClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {6167DD9D-73D5-4d07-9E92-CF12AF451B08}
|
||||
static const GUID guid = { 0x6167dd9d, 0x73d5, 0x4d07, { 0x9e, 0x92, 0xcf, 0x12, 0xaf, 0x45, 0x1b, 0x8 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_SHAPE; };
|
||||
const char* ClassName() { return "Shape"; };
|
||||
const char* Category() { return "Area"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CShapeObject); };
|
||||
int GameCreationOrder() { return 50; };
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Special object for forbidden area.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CAIForbiddenAreaObject : public CShapeObject
|
||||
{
|
||||
DECLARE_DYNCREATE(CAIForbiddenAreaObject)
|
||||
public:
|
||||
CAIForbiddenAreaObject();
|
||||
// Ovverride game area creation.
|
||||
virtual void UpdateGameArea( bool bRemove=false );
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Special object for AI Walkabale paths.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CAIPathObject : public CShapeObject
|
||||
{
|
||||
DECLARE_DYNCREATE(CAIPathObject)
|
||||
public:
|
||||
CAIPathObject();
|
||||
// Ovverride game area creation.
|
||||
virtual void UpdateGameArea( bool bRemove=false );
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Special object for AI Walkabale paths.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CAINavigationModifierObject : public CShapeObject
|
||||
{
|
||||
DECLARE_DYNCREATE(CAINavigationModifierObject)
|
||||
public:
|
||||
CAINavigationModifierObject();
|
||||
// Ovverride game area creation.
|
||||
virtual void UpdateGameArea( bool bRemove=false );
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Special object for AI Walkabale paths.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CAIOcclusionPlaneObject : public CShapeObject
|
||||
{
|
||||
DECLARE_DYNCREATE(CAIOcclusionPlaneObject)
|
||||
public:
|
||||
CAIOcclusionPlaneObject();
|
||||
// Ovverride game area creation.
|
||||
virtual void UpdateGameArea( bool bRemove=false );
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of CForbiddenAreaObject.
|
||||
*/
|
||||
class CAIForbiddenAreaObjectClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {9C9D5FD9-761B-4734-B2AA-38990E4C2EB9}
|
||||
static const GUID guid = { 0x9c9d5fd9, 0x761b, 0x4734, { 0xb2, 0xaa, 0x38, 0x99, 0xe, 0x4c, 0x2e, 0xb9 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_SHAPE; };
|
||||
const char* ClassName() { return "ForbiddenArea"; };
|
||||
const char* Category() { return "AI"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CAIForbiddenAreaObject); };
|
||||
int GameCreationOrder() { return 50; };
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of CForbiddenAreaObject.
|
||||
*/
|
||||
class CAIPathObjectClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {06380C56-6ECB-416f-9888-60DE08F0280B}
|
||||
static const GUID guid = { 0x6380c56, 0x6ecb, 0x416f, { 0x98, 0x88, 0x60, 0xde, 0x8, 0xf0, 0x28, 0xb } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_SHAPE; };
|
||||
const char* ClassName() { return "AIPath"; };
|
||||
const char* Category() { return "AI"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CAIPathObject); };
|
||||
int GameCreationOrder() { return 50; };
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of CForbiddenAreaObject.
|
||||
*/
|
||||
class CAINavigationModifierObjectClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {2AD95C7B-5548-435b-BF0C-63632D7FEA40}
|
||||
static const GUID guid = { 0x2ad95c7b, 0x5548, 0x435b, { 0xbf, 0xc, 0x63, 0x63, 0x2d, 0x7f, 0xea, 0x40 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_SHAPE; };
|
||||
const char* ClassName() { return "AINavigationModifier"; };
|
||||
const char* Category() { return "AI"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CAINavigationModifierObject); };
|
||||
int GameCreationOrder() { return 50; };
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of CForbiddenAreaObject.
|
||||
*/
|
||||
class CAIOcclusionPlaneObjectClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {85F4FEB1-1E97-4d78-BC0F-CACEA0D539C3}
|
||||
static const GUID guid =
|
||||
{ 0x85f4feb1, 0x1e97, 0x4d78, { 0xbc, 0xf, 0xca, 0xce, 0xa0, 0xd5, 0x39, 0xc3 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_SHAPE; };
|
||||
const char* ClassName() { return "AIHorizontalOcclusionPlane"; };
|
||||
const char* Category() { return "AI"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CAIOcclusionPlaneObject); };
|
||||
int GameCreationOrder() { return 50; };
|
||||
};
|
||||
|
||||
#endif // __ShapeObject_h__
|
||||
199
Editor/Objects/SoundObject.cpp
Normal file
199
Editor/Objects/SoundObject.cpp
Normal file
@@ -0,0 +1,199 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: SoundObject.cpp
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: CSoundObject implementation.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "SoundObject.h"
|
||||
#include "..\SoundObjectPanel.h"
|
||||
|
||||
#include "..\Viewport.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CBase implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CSoundObject,CBaseObject)
|
||||
|
||||
int CSoundObject::m_rollupId = 0;
|
||||
CSoundObjectPanel* CSoundObject::m_panel = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CSoundObject::CSoundObject()
|
||||
{
|
||||
//m_ITag = 0;
|
||||
|
||||
m_innerRadius = 1;
|
||||
m_outerRadius = 10;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSoundObject::Done()
|
||||
{
|
||||
//if (m_ITag)
|
||||
{
|
||||
// GetIEditor()->GetGame()->RemoveSoundObject( m_ITag );
|
||||
}
|
||||
CBaseObject::Done();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CSoundObject::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
m_ie = ie;
|
||||
|
||||
SetColor( RGB(255,255,0) );
|
||||
bool res = CBaseObject::Init( ie,prev,file );
|
||||
|
||||
// Create Tag point in game.
|
||||
//m_ITag = GetIEditor()->GetGame()->CreateSoundObject( (const char*)GetName(),GetPos(),GetAngles() );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSoundObject::SetName( const CString &name )
|
||||
{
|
||||
CBaseObject::SetName( name );
|
||||
//if (m_ITag)
|
||||
//m_ITag->SetName( name );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSoundObject::SetPos( const Vec3d &pos )
|
||||
{
|
||||
CBaseObject::SetPos( pos );
|
||||
//if (m_ITag)
|
||||
//m_ITag->SetPos( pos );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSoundObject::SetAngles( const Vec3d &angles )
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSoundObject::SetScale( const Vec3d &scale )
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSoundObject::GetBoundSphere( Vec3d &pos,float &radius )
|
||||
{
|
||||
pos = GetPos();
|
||||
radius = m_outerRadius;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSoundObject::BeginEditParams( IEditor *ie,int flags )
|
||||
{
|
||||
m_ie = ie;
|
||||
CBaseObject::BeginEditParams( ie,flags );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSoundObject::EndEditParams( IEditor *ie )
|
||||
{
|
||||
CBaseObject::EndEditParams( ie );
|
||||
}
|
||||
|
||||
/*
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSoundObject::OnPropertyChange( const CString &property )
|
||||
{
|
||||
CBaseObject::OnPropertyChange(property);
|
||||
|
||||
if (!GetParams())
|
||||
return;
|
||||
|
||||
GetParams()->getAttr( "InnerRadius",m_innerRadius );
|
||||
GetParams()->getAttr( "OuterRadius",m_outerRadius );
|
||||
}
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CSoundObject::MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags )
|
||||
{
|
||||
if (event == eMouseMove || event == eMouseLDown)
|
||||
{
|
||||
Vec3 pos;
|
||||
// Position 1 meter above ground when creating.
|
||||
if (GetIEditor()->GetAxisConstrains() != AXIS_TERRAIN)
|
||||
{
|
||||
pos = view->MapViewToCP(point);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Snap to terrain.
|
||||
bool hitTerrain;
|
||||
pos = view->ViewToWorld( point,&hitTerrain );
|
||||
if (hitTerrain)
|
||||
{
|
||||
pos.z = GetIEditor()->GetTerrainElevation(pos.x,pos.y) + 1.0f;
|
||||
}
|
||||
pos = view->SnapToGrid(pos);
|
||||
}
|
||||
SetPos( pos );
|
||||
if (event == eMouseLDown)
|
||||
return MOUSECREATE_OK;
|
||||
return MOUSECREATE_CONTINUE;
|
||||
}
|
||||
return CBaseObject::MouseCreateCallback( view,event,point,flags );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CSoundObject::HitTest( HitContext &hc )
|
||||
{
|
||||
Vec3 origin = GetPos();
|
||||
float radius = 1;
|
||||
|
||||
Vec3 w = origin - hc.raySrc;
|
||||
w = hc.rayDir.Cross( w );
|
||||
float d = w.Length();
|
||||
|
||||
if (d < radius + hc.distanceTollerance)
|
||||
{
|
||||
hc.dist = GetDistance(hc.raySrc,origin);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSoundObject::Display( DisplayContext &dc )
|
||||
{
|
||||
COLORREF color = GetColor();
|
||||
|
||||
dc.SetColor( color,0.8f );
|
||||
dc.DrawBall( GetPos(),1 );
|
||||
|
||||
dc.SetColor( 0,1,0,0.3f );
|
||||
dc.DrawWireSphere( GetPos(),m_innerRadius );
|
||||
|
||||
dc.SetColor( color,1 );
|
||||
dc.DrawWireSphere( GetPos(),m_outerRadius );
|
||||
//dc.renderer->DrawBall( GetPos(),m_outerRadius );
|
||||
|
||||
if (IsSelected())
|
||||
{
|
||||
dc.SetSelectedColor( 0.5f );
|
||||
dc.DrawBall( GetPos(),1.3f );
|
||||
}
|
||||
DrawDefault( dc );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
XmlNodeRef CSoundObject::Export( const CString &levelPath,XmlNodeRef &xmlNode )
|
||||
{
|
||||
XmlNodeRef objNode = CBaseObject::Export( levelPath,xmlNode );
|
||||
return objNode;
|
||||
}
|
||||
93
Editor/Objects/SoundObject.h
Normal file
93
Editor/Objects/SoundObject.h
Normal file
@@ -0,0 +1,93 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: SoundObject.h
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: SoundObject object definition.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __SoundObject_h__
|
||||
#define __SoundObject_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "BaseObject.h"
|
||||
|
||||
/*!
|
||||
* CSoundObject is an object that represent named 3d position in world.
|
||||
*
|
||||
*/
|
||||
class CSoundObject : public CBaseObject
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CSoundObject)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
|
||||
void Display( DisplayContext &dc );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetName( const CString &name );
|
||||
virtual void SetPos( const Vec3d &pos );
|
||||
virtual void SetAngles( const Vec3d &angles );
|
||||
virtual void SetScale( const Vec3d &angles );
|
||||
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
|
||||
//! Called when object is being created.
|
||||
int MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags );
|
||||
|
||||
void GetBoundSphere( Vec3d &pos,float &radius );
|
||||
bool HitTest( HitContext &hc );
|
||||
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CSoundObject();
|
||||
void DeleteThis() { delete this; };
|
||||
|
||||
float m_innerRadius;
|
||||
float m_outerRadius;
|
||||
|
||||
IEditor *m_ie;
|
||||
//ISoundObject *m_ITag;
|
||||
|
||||
static int m_rollupId;
|
||||
static class CSoundObjectPanel* m_panel;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of SoundObject.
|
||||
*/
|
||||
class CSoundObjectClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {6B3EDDE5-7BCF-4936-B891-39CD7A8DC021}
|
||||
static const GUID guid = { 0x6b3edde5, 0x7bcf, 0x4936, { 0xb8, 0x91, 0x39, 0xcd, 0x7a, 0x8d, 0xc0, 0x21 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_TAGPOINT; };
|
||||
const char* ClassName() { return "StdSoundObject"; };
|
||||
const char* Category() { return ""; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CSoundObject); };
|
||||
};
|
||||
|
||||
#endif // __SoundObject_h__
|
||||
479
Editor/Objects/StatObj.cpp
Normal file
479
Editor/Objects/StatObj.cpp
Normal file
@@ -0,0 +1,479 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: StatObj.cpp
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: StaticObject implementation.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "StatObj.h"
|
||||
#include "..\StatObjPanel.h"
|
||||
#include "selectiongroup.h"
|
||||
|
||||
#include "..\Viewport.h"
|
||||
#include "..\AnimationContext.h"
|
||||
|
||||
#include <I3DEngine.h>
|
||||
#include <IEntitySystem.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CBase implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Do not replace CBaseObject to CEntity, we want in Our hierarchy static objects be not derived from entity.
|
||||
IMPLEMENT_DYNCREATE(CStaticObject,CEntity)
|
||||
|
||||
int CStaticObject::m_rollupId = 0;
|
||||
CStatObjPanel* CStaticObject::m_panel = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CStaticObject::CStaticObject()
|
||||
{
|
||||
//m_staticEntity = true;
|
||||
m_loadFailed = false;
|
||||
m_bCharacter = false;
|
||||
|
||||
mv_rigidBody = false;
|
||||
mv_hidable = false;
|
||||
mv_density = 1;
|
||||
mv_mass = 1;
|
||||
|
||||
mv_animationLoop = false;
|
||||
mv_animationSpeed = 1;
|
||||
|
||||
AddVariable( mv_hidable,"Hidable",functor(*this,OnRigidBodyChange) );
|
||||
AddVariable( mv_rigidBody,"RigidBody",functor(*this,OnRigidBodyChange) );
|
||||
AddVariable( mv_mass,"Mass",functor(*this,OnMassChange) );
|
||||
AddVariable( mv_density,"Density",functor(*this,OnMassChange) );
|
||||
AddVariable( mv_animation,"Animation",functor(*this,OnAnimationChange) );
|
||||
AddVariable( mv_animationLoop,"AnimLoop",functor(*this,OnAnimationChange) );
|
||||
AddVariable( mv_animationSpeed,"AnimSpeed",functor(*this,OnAnimationChange) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::Done()
|
||||
{
|
||||
UnloadObject();
|
||||
CEntity::Done();
|
||||
}
|
||||
|
||||
void CStaticObject::UnloadObject()
|
||||
{
|
||||
UnloadEntity();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CStaticObject::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
//CBaseObject::Init( ie,prev,file );
|
||||
|
||||
SetColor( RGB(0,255,255) );
|
||||
|
||||
CEntity::Init( ie,prev,"" );
|
||||
|
||||
if (prev)
|
||||
{
|
||||
CStaticObject* po = (CStaticObject*)prev;
|
||||
LoadObject( po->GetObjectName(),true );
|
||||
}
|
||||
else if (!file.IsEmpty())
|
||||
{
|
||||
LoadObject( file,true );
|
||||
char filename[1024];
|
||||
_splitpath( file,0,0,filename,0 );
|
||||
SetUniqName( filename );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::SetScale( const Vec3d &scale )
|
||||
{
|
||||
CBaseObject::SetScale( scale );
|
||||
|
||||
IEntity *entity = GetIEntity();
|
||||
if (entity)
|
||||
{
|
||||
entity->SetScale( GetScale().x );
|
||||
CalcBBox();
|
||||
}
|
||||
if (m_animNode)
|
||||
{
|
||||
m_animNode->SetScale( GetIEditor()->GetAnimation()->GetTime(),scale );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::LoadObject( const CString &file,bool bForceReload )
|
||||
{
|
||||
// Ignore loading if object name is same as before.
|
||||
if (file == m_objectName && !m_loadFailed && !bForceReload)
|
||||
return;
|
||||
|
||||
m_objectName = file;
|
||||
|
||||
if (!IsCreateGameObjects())
|
||||
return;
|
||||
|
||||
CLogFile::FormatLine( "Loading Static Object %s",(const char*)file );
|
||||
|
||||
UnloadObject();
|
||||
|
||||
m_loadFailed = false;
|
||||
|
||||
// Spawn new entity.
|
||||
LoadEntity( "StaticEntity",true );
|
||||
// Load this static object to the entity.
|
||||
IEntity *entity = GetIEntity();
|
||||
if (entity)
|
||||
{
|
||||
if (entity->GetCharInterface()->LoadCharacter( 0,file ))
|
||||
{
|
||||
entity->DrawCharacter(0,ETY_DRAW_NORMAL);
|
||||
int flags = entity->GetCharInterface()->GetCharacter(0)->GetFlags();
|
||||
entity->GetCharInterface()->GetCharacter(0)->SetFlags(flags|CS_FLAG_UPDATE);
|
||||
// Character loaded.
|
||||
m_bCharacter = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Object loaded.
|
||||
entity->LoadObject( 0,m_objectName,1 );
|
||||
entity->DrawObject( 0,ETY_DRAW_NORMAL );
|
||||
m_bCharacter = false;
|
||||
}
|
||||
// CEntityObject the_object;
|
||||
// if (entity->GetEntityObject(0,the_object))
|
||||
// {
|
||||
// the_object.object->SetHideability(m_hidable);
|
||||
// }
|
||||
|
||||
entity->SetNetPresence(false);
|
||||
entity->SetScale( GetScale().x );
|
||||
|
||||
if (mv_rigidBody)
|
||||
{
|
||||
//entity->SetNeedUpdate(true);
|
||||
entity->CreateRigidBody(PE_RIGID, mv_density,mv_mass,0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
//entity->SetNeedUpdate(false);
|
||||
entity->CreateStaticEntity( mv_mass,0 );
|
||||
}
|
||||
|
||||
if (m_bCharacter)
|
||||
{
|
||||
OnAnimationChange(0);
|
||||
entity->GetCharInterface()->PhysicalizeCharacter(0,mv_mass,0 );
|
||||
}
|
||||
|
||||
CalcBBox();
|
||||
// new stuff - PETAR
|
||||
IPhysicalEntity *pPhysics = entity->GetPhysics();
|
||||
if (pPhysics)
|
||||
{
|
||||
if (mv_rigidBody)
|
||||
{
|
||||
pe_params_pos params;
|
||||
params.iSimClass = 1; // sleep.
|
||||
pPhysics->SetParams( ¶ms );
|
||||
}
|
||||
|
||||
pe_params_foreign_data pfn;
|
||||
pPhysics->GetParams(&pfn);
|
||||
if (mv_hidable)
|
||||
{
|
||||
pfn.iForeignFlags|=PFF_HIDABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pfn.iForeignFlags&=~PFF_HIDABLE;
|
||||
}
|
||||
pPhysics->SetParams(&pfn);
|
||||
}
|
||||
//----------------------------------
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::ReloadObject()
|
||||
{
|
||||
LoadObject( m_objectName,true );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::BeginEditParams( IEditor *ie,int flags )
|
||||
{
|
||||
CBaseObject::BeginEditParams( ie,flags );
|
||||
|
||||
if (!m_panel)
|
||||
{
|
||||
m_panel = new CStatObjPanel(AfxGetMainWnd());
|
||||
m_rollupId = GetIEditor()->AddRollUpPage( ROLLUP_OBJECTS,"StaticObject Parameters",m_panel );
|
||||
}
|
||||
if (m_panel)
|
||||
{
|
||||
m_panel->SetObject( this );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::EndEditParams( IEditor *ie )
|
||||
{
|
||||
if (m_rollupId != 0)
|
||||
GetIEditor()->RemoveRollUpPage( ROLLUP_OBJECTS,m_rollupId );
|
||||
|
||||
m_rollupId = 0;
|
||||
m_panel = 0;
|
||||
|
||||
CBaseObject::EndEditParams( ie );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::BeginEditMultiSelParams( bool bAllOfSameType )
|
||||
{
|
||||
CBaseObject::BeginEditMultiSelParams(bAllOfSameType);
|
||||
|
||||
if (bAllOfSameType)
|
||||
{
|
||||
m_panel = new CStatObjPanel(AfxGetMainWnd());
|
||||
m_rollupId = GetIEditor()->AddRollUpPage( ROLLUP_OBJECTS,"StaticObject Parameters",m_panel );
|
||||
m_panel->SetMultiSelect( true );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::EndEditMultiSelParams()
|
||||
{
|
||||
if (m_rollupId)
|
||||
GetIEditor()->RemoveRollUpPage( ROLLUP_OBJECTS,m_rollupId );
|
||||
m_rollupId = 0;
|
||||
m_panel = 0;
|
||||
|
||||
CBaseObject::EndEditMultiSelParams();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::Display( DisplayContext &dc )
|
||||
{
|
||||
if (!m_entity)
|
||||
return;
|
||||
|
||||
COLORREF col = GetColor();
|
||||
if (IsSelected())
|
||||
{
|
||||
//float scl = GetScale().x;
|
||||
|
||||
dc.PushMatrix( GetWorldTM() );
|
||||
|
||||
dc.SetSelectedColor();
|
||||
dc.DrawWireBox( m_box.min,m_box.max );
|
||||
|
||||
dc.PopMatrix();
|
||||
}
|
||||
else if (dc.flags & DISPLAY_2D)
|
||||
{
|
||||
dc.PushMatrix( GetWorldTM() );
|
||||
dc.SetColor( GetColor() );
|
||||
dc.DrawWireBox( m_box.min,m_box.max );
|
||||
dc.PopMatrix();
|
||||
}
|
||||
DrawDefault(dc,col);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::Serialize( CObjectArchive &ar )
|
||||
{
|
||||
CBaseObject::Serialize( ar );
|
||||
XmlNodeRef xmlNode = ar.node;
|
||||
if (ar.bLoading)
|
||||
{
|
||||
// Loading.
|
||||
m_loadFailed = false;
|
||||
|
||||
xmlNode->getAttr( "EntityId",m_entityId );
|
||||
xmlNode->getAttr( "ObjectName",m_objectName );
|
||||
LoadObject( m_objectName,true );
|
||||
|
||||
if (ar.bUndo && m_panel && m_panel->GetObject() == this)
|
||||
m_panel->UpdateObject();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Saving.
|
||||
if (m_entityId != 0)
|
||||
xmlNode->setAttr( "EntityId",m_entityId );
|
||||
|
||||
if (!m_objectName.IsEmpty())
|
||||
xmlNode->setAttr( "ObjectName",m_objectName );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
XmlNodeRef CStaticObject::Export( const CString &levelPath,XmlNodeRef &xmlNode )
|
||||
{
|
||||
// Ignore exporting.
|
||||
XmlNodeRef objNode = CEntity::Export( levelPath,xmlNode );
|
||||
objNode->setTag( "StaticEntity" );
|
||||
|
||||
if (m_bCharacter)
|
||||
{
|
||||
// Character.
|
||||
objNode->setAttr( "CharacterName",m_objectName );
|
||||
}
|
||||
else
|
||||
{
|
||||
objNode->setAttr( "ObjectName",m_objectName );
|
||||
}
|
||||
|
||||
return objNode;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::OnEvent( ObjectEvent event )
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case EVENT_UNLOAD_ENTITY:
|
||||
case EVENT_RELOAD_ENTITY:
|
||||
// For static objects ignore unloading of entity.
|
||||
return;
|
||||
|
||||
case EVENT_RELOAD_GEOM:
|
||||
ReloadObject();
|
||||
break;
|
||||
case EVENT_UNLOAD_GEOM:
|
||||
UnloadObject();
|
||||
break;
|
||||
|
||||
case EVENT_OUTOFGAME:
|
||||
// After exiting game reset simulation class to sleeping.
|
||||
if (m_entity)
|
||||
{
|
||||
IPhysicalEntity *pPhysics = m_entity->GetPhysics();
|
||||
if (pPhysics)
|
||||
{
|
||||
if (mv_rigidBody)
|
||||
{
|
||||
pe_params_pos params;
|
||||
params.iSimClass = 1; // sleep.
|
||||
pPhysics->SetParams( ¶ms );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
CEntity::OnEvent(event);
|
||||
return;
|
||||
/*
|
||||
CBaseObject::OnEvent(event);
|
||||
|
||||
if (!m_loadFailed && !m_objectName.IsEmpty())
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case EVENT_INGAME:
|
||||
if (!IsHidden())
|
||||
GetIEditor()->Get3DEngine()->AddStaticObject( m_objectName,GetPos(),GetScale().x );
|
||||
break;
|
||||
case EVENT_OUTOFGAME:
|
||||
if (!IsHidden())
|
||||
GetIEditor()->Get3DEngine()->RemoveStaticObject( m_objectName,GetPos() );
|
||||
break;
|
||||
case EVENT_REFRESH:
|
||||
// When refreshing make sure object is removed.
|
||||
GetIEditor()->Get3DEngine()->RemoveStaticObject( m_objectName,GetPos() );
|
||||
break;
|
||||
case EVENT_RELOAD_TEXTURES:
|
||||
// When refreshing make sure object is removed.
|
||||
if (m_object)
|
||||
m_object->Refresh(FRO_SHADERS|FRO_TEXTURES);
|
||||
break;
|
||||
case EVENT_RELOAD_GEOM:
|
||||
// When refreshing make sure object is removed.
|
||||
ReloadObject();
|
||||
break;
|
||||
case EVENT_UNLOAD_GEOM:
|
||||
// When refreshing make sure object is removed.
|
||||
ReleaseObject();
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void CStaticObject::SetRigidBody( bool enable )
|
||||
{
|
||||
StoreUndo( "RigidBody" );
|
||||
mv_rigidBody = enable;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::SetHidable( bool hidable )
|
||||
{
|
||||
StoreUndo( "Hidable" );
|
||||
|
||||
mv_hidable = hidable;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::SetMass( float mass )
|
||||
{
|
||||
StoreUndo( "Mass" );
|
||||
mv_mass = mass;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::OnRigidBodyChange( IVariable *var )
|
||||
{
|
||||
// Reload object.
|
||||
if (m_entity)
|
||||
LoadObject( m_objectName,true );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::OnMassChange( IVariable *var )
|
||||
{
|
||||
// Reload object.
|
||||
if (m_entity && mv_rigidBody)
|
||||
{
|
||||
IPhysicalEntity *phys = m_entity->GetPhysics();
|
||||
pe_params_pos param;
|
||||
//param.s
|
||||
//m_physic->SetParams(&temp);
|
||||
// phys->SetParams( LoadObject( m_objectName,true );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CStaticObject::OnAnimationChange( IVariable *var )
|
||||
{
|
||||
if (m_entity && m_bCharacter)
|
||||
{
|
||||
ICryCharInstance *character = m_entity->GetCharInterface()->GetCharacter(0);
|
||||
if (character)
|
||||
{
|
||||
CString anim = mv_animation;
|
||||
if (anim.IsEmpty())
|
||||
anim = "Default";
|
||||
|
||||
ICryAnimationSet *animSet = character->GetModel()->GetAnimationSet();
|
||||
if (animSet)
|
||||
{
|
||||
animSet->SetLoop( animSet->Find(anim),mv_animationLoop );
|
||||
}
|
||||
character->StartAnimation( anim );
|
||||
character->SetAnimationSpeed(mv_animationSpeed);
|
||||
}
|
||||
}
|
||||
}
|
||||
122
Editor/Objects/StatObj.h
Normal file
122
Editor/Objects/StatObj.h
Normal file
@@ -0,0 +1,122 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: StatObj.h
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: StaticObject object definition.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __StatObj_h__
|
||||
#define __StatObj_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "BaseObject.h"
|
||||
#include "Entity.h"
|
||||
|
||||
/*!
|
||||
* CStatObj is an static object on terrain.
|
||||
*
|
||||
*/
|
||||
class CStaticObject : public CEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CStaticObject)
|
||||
|
||||
// Operators.
|
||||
void LoadObject( const CString &file,bool bForceReload=false );
|
||||
void ReloadObject();
|
||||
void UnloadObject();
|
||||
|
||||
// Accessors.
|
||||
CString GetObjectName() { return m_objectName; };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
void Display( DisplayContext &disp );
|
||||
|
||||
void SetScale( const Vec3d &scale );
|
||||
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
void BeginEditMultiSelParams( bool bAllOfSameType );
|
||||
void EndEditMultiSelParams();
|
||||
|
||||
//void GetBoundSphere( Vec3d &pos,float &radius );
|
||||
//void GetBoundBox( BBox &box );
|
||||
//bool HitTest( HitContext &hc );
|
||||
|
||||
void Serialize( CObjectArchive &ar );
|
||||
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
|
||||
void OnEvent( ObjectEvent event );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SetRigidBody( bool enable );
|
||||
void SetMass( float mass );
|
||||
void SetHidable( bool enable );
|
||||
|
||||
bool IsRigidBody() const { return mv_rigidBody; }
|
||||
bool IsHideable() const { return mv_hidable; }
|
||||
float GetMass() const { return mv_mass; }
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CStaticObject();
|
||||
void DeleteThis() { delete this; };
|
||||
|
||||
void OnRigidBodyChange( IVariable *var );
|
||||
void OnMassChange( IVariable *var );
|
||||
void OnAnimationChange( IVariable *var );
|
||||
|
||||
CString m_objectName;
|
||||
|
||||
CVariable<bool> mv_rigidBody;
|
||||
CVariable<bool> mv_hidable;
|
||||
CVariable<float> mv_mass;
|
||||
CVariable<float> mv_density;
|
||||
CVariable<CString> mv_animation;
|
||||
CVariable<bool> mv_animationLoop;
|
||||
CVariable<float> mv_animationSpeed;
|
||||
|
||||
bool m_loadFailed;
|
||||
bool m_bCharacter;
|
||||
|
||||
static int m_rollupId;
|
||||
static class CStatObjPanel* m_panel;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of StaticObject
|
||||
*/
|
||||
class CStaticObjectClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {BE4B917B-CA10-4f3e-8B93-F54450FE840E}
|
||||
static const GUID guid = { 0xbe4b917b, 0xca10, 0x4f3e, { 0x8b, 0x93, 0xf5, 0x44, 0x50, 0xfe, 0x84, 0xe } };
|
||||
return guid;
|
||||
}
|
||||
void Release() { delete this; }
|
||||
ObjectType GetObjectType() { return OBJTYPE_STATIC; };
|
||||
const char* ClassName() { return "StdStatic"; };
|
||||
const char* Category() { return ""; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CStaticObject); };
|
||||
const char* GetFileSpec() { return "Objects\\*.cgf;*.ccgf;*.cga"; };
|
||||
};
|
||||
|
||||
#endif // __CStaticObject_h__
|
||||
161
Editor/Objects/TagComment.cpp
Normal file
161
Editor/Objects/TagComment.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: tagcomment.cpp
|
||||
// Version: v1.00
|
||||
// Created: 6/5/2003 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description: Special tag point for comment.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "TagComment.h"
|
||||
|
||||
#include "..\Viewport.h"
|
||||
#include "Settings.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CBase implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CTagComment,CBaseObject)
|
||||
|
||||
#define TAGCOMMENT_RADIUS 0.2f
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
float CTagComment::m_helperScale = 1;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CTagComment::CTagComment()
|
||||
{
|
||||
SetColor( RGB(255,160,0) );
|
||||
|
||||
AddVariable( mv_comment,"Comment" );
|
||||
AddVariable( mv_fixed,"Fixed" );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
float CTagComment::GetRadius()
|
||||
{
|
||||
return TAGCOMMENT_RADIUS*m_helperScale*gSettings.gizmo.helpersScale;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTagComment::SetScale( const Vec3d &scale )
|
||||
{
|
||||
// Ignore scale.
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CTagComment::MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags )
|
||||
{
|
||||
if (event == eMouseMove || event == eMouseLDown)
|
||||
{
|
||||
Vec3 pos;
|
||||
if (GetIEditor()->GetAxisConstrains() != AXIS_TERRAIN)
|
||||
{
|
||||
pos = view->MapViewToCP(point);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Snap to terrain.
|
||||
bool hitTerrain;
|
||||
pos = view->ViewToWorld( point,&hitTerrain );
|
||||
if (hitTerrain)
|
||||
{
|
||||
pos.z = GetIEditor()->GetTerrainElevation(pos.x,pos.y) + GetRadius()*2;
|
||||
}
|
||||
}
|
||||
|
||||
pos = view->SnapToGrid(pos);
|
||||
SetPos( pos );
|
||||
if (event == eMouseLDown)
|
||||
return MOUSECREATE_OK;
|
||||
return MOUSECREATE_CONTINUE;
|
||||
}
|
||||
return CBaseObject::MouseCreateCallback( view,event,point,flags );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTagComment::Display( DisplayContext &dc )
|
||||
{
|
||||
const Matrix44 &wtm = GetWorldTM();
|
||||
|
||||
Vec3 wp = wtm.GetTranslationOLD();
|
||||
|
||||
if (IsFrozen())
|
||||
dc.SetFreezeColor();
|
||||
else
|
||||
{
|
||||
if (!mv_fixed)
|
||||
dc.SetColor( GetColor(),0.8f );
|
||||
else
|
||||
// Fixed color.
|
||||
dc.SetColor( RGB(0,255,0),0.8f );
|
||||
}
|
||||
|
||||
float fHelperScale = 1*m_helperScale*gSettings.gizmo.helpersScale;
|
||||
Vec3 x = wtm.TransformVectorOLD( Vec3(0,-fHelperScale,0) );
|
||||
dc.DrawArrow( wp,wp+x*2,fHelperScale );
|
||||
|
||||
dc.DrawBall( wp,GetRadius() );
|
||||
|
||||
if (IsSelected())
|
||||
{
|
||||
dc.SetSelectedColor(0.6f);
|
||||
dc.DrawBall( wp,GetRadius()+0.02f );
|
||||
}
|
||||
|
||||
//if (!IsSelected())
|
||||
// dc.SetColor( RGB(255,255,255) );
|
||||
const char *szText = (CString)mv_comment;
|
||||
dc.DrawTextLabel( wp+Vec3(0,0,GetRadius()),1.2f,szText );
|
||||
|
||||
DrawDefault( dc );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CTagComment::HitTest( HitContext &hc )
|
||||
{
|
||||
Vec3 origin = GetWorldPos();
|
||||
float radius = GetRadius();
|
||||
|
||||
Vec3 w = origin - hc.raySrc;
|
||||
w = hc.rayDir.Cross( w );
|
||||
float d = w.Length();
|
||||
|
||||
if (d < radius + hc.distanceTollerance)
|
||||
{
|
||||
hc.dist = GetDistance(hc.raySrc,origin);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTagComment::GetBoundBox( BBox &box )
|
||||
{
|
||||
Vec3 pos = GetWorldPos();
|
||||
float r = GetRadius();
|
||||
box.min = pos - Vec3(r,r,r);
|
||||
box.max = pos + Vec3(r,r,r);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTagComment::GetLocalBounds( BBox &box )
|
||||
{
|
||||
float r = GetRadius();
|
||||
box.min = -Vec3(r,r,r);
|
||||
box.max = Vec3(r,r,r);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
XmlNodeRef CTagComment::Export( const CString &levelPath,XmlNodeRef &xmlNode )
|
||||
{
|
||||
// Dont export this. Only relevant for editor.
|
||||
return 0;
|
||||
}
|
||||
83
Editor/Objects/TagComment.h
Normal file
83
Editor/Objects/TagComment.h
Normal file
@@ -0,0 +1,83 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: tagcomment.h
|
||||
// Version: v1.00
|
||||
// Created: 6/5/2003 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description: Special tag point for comment.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __tagcomment_h__
|
||||
#define __tagcomment_h__
|
||||
#pragma once
|
||||
|
||||
#include "BaseObject.h"
|
||||
|
||||
/*!
|
||||
* CTagComment is an object that represent text commentary added to named 3d position in world.
|
||||
*
|
||||
*/
|
||||
class CTagComment : public CBaseObject
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CTagComment)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void Display( DisplayContext &disp );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetScale( const Vec3d &scale );
|
||||
|
||||
//! Called when object is being created.
|
||||
int MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags );
|
||||
bool HitTest( HitContext &hc );
|
||||
|
||||
void GetBoundBox( BBox &box );
|
||||
void GetLocalBounds( BBox &box );
|
||||
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual void SetHelperScale( float scale ) { m_helperScale = scale; };
|
||||
virtual float GetHelperScale() { return m_helperScale; };
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CTagComment();
|
||||
float GetRadius();
|
||||
|
||||
void DeleteThis() { delete this; };
|
||||
|
||||
CVariable<CString> mv_comment;
|
||||
CVariable<bool> mv_fixed;
|
||||
|
||||
static float m_helperScale;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of CTagComment.
|
||||
*/
|
||||
class CTagCommentClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {FAAA3955-EFE0-4888-85E8-C5481DC16FA5}
|
||||
static const GUID guid = { 0xfaaa3955, 0xefe0, 0x4888, { 0x85, 0xe8, 0xc5, 0x48, 0x1d, 0xc1, 0x6f, 0xa5 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_TAGPOINT; };
|
||||
const char* ClassName() { return "StdTagComment"; };
|
||||
const char* Category() { return ""; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CTagComment); };
|
||||
};
|
||||
|
||||
#endif // __tagcomment_h__
|
||||
355
Editor/Objects/TagPoint.cpp
Normal file
355
Editor/Objects/TagPoint.cpp
Normal file
@@ -0,0 +1,355 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: TagPoint.cpp
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: CTagPoint implementation.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "TagPoint.h"
|
||||
#include <IAgent.h>
|
||||
|
||||
#include "..\Viewport.h"
|
||||
#include "Settings.h"
|
||||
|
||||
#include <IAISystem.h>
|
||||
#include <IGame.h>
|
||||
#include <IMarkers.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CBase implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CTagPoint,CBaseObject)
|
||||
IMPLEMENT_DYNCREATE(CRespawnPoint,CTagPoint)
|
||||
|
||||
#define TAGPOINT_RADIUS 0.5f
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
float CTagPoint::m_helperScale = 1;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CTagPoint::CTagPoint()
|
||||
{
|
||||
m_ITag = 0;
|
||||
m_aiTag = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTagPoint::Done()
|
||||
{
|
||||
if (m_ITag)
|
||||
{
|
||||
GetIEditor()->GetGame()->GetTagPointManager()->RemoveTagPoint( m_ITag );
|
||||
m_ITag = 0;
|
||||
}
|
||||
if (m_aiTag)
|
||||
{
|
||||
m_ie->GetSystem()->GetAISystem()->RemoveObject(m_aiTag);
|
||||
m_aiTag = 0;
|
||||
}
|
||||
CBaseObject::Done();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CTagPoint::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
m_ie = ie;
|
||||
|
||||
SetColor( RGB(0,0,255) );
|
||||
bool res = CBaseObject::Init( ie,prev,file );
|
||||
|
||||
if (IsCreateGameObjects())
|
||||
{
|
||||
// Create Tag point in game.
|
||||
if (!GetName().IsEmpty())
|
||||
CreateITagPoint();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
float CTagPoint::GetRadius()
|
||||
{
|
||||
return TAGPOINT_RADIUS * m_helperScale * gSettings.gizmo.helpersScale;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTagPoint::SetName( const CString &name )
|
||||
{
|
||||
bool bModified = strcmp(name,GetName()) != 0;
|
||||
CBaseObject::SetName( name );
|
||||
|
||||
if (bModified)
|
||||
{
|
||||
CreateITagPoint();
|
||||
//if (m_aiTag)
|
||||
//m_aiTag->SetName(name);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTagPoint::CreateITagPoint()
|
||||
{
|
||||
if (IsCreateGameObjects())
|
||||
{
|
||||
IGame *pGame = GetIEditor()->GetGame();
|
||||
if (m_ITag)
|
||||
{
|
||||
pGame->GetTagPointManager()->RemoveTagPoint( m_ITag );
|
||||
m_ITag = 0;
|
||||
}
|
||||
if (m_aiTag)
|
||||
{
|
||||
m_ie->GetSystem()->GetAISystem()->RemoveObject(m_aiTag);
|
||||
m_aiTag = 0;
|
||||
}
|
||||
|
||||
const Matrix44 &tm = GetWorldTM();
|
||||
// Create Tag point in game.
|
||||
if (!GetName().IsEmpty())
|
||||
{
|
||||
|
||||
// Export world coordinates.
|
||||
//M2Q_CHANGED_BY_IVO
|
||||
//Quat q(tm);
|
||||
//Quat q = CovertMatToQuat<float>( GetTransposed44(tm) );
|
||||
Quat q = Quat( GetTransposed44(tm) );
|
||||
|
||||
Vec3 angles = RAD2DEG(Ang3::GetAnglesXYZ(Matrix33(q)));
|
||||
m_ITag = pGame->GetTagPointManager()->CreateTagPoint( (const char*)GetName(),GetWorldPos(),angles );
|
||||
}
|
||||
|
||||
//if (m_aiTag)
|
||||
m_aiTag = m_ie->GetSystem()->GetAISystem()->CreateAIObject( AIOBJECT_WAYPOINT,0 );
|
||||
m_aiTag->SetName( GetName() );
|
||||
m_aiTag->SetPos( tm.GetTranslationOLD() );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTagPoint::InvalidateTM()
|
||||
{
|
||||
CBaseObject::InvalidateTM();
|
||||
|
||||
if (m_ITag || m_aiTag)
|
||||
{
|
||||
const Matrix44 &tm = GetWorldTM();
|
||||
|
||||
//CHANGED_BY_IVO
|
||||
//Quat q(tm);
|
||||
//Quat q = CovertMatToQuat<float>( GetTransposed44(tm) );
|
||||
Quat q = Quat( GetTransposed44(tm) );
|
||||
|
||||
Vec3 angles = RAD2DEG(Ang3::GetAnglesXYZ(Matrix33(q)));
|
||||
if (m_ITag)
|
||||
{
|
||||
m_ITag->SetPos(tm.GetTranslationOLD());
|
||||
m_ITag->SetAngles(angles);
|
||||
}
|
||||
if (m_aiTag)
|
||||
{
|
||||
m_aiTag->SetPos(tm.GetTranslationOLD());
|
||||
m_aiTag->SetAngles(angles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTagPoint::SetScale( const Vec3d &scale )
|
||||
{
|
||||
// Ignore scale.
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTagPoint::BeginEditParams( IEditor *ie,int flags )
|
||||
{
|
||||
m_ie = ie;
|
||||
CBaseObject::BeginEditParams( ie,flags );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTagPoint::EndEditParams( IEditor *ie )
|
||||
{
|
||||
CBaseObject::EndEditParams( ie );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CTagPoint::MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags )
|
||||
{
|
||||
if (event == eMouseMove || event == eMouseLDown)
|
||||
{
|
||||
Vec3 pos;
|
||||
if (GetIEditor()->GetAxisConstrains() != AXIS_TERRAIN)
|
||||
{
|
||||
pos = view->MapViewToCP(point);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Snap to terrain.
|
||||
bool hitTerrain;
|
||||
pos = view->ViewToWorld( point,&hitTerrain );
|
||||
if (hitTerrain)
|
||||
{
|
||||
pos.z = GetIEditor()->GetTerrainElevation(pos.x,pos.y) + 1.0f;
|
||||
}
|
||||
pos = view->SnapToGrid(pos);
|
||||
}
|
||||
|
||||
pos = view->SnapToGrid(pos);
|
||||
SetPos( pos );
|
||||
if (event == eMouseLDown)
|
||||
return MOUSECREATE_OK;
|
||||
return MOUSECREATE_CONTINUE;
|
||||
}
|
||||
return CBaseObject::MouseCreateCallback( view,event,point,flags );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTagPoint::Display( DisplayContext &dc )
|
||||
{
|
||||
const Matrix44 &wtm = GetWorldTM();
|
||||
|
||||
//CHANGED_BY_IVO
|
||||
//Vec3 x = wtm.TransformVector( Vec3(0,-1,0) );
|
||||
float fHelperScale = 1*m_helperScale*gSettings.gizmo.helpersScale;
|
||||
Vec3 x = wtm.TransformVectorOLD( Vec3(0,-fHelperScale,0) );
|
||||
Vec3 wp = wtm.GetTranslationOLD();
|
||||
dc.SetColor( 1,1,0 );
|
||||
dc.DrawArrow( wp,wp+x*2,fHelperScale );
|
||||
|
||||
if (IsFrozen())
|
||||
dc.SetFreezeColor();
|
||||
else
|
||||
{
|
||||
if (m_ITag)
|
||||
dc.SetColor( GetColor(),0.8f );
|
||||
else
|
||||
{
|
||||
//Warning bad tag point name color.
|
||||
float t = GetTickCount() / 1000.0f;
|
||||
int r = fabs(sin(t*10.0f)*255);
|
||||
r = __min(r,255);
|
||||
dc.SetColor( RGB(r,0,0),0.2f );
|
||||
}
|
||||
}
|
||||
|
||||
dc.DrawBall( wp,GetRadius() );
|
||||
|
||||
if (IsSelected())
|
||||
{
|
||||
dc.SetSelectedColor(0.6f);
|
||||
dc.DrawBall( wp,GetRadius()+0.02f );
|
||||
}
|
||||
DrawDefault( dc );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CTagPoint::HitTest( HitContext &hc )
|
||||
{
|
||||
Vec3 origin = GetWorldPos();
|
||||
float radius = GetRadius();
|
||||
|
||||
Vec3 w = origin - hc.raySrc;
|
||||
w = hc.rayDir.Cross( w );
|
||||
float d = w.GetLengthSquared();
|
||||
|
||||
if (d < radius*radius + hc.distanceTollerance)
|
||||
{
|
||||
Vec3 i0;
|
||||
if (Intersect::Ray_SphereFirst(Ray(hc.raySrc,hc.rayDir),Sphere(origin,radius),i0))
|
||||
{
|
||||
hc.dist = GetDistance(hc.raySrc,i0);
|
||||
return true;
|
||||
}
|
||||
hc.dist = GetDistance(hc.raySrc,origin);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTagPoint::GetBoundBox( BBox &box )
|
||||
{
|
||||
Vec3 pos = GetWorldPos();
|
||||
float r = GetRadius();
|
||||
box.min = pos - Vec3(r,r,r);
|
||||
box.max = pos + Vec3(r,r,r);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTagPoint::GetLocalBounds( BBox &box )
|
||||
{
|
||||
float r = GetRadius();
|
||||
box.min = -Vec3(r,r,r);
|
||||
box.max = Vec3(r,r,r);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
XmlNodeRef CTagPoint::Export( const CString &levelPath,XmlNodeRef &xmlNode )
|
||||
{
|
||||
XmlNodeRef objNode = CBaseObject::Export( levelPath,xmlNode );
|
||||
|
||||
// Export position in world space.
|
||||
Matrix44 wtm = GetWorldTM();
|
||||
wtm.NoScale();
|
||||
|
||||
//CHANGED_BY_IVO
|
||||
//Quat q(wtm);
|
||||
//Quat q = CovertMatToQuat<float>( GetTransposed44(wtm) );
|
||||
Quat q = Quat( GetTransposed44(wtm) );
|
||||
|
||||
Vec3 worldPos = wtm.GetTranslationOLD();
|
||||
Vec3 worldAngles = Ang3::GetAnglesXYZ(Matrix33(q)) * 180.0f/gf_PI;
|
||||
|
||||
//if (worldPos != Vec3(0,0,0))
|
||||
if (!IsEquivalent(worldPos,Vec3(0,0,0)))
|
||||
objNode->setAttr( "Pos",worldPos );
|
||||
|
||||
//if (worldAngles != Vec3(0,0,0))
|
||||
if (!IsEquivalent(worldAngles,Vec3(0,0,0)))
|
||||
objNode->setAttr( "Angles",worldAngles );
|
||||
|
||||
|
||||
return objNode;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CRespawnPoint implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CRespawnPoint::CreateITagPoint()
|
||||
{
|
||||
if (IsCreateGameObjects())
|
||||
{
|
||||
IGame *pGame = GetIEditor()->GetGame();
|
||||
if (m_ITag)
|
||||
{
|
||||
pGame->GetTagPointManager()->RemoveRespawnPoint( m_ITag );
|
||||
pGame->GetTagPointManager()->RemoveTagPoint( m_ITag );
|
||||
}
|
||||
// Create Tag point in game.
|
||||
m_ITag = pGame->GetTagPointManager()->CreateTagPoint( (const char*)GetName(),GetWorldPos(),GetAngles() );
|
||||
if (m_ITag)
|
||||
pGame->GetTagPointManager()->AddRespawnPoint( m_ITag );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CRespawnPoint::Done()
|
||||
{
|
||||
if (m_ITag)
|
||||
{
|
||||
IGame *pGame = GetIEditor()->GetGame();
|
||||
pGame->GetTagPointManager()->RemoveRespawnPoint( m_ITag );
|
||||
}
|
||||
CTagPoint::Done();
|
||||
}
|
||||
126
Editor/Objects/TagPoint.h
Normal file
126
Editor/Objects/TagPoint.h
Normal file
@@ -0,0 +1,126 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: TagPoint.h
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: TagPoint object definition.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __TagPoint_h__
|
||||
#define __TagPoint_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "BaseObject.h"
|
||||
|
||||
/*!
|
||||
* CTagPoint is an object that represent named 3d position in world.
|
||||
*
|
||||
*/
|
||||
class CTagPoint : public CBaseObject
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CTagPoint)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
void Display( DisplayContext &disp );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetName( const CString &name );
|
||||
virtual void SetScale( const Vec3d &scale );
|
||||
virtual void InvalidateTM();
|
||||
|
||||
void BeginEditParams( IEditor *ie,int flags );
|
||||
void EndEditParams( IEditor *ie );
|
||||
|
||||
//! Called when object is being created.
|
||||
int MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags );
|
||||
bool HitTest( HitContext &hc );
|
||||
|
||||
void GetLocalBounds( BBox &box );
|
||||
void GetBoundBox( BBox &box );
|
||||
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual void SetHelperScale( float scale ) { m_helperScale = scale; };
|
||||
virtual float GetHelperScale() { return m_helperScale; };
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CTagPoint();
|
||||
|
||||
virtual void CreateITagPoint();
|
||||
float GetRadius();
|
||||
|
||||
void DeleteThis() { delete this; };
|
||||
|
||||
IEditor *m_ie;
|
||||
struct ITagPoint *m_ITag;
|
||||
struct IAIObject *m_aiTag;
|
||||
|
||||
//! Static, common to all tag points.
|
||||
static float m_helperScale;
|
||||
};
|
||||
|
||||
/** Respawn point is a special tag point where player will be respawn at begining or after death.
|
||||
*/
|
||||
class CRespawnPoint : public CTagPoint
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CRespawnPoint)
|
||||
|
||||
void Done();
|
||||
virtual void CreateITagPoint();
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of TagPoint.
|
||||
*/
|
||||
class CTagPointClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {7826D64A-080E-46cc-8C50-BA6A6CAE5175}
|
||||
static const GUID guid = { 0x7826d64a, 0x80e, 0x46cc, { 0x8c, 0x50, 0xba, 0x6a, 0x6c, 0xae, 0x51, 0x75 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_TAGPOINT; };
|
||||
const char* ClassName() { return "StdTagPoint"; };
|
||||
const char* Category() { return ""; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CTagPoint); };
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of TagPoint.
|
||||
*/
|
||||
class CRespawnPointClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {03A22E8A-0AB8-41fe-8503-75687A8A50BC}
|
||||
static const GUID guid = { 0x3a22e8a, 0xab8, 0x41fe, { 0x85, 0x3, 0x75, 0x68, 0x7a, 0x8a, 0x50, 0xbc } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_TAGPOINT; };
|
||||
const char* ClassName() { return "Respawn"; };
|
||||
const char* Category() { return "TagPoint"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CRespawnPoint); };
|
||||
};
|
||||
|
||||
#endif // __TagPoint_h__
|
||||
225
Editor/Objects/TrackGizmo.cpp
Normal file
225
Editor/Objects/TrackGizmo.cpp
Normal file
@@ -0,0 +1,225 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: trackgizmo.cpp
|
||||
// Version: v1.00
|
||||
// Created: 2/7/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "TrackGizmo.h"
|
||||
#include "DisplayContext.h"
|
||||
|
||||
#include "..\Viewport.h"
|
||||
#include "..\DisplaySettings.h"
|
||||
#include "ObjectManager.h"
|
||||
|
||||
#include <IMovieSystem.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CTrackGizmo implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
#define AXIS_SIZE 0.1f
|
||||
|
||||
namespace {
|
||||
int s_highlightAxis = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CTrackGizmo::CTrackGizmo()
|
||||
{
|
||||
m_animNode = 0;
|
||||
|
||||
m_bbox.min = Vec3(-10000,-10000,-10000);
|
||||
m_bbox.max = Vec3(10000,10000,10000);
|
||||
m_keysSelected = false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CTrackGizmo::~CTrackGizmo()
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTrackGizmo::Display( DisplayContext &dc )
|
||||
{
|
||||
if (!(dc.flags & DISPLAY_TRACKS))
|
||||
return;
|
||||
|
||||
if (!m_animNode)
|
||||
return;
|
||||
|
||||
uint hideMask = GetIEditor()->GetDisplaySettings()->GetObjectHideMask();
|
||||
|
||||
CAnimationContext *ac = GetIEditor()->GetAnimation();
|
||||
|
||||
// Should have animation sequence.
|
||||
if (!ac->GetSequence())
|
||||
return;
|
||||
|
||||
IAnimBlock *ablock = m_animNode->GetAnimBlock();
|
||||
if (!ablock)
|
||||
return;
|
||||
|
||||
m_keysSelected = false;
|
||||
|
||||
// Must have non empty position track.
|
||||
IAnimTrack *track = ablock->GetTrack(APARAM_POS);
|
||||
if (!track)
|
||||
return;
|
||||
|
||||
int nkeys = track->GetNumKeys();
|
||||
if (nkeys < 2)
|
||||
return;
|
||||
|
||||
Range range = ac->GetTimeRange();
|
||||
range.start = __min(range.end,track->GetKeyTime(0));
|
||||
range.end = __min(range.end,track->GetKeyTime(nkeys-1));
|
||||
//float step = range.Length() / 100.0f;
|
||||
//step = min(step,0.01f);
|
||||
float step = 0.1f;
|
||||
|
||||
bool bTicks = (dc.flags & DISPLAY_TRACKTICKS) == DISPLAY_TRACKTICKS;
|
||||
|
||||
// Get Spline color.
|
||||
Vec3 splineCol(0.5f,0.3f,1);
|
||||
Vec3 timeCol(0,1,0);
|
||||
|
||||
m_bbox.Reset();
|
||||
|
||||
float zOffset = 0.01f;
|
||||
Vec3 p0,p1;
|
||||
Vec3 tick(0,0,0.05f);
|
||||
track->GetValue( range.start,p0 );
|
||||
p0.z += zOffset;
|
||||
|
||||
// Update bounding box.
|
||||
m_bbox.Add( p0 );
|
||||
|
||||
const Matrix44 &wtm = GetMatrix();
|
||||
p0 = wtm.TransformPointOLD(p0);
|
||||
|
||||
for (float t = range.start+step; t < range.end; t += step)
|
||||
{
|
||||
track->GetValue( t,p1 );
|
||||
// Update bounding box.
|
||||
m_bbox.Add( p1 );
|
||||
|
||||
p1 = wtm.TransformPointOLD(p1);
|
||||
|
||||
p1.z += zOffset;
|
||||
// Get Spline color.
|
||||
//dc.SetColor( splineCol.x,splineCol.y,splineCol.z,1 );
|
||||
if (bTicks)
|
||||
dc.DrawLine( p0-tick,p0+tick,timeCol,timeCol );
|
||||
dc.DrawLine( p0,p1,splineCol,splineCol );
|
||||
p0 = p1;
|
||||
}
|
||||
|
||||
// Get Key color.
|
||||
dc.SetColor( 1,0,0,1 );
|
||||
float sz = 0.2f;
|
||||
for (int i = 0; i < nkeys; i++)
|
||||
{
|
||||
float t = track->GetKeyTime(i);
|
||||
track->GetValue( t,p0 );
|
||||
p0 = wtm.TransformPointOLD(p0);
|
||||
p0.z += zOffset;
|
||||
|
||||
//float sz = 0.01f * dc.view->GetScreenScaleFactor(p0);
|
||||
float sz = 0.005f * dc.view->GetScreenScaleFactor(p0);
|
||||
|
||||
// Draw quad.
|
||||
//dc.DrawBall( p0,sz );
|
||||
dc.DrawWireBox( p0-Vec3(sz,sz,sz),p0+Vec3(sz,sz,sz) );
|
||||
|
||||
if (track->GetKeyFlags(i) & AKEY_SELECTED)
|
||||
{
|
||||
m_keysSelected = true;
|
||||
DrawAxis( dc,p0 );
|
||||
dc.SetColor( 1,0,0,1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTrackGizmo::SetAnimNode( IAnimNode *node )
|
||||
{
|
||||
m_animNode = node;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTrackGizmo::GetWorldBounds( BBox &bbox )
|
||||
{
|
||||
bbox = m_bbox;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTrackGizmo::DrawAxis( DisplayContext &dc,const Vec3 &org )
|
||||
{
|
||||
float size = AXIS_SIZE;
|
||||
|
||||
int prevRState = dc.SetStateFlag(GS_NODEPTHTEST);
|
||||
|
||||
Vec3 x(size,0,0);
|
||||
Vec3 y(0,size,0);
|
||||
Vec3 z(0,0,size);
|
||||
|
||||
float fScreenScale = dc.view->GetScreenScaleFactor(org);
|
||||
x = x * fScreenScale;
|
||||
y = y * fScreenScale;
|
||||
z = z * fScreenScale;
|
||||
|
||||
float col[4] = { 1,1,1,1 };
|
||||
float hcol[4] = { 1,0,0,1 };
|
||||
dc.renderer->DrawLabelEx( org+x,1.2f,col,true,true,"X" );
|
||||
dc.renderer->DrawLabelEx( org+y,1.2f,col,true,true,"Y" );
|
||||
dc.renderer->DrawLabelEx( org+z,1.2f,col,true,true,"Z" );
|
||||
|
||||
Vec3 colX(1,0,0),colY(0,1,0),colZ(0,0,1);
|
||||
if (s_highlightAxis)
|
||||
{
|
||||
float col[4] = { 1,0,0,1 };
|
||||
if (s_highlightAxis == 1)
|
||||
{
|
||||
colX(1,1,0);
|
||||
dc.renderer->DrawLabelEx( org+x,1.2f,col,true,true,"X" );
|
||||
}
|
||||
if (s_highlightAxis == 2)
|
||||
{
|
||||
colY(1,1,0);
|
||||
dc.renderer->DrawLabelEx( org+y,1.2f,col,true,true,"Y" );
|
||||
}
|
||||
if (s_highlightAxis == 3)
|
||||
{
|
||||
colZ(1,1,0);
|
||||
dc.renderer->DrawLabelEx( org+z,1.2f,col,true,true,"Z" );
|
||||
}
|
||||
}
|
||||
|
||||
x = x * 0.8f;
|
||||
y = y * 0.8f;
|
||||
z = z * 0.8f;
|
||||
float fArrowScale = fScreenScale * 0.07f;
|
||||
dc.SetColor( colX );
|
||||
dc.DrawArrow( org,org+x,fArrowScale );
|
||||
dc.SetColor( colY );
|
||||
dc.DrawArrow( org,org+y,fArrowScale );
|
||||
dc.SetColor( colZ );
|
||||
dc.DrawArrow( org,org+z,fArrowScale );
|
||||
|
||||
dc.SetState( prevRState );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CTrackGizmo::HitTest( HitContext &hc )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
57
Editor/Objects/TrackGizmo.h
Normal file
57
Editor/Objects/TrackGizmo.h
Normal file
@@ -0,0 +1,57 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: trackgizmo.h
|
||||
// Version: v1.00
|
||||
// Created: 2/7/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __trackgizmo_h__
|
||||
#define __trackgizmo_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "Gizmo.h"
|
||||
|
||||
// forward declarations.
|
||||
struct DisplayContext;
|
||||
struct IAnimNode;
|
||||
|
||||
/** Gizmo of Objects animation track.
|
||||
*/
|
||||
class CTrackGizmo : public CGizmo
|
||||
{
|
||||
public:
|
||||
CTrackGizmo();
|
||||
~CTrackGizmo();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CGizmo
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void GetWorldBounds( BBox &bbox );
|
||||
virtual void Display( DisplayContext &dc );
|
||||
virtual bool HitTest( HitContext &hc );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SetAnimNode( IAnimNode *node );
|
||||
void DrawAxis( DisplayContext &dc,const Vec3 &pos );
|
||||
|
||||
private:
|
||||
IAnimNode *m_animNode;
|
||||
BBox m_bbox;
|
||||
bool m_keysSelected;
|
||||
};
|
||||
|
||||
// Define CGizmoPtr smart pointer.
|
||||
SMARTPTR_TYPEDEF(CTrackGizmo);
|
||||
|
||||
#endif // __trackgizmo_h__
|
||||
201
Editor/Objects/VisAreaShapeObject.cpp
Normal file
201
Editor/Objects/VisAreaShapeObject.cpp
Normal file
@@ -0,0 +1,201 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: VisAreaShapeObject.cpp
|
||||
// Version: v1.00
|
||||
// Created: 10/12/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "VisAreaShapeObject.h"
|
||||
|
||||
#include <I3DEngine.h>
|
||||
#include <ISound.h> // to RecomputeSoundOcclusion() when deleting a vis area
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CVisAreaShapeObject,CShapeObject)
|
||||
IMPLEMENT_DYNCREATE(COccluderShapeObject,CVisAreaShapeObject)
|
||||
IMPLEMENT_DYNCREATE(CPortalShapeObject,CVisAreaShapeObject)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CVisAreaShapeObject::CVisAreaShapeObject()
|
||||
{
|
||||
m_area = 0;
|
||||
mv_height = 5;
|
||||
m_bDisplayFilledWhenSelected = true;
|
||||
|
||||
mv_vAmbientColor = Vec3d(0.25f,0.25f,0.25f);
|
||||
mv_vDynAmbientColor = Vec3d(0,0,0);
|
||||
mv_bAffectedBySun = false;
|
||||
mv_fViewDistRatio = 100.f;
|
||||
mv_bSkyOnly = false;
|
||||
|
||||
AddVariable( mv_vAmbientColor,"AmbientColor",functor(*this, &CVisAreaShapeObject::OnShapeChange), IVariable::DT_COLOR );
|
||||
AddVariable( mv_vDynAmbientColor,"DynAmbientColor",functor(*this, &CVisAreaShapeObject::OnShapeChange), IVariable::DT_COLOR );
|
||||
AddVariable( mv_bAffectedBySun,"AffectedBySun",functor(*this, &CVisAreaShapeObject::OnShapeChange) );
|
||||
AddVariable( mv_fViewDistRatio,"ViewDistRatio",functor(*this, &CVisAreaShapeObject::OnShapeChange) );
|
||||
AddVariable( mv_bSkyOnly,"SkyOnly",functor(*this, &CVisAreaShapeObject::OnShapeChange) );
|
||||
|
||||
SetColor( RGB(255,128,0) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CVisAreaShapeObject::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
bool res = CShapeObject::Init( ie,prev,file );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CVisAreaShapeObject::Done()
|
||||
{
|
||||
if (m_area)
|
||||
{
|
||||
// reset the listener vis area in the unlucky case that we are deleting the
|
||||
// vis area where the listener is currently in
|
||||
GetIEditor()->GetSystem()->GetISoundSystem()->RecomputeSoundOcclusion(false,false,true);
|
||||
GetIEditor()->Get3DEngine()->DeleteVisArea(m_area);
|
||||
m_area = 0;
|
||||
}
|
||||
CShapeObject::Done();
|
||||
}
|
||||
|
||||
bool CVisAreaShapeObject::CreateGameObject()
|
||||
{
|
||||
if (!m_area)
|
||||
{
|
||||
m_area = GetIEditor()->Get3DEngine()->CreateVisArea();
|
||||
m_bAreaModified = true;
|
||||
UpdateGameArea(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CVisAreaShapeObject::UpdateGameArea( bool bRemove )
|
||||
{
|
||||
if (bRemove)
|
||||
return;
|
||||
if (!m_bAreaModified)
|
||||
return;
|
||||
|
||||
if (m_area)
|
||||
{
|
||||
std::vector<Vec3> points;
|
||||
if (GetPointCount() > 3)
|
||||
{
|
||||
const Matrix44 &wtm = GetWorldTM();
|
||||
points.resize(GetPointCount());
|
||||
for (int i = 0; i < GetPointCount(); i++)
|
||||
{
|
||||
points[i] = wtm.TransformPointOLD( GetPoint(i) );
|
||||
}
|
||||
|
||||
Vec3d vAmbClr = mv_vAmbientColor;
|
||||
Vec3d vDynAmbClr = mv_vDynAmbientColor;
|
||||
GetIEditor()->Get3DEngine()->UpdateVisArea( m_area, &points[0],points.size(), GetName(), GetHeight(), vAmbClr, mv_bAffectedBySun, mv_bSkyOnly, vDynAmbClr, mv_fViewDistRatio, true, false, false );
|
||||
}
|
||||
}
|
||||
m_bAreaModified = false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CPortalShapeObject
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CPortalShapeObject::CPortalShapeObject()
|
||||
{
|
||||
m_bDisplayFilledWhenSelected = true;
|
||||
SetColor( RGB(100,250,60) );
|
||||
|
||||
mv_bUseDeepness = false;
|
||||
mv_bDoubleSide = true;
|
||||
AddVariable( mv_bUseDeepness,"UseDeepness",functor(*this,&CPortalShapeObject::OnShapeChange) );
|
||||
AddVariable( mv_bDoubleSide,"DoubleSide",functor(*this,&CPortalShapeObject::OnShapeChange) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPortalShapeObject::UpdateGameArea( bool bRemove )
|
||||
{
|
||||
if (bRemove)
|
||||
return;
|
||||
|
||||
if (!m_bAreaModified)
|
||||
return;
|
||||
|
||||
if (m_area)
|
||||
{
|
||||
std::vector<Vec3> points;
|
||||
if (GetPointCount() > 3)
|
||||
{
|
||||
const Matrix44 &wtm = GetWorldTM();
|
||||
points.resize(GetPointCount());
|
||||
for (int i = 0; i < GetPointCount(); i++)
|
||||
{
|
||||
points[i] = wtm.TransformPointOLD( GetPoint(i) );
|
||||
}
|
||||
|
||||
CString name = CString("Portal_") + GetName();
|
||||
|
||||
Vec3d vAmbClr = mv_vAmbientColor;
|
||||
Vec3d vDynAmbClr = mv_vDynAmbientColor;
|
||||
GetIEditor()->Get3DEngine()->UpdateVisArea( m_area, &points[0],points.size(), name, GetHeight(), vAmbClr, mv_bAffectedBySun, mv_bSkyOnly, vDynAmbClr, mv_fViewDistRatio, mv_bDoubleSide, mv_bUseDeepness, false );
|
||||
}
|
||||
}
|
||||
m_bAreaModified = false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
COccluderShapeObject::COccluderShapeObject()
|
||||
{
|
||||
m_bDisplayFilledWhenSelected = true;
|
||||
SetColor( RGB(200,128,60) );
|
||||
|
||||
mv_bUseInIndoors = false;
|
||||
mv_bDoubleSide = true;
|
||||
AddVariable( mv_bUseInIndoors,"UseInIndoors",functor(*this,&COccluderShapeObject::OnShapeChange) );
|
||||
AddVariable( mv_bDoubleSide,"DoubleSide",functor(*this,&COccluderShapeObject::OnShapeChange) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void COccluderShapeObject::UpdateGameArea( bool bRemove )
|
||||
{
|
||||
if (bRemove)
|
||||
return;
|
||||
if (!m_bAreaModified)
|
||||
return;
|
||||
|
||||
if (m_area)
|
||||
{
|
||||
std::vector<Vec3> points;
|
||||
if (GetPointCount() > 1)
|
||||
{
|
||||
const Matrix44 &wtm = GetWorldTM();
|
||||
points.resize(GetPointCount());
|
||||
for (int i = 0; i < GetPointCount(); i++)
|
||||
{
|
||||
points[i] = wtm.TransformPointOLD( GetPoint(i) );
|
||||
}
|
||||
|
||||
CString name = CString("OcclArea_") + GetName();
|
||||
|
||||
Vec3d vAmbClr = mv_vAmbientColor;
|
||||
Vec3d vDynAmbClr = mv_vDynAmbientColor;
|
||||
GetIEditor()->Get3DEngine()->UpdateVisArea( m_area, &points[0],points.size(), name, GetHeight(), vAmbClr, mv_bAffectedBySun, mv_bSkyOnly, vDynAmbClr, mv_fViewDistRatio, mv_bDoubleSide, false, mv_bUseInIndoors );
|
||||
}
|
||||
}
|
||||
m_bAreaModified = false;
|
||||
}
|
||||
142
Editor/Objects/VisAreaShapeObject.h
Normal file
142
Editor/Objects/VisAreaShapeObject.h
Normal file
@@ -0,0 +1,142 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: VisAreaShapeObject.h
|
||||
// Version: v1.00
|
||||
// Created: 10/12/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __visareashapeobject_h__
|
||||
#define __visareashapeobject_h__
|
||||
#pragma once
|
||||
|
||||
#include "ShapeObject.h"
|
||||
|
||||
/** Represent Visibiility Area, visibility areas can be connected with portals.
|
||||
*/
|
||||
class CVisAreaShapeObject : public CShapeObject
|
||||
{
|
||||
DECLARE_DYNCREATE(CVisAreaShapeObject)
|
||||
public:
|
||||
CVisAreaShapeObject();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
bool CreateGameObject();
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected:
|
||||
virtual bool IsOnlyUpdateOnUnselect() const { return true; }
|
||||
virtual void UpdateGameArea( bool bRemove=false );
|
||||
|
||||
// Visibilty area in 3d engine.
|
||||
struct IVisArea* m_area;
|
||||
CVariable<Vec3d> mv_vAmbientColor;
|
||||
CVariable<bool> mv_bAffectedBySun;
|
||||
CVariable<Vec3d> mv_vDynAmbientColor;
|
||||
CVariable<float> mv_fViewDistRatio;
|
||||
CVariable<bool> mv_bSkyOnly;
|
||||
};
|
||||
|
||||
/** Represent Portal Area.
|
||||
Portal connect visibility areas, visibility between vis areas are only done with portals.
|
||||
*/
|
||||
class CPortalShapeObject : public CVisAreaShapeObject
|
||||
{
|
||||
DECLARE_DYNCREATE(CPortalShapeObject)
|
||||
public:
|
||||
CPortalShapeObject();
|
||||
|
||||
protected:
|
||||
virtual int GetMaxPoints() const { return 4; };
|
||||
virtual void UpdateGameArea( bool bRemove=false );
|
||||
|
||||
CVariable<bool> mv_bUseDeepness;
|
||||
CVariable<bool> mv_bDoubleSide;
|
||||
};
|
||||
|
||||
/** Represent Occluder Area.
|
||||
Areas that occlude objects behind it.
|
||||
*/
|
||||
class COccluderShapeObject : public CVisAreaShapeObject
|
||||
{
|
||||
DECLARE_DYNCREATE(COccluderShapeObject)
|
||||
public:
|
||||
COccluderShapeObject();
|
||||
|
||||
protected:
|
||||
virtual int GetMaxPoints() const { return 4; };
|
||||
virtual void UpdateGameArea( bool bRemove=false );
|
||||
|
||||
CVariable<bool> mv_bUseInIndoors;
|
||||
CVariable<bool> mv_bDoubleSide;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of CVisAreaShapeObject.
|
||||
*/
|
||||
class CVisAreaShapeObjectClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {31B912A0-D351-4abc-AA8F-B819CED21231}
|
||||
static const GUID guid = { 0x31b912a0, 0xd351, 0x4abc, { 0xaa, 0x8f, 0xb8, 0x19, 0xce, 0xd2, 0x12, 0x31 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_VOLUME; };
|
||||
const char* ClassName() { return "VisArea"; };
|
||||
const char* Category() { return "Area"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CVisAreaShapeObject); };
|
||||
int GameCreationOrder() { return 10; };
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of CPortalShapeObject.
|
||||
*/
|
||||
class CPortalShapeObjectClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {D8665C26-AE2D-482b-9574-B6E2C9253E40}
|
||||
static const GUID guid = { 0xd8665c26, 0xae2d, 0x482b, { 0x95, 0x74, 0xb6, 0xe2, 0xc9, 0x25, 0x3e, 0x40 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_VOLUME; };
|
||||
const char* ClassName() { return "Portal"; };
|
||||
const char* Category() { return "Area"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CPortalShapeObject); };
|
||||
int GameCreationOrder() { return 11; };
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of COccluderShapeObject.
|
||||
*/
|
||||
class COccluderShapeObjectClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {76D000C3-47E8-420a-B4C9-17F698C1A607}
|
||||
static const GUID guid = { 0x76d000c3, 0x47e8, 0x420a, { 0xb4, 0xc9, 0x17, 0xf6, 0x98, 0xc1, 0xa6, 0x7 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_VOLUME; };
|
||||
const char* ClassName() { return "OccluderArea"; };
|
||||
const char* Category() { return "Area"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(COccluderShapeObject); };
|
||||
int GameCreationOrder() { return 12; };
|
||||
};
|
||||
|
||||
#endif // __visareashapeobject_h__
|
||||
229
Editor/Objects/Volume.cpp
Normal file
229
Editor/Objects/Volume.cpp
Normal file
@@ -0,0 +1,229 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: TagPoint.cpp
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: CVolume implementation.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "Volume.h"
|
||||
|
||||
#include "..\Viewport.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CBase implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CVolume,CBaseObject)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CVolume::CVolume()
|
||||
{
|
||||
m_box.min = Vec3(-1,-1,0);
|
||||
m_box.max = Vec3(1,1,2);
|
||||
|
||||
// Initials.
|
||||
mv_width = 4;
|
||||
mv_length = 4;
|
||||
mv_height = 1;
|
||||
mv_viewDistance = 4;
|
||||
|
||||
AddVariable( mv_width,"Width",functor(*this,&CVolume::OnSizeChange) );
|
||||
AddVariable( mv_length,"Length",functor(*this,&CVolume::OnSizeChange) );
|
||||
AddVariable( mv_height,"Height",functor(*this,&CVolume::OnSizeChange) );
|
||||
AddVariable( mv_viewDistance,"ViewDistance" );
|
||||
AddVariable( mv_shader,"Shader",0,IVariable::DT_SHADER );
|
||||
AddVariable( mv_fogColor,"Color",0,IVariable::DT_COLOR );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CVolume::Done()
|
||||
{
|
||||
CBaseObject::Done();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CVolume::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
bool res = CBaseObject::Init( ie,prev,file );
|
||||
SetColor( RGB(0,0,255) );
|
||||
if (prev)
|
||||
{
|
||||
m_sphere = ((CVolume*)prev)->m_sphere;
|
||||
m_box = ((CVolume*)prev)->m_box;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CVolume::GetBoundBox( BBox &box )
|
||||
{
|
||||
box = m_box;
|
||||
box.Transform( GetWorldTM() );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CVolume::GetLocalBounds( BBox &box )
|
||||
{
|
||||
box = m_box;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CVolume::SetAngles( const Vec3d &angles )
|
||||
{
|
||||
// Ignore angles on Volume.
|
||||
}
|
||||
|
||||
void CVolume::SetScale( const Vec3d &scale )
|
||||
{
|
||||
// Ignore scale on Volume.
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CVolume::HitTest( HitContext &hc )
|
||||
{
|
||||
Vec3 p;
|
||||
BBox box;
|
||||
GetBoundBox( box );
|
||||
if (box.IsIntersectRay(hc.raySrc,hc.rayDir,p ))
|
||||
{
|
||||
hc.dist = Vec3(hc.raySrc - p).Length();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CVolume::OnSizeChange( IVariable *var )
|
||||
{
|
||||
Vec3 size( 0,0,0 );
|
||||
size.x = mv_width;
|
||||
size.y = mv_length;
|
||||
size.z = mv_height;
|
||||
|
||||
m_box.min = -size/2;
|
||||
m_box.max = size/2;
|
||||
// Make volume position bottom of bounding box.
|
||||
m_box.min.z = 0;
|
||||
m_box.max.z = size.z;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CVolume::Display( DisplayContext &dc )
|
||||
{
|
||||
COLORREF wireColor,solidColor;
|
||||
float wireOffset = 0;
|
||||
float alpha = 0.3f;
|
||||
if (IsSelected())
|
||||
{
|
||||
wireColor = dc.GetSelectedColor();
|
||||
solidColor = GetColor();
|
||||
wireOffset = -0.1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
wireColor = GetColor();
|
||||
solidColor = GetColor();
|
||||
}
|
||||
|
||||
dc.renderer->SetCullMode( R_CULL_DISABLE );
|
||||
int rstate = dc.ClearStateFlag( GS_DEPTHWRITE );
|
||||
|
||||
BBox box;
|
||||
const Matrix44 &tm = GetWorldTM();
|
||||
box.min = tm.TransformPointOLD(m_box.min);
|
||||
box.max = tm.TransformPointOLD(m_box.max);
|
||||
|
||||
|
||||
bool bFrozen = IsFrozen();
|
||||
|
||||
if (bFrozen)
|
||||
dc.SetFreezeColor();
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (!bFrozen)
|
||||
dc.SetColor( solidColor,alpha );
|
||||
//dc.DrawSolidBox( box.min,box.max );
|
||||
|
||||
if (!bFrozen)
|
||||
dc.SetColor( wireColor,1 );
|
||||
dc.DrawWireBox( box.min,box.max,wireOffset );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
dc.renderer->SetCullMode( R_CULL_BACK );
|
||||
dc.SetState( rstate );
|
||||
|
||||
|
||||
DrawDefault(dc);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CVolume::Serialize( CObjectArchive &ar )
|
||||
{
|
||||
CBaseObject::Serialize( ar );
|
||||
XmlNodeRef xmlNode = ar.node;
|
||||
if (ar.bLoading)
|
||||
{
|
||||
xmlNode->getAttr( "BoxMin",m_box.min );
|
||||
xmlNode->getAttr( "BoxMax",m_box.max );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Saving.
|
||||
xmlNode->setAttr( "BoxMin",m_box.min );
|
||||
xmlNode->setAttr( "BoxMax",m_box.max );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
XmlNodeRef CVolume::Export( const CString &levelPath,XmlNodeRef &xmlNode )
|
||||
{
|
||||
XmlNodeRef objNode = CBaseObject::Export( levelPath,xmlNode );
|
||||
|
||||
// Export position in world space.
|
||||
Matrix44 wtm = GetWorldTM();
|
||||
AffineParts affineParts;
|
||||
affineParts.SpectralDecompose(wtm);
|
||||
Vec3 worldPos = affineParts.pos;
|
||||
Vec3 worldAngles = RAD2DEG(Ang3::GetAnglesXYZ(Matrix33(affineParts.rot)));
|
||||
|
||||
if (!IsEquivalent(worldPos,Vec3(0,0,0),0))
|
||||
objNode->setAttr( "Pos",worldPos );
|
||||
|
||||
if (!IsEquivalent(worldAngles,Vec3(0,0,0),0))
|
||||
objNode->setAttr( "Angles",worldAngles );
|
||||
|
||||
objNode->setAttr( "BoxMin",wtm.TransformPointOLD(m_box.min) );
|
||||
objNode->setAttr( "BoxMax",wtm.TransformPointOLD(m_box.max) );
|
||||
return objNode;
|
||||
|
||||
/*
|
||||
CString volumeName,volumeParam;
|
||||
|
||||
BBox box;
|
||||
GetBoundBox( box );
|
||||
|
||||
volumeName = GetClassDesc()->GetTypeName() + "_" + GetName();
|
||||
volumeParam.Format( "Box{ %.2f,%.2f,%.2f,%.2f,%.2f,%.2f } ",box.min.x,box.min.y,box.min.z,box.max.x,box.max.y,box.max.z );
|
||||
|
||||
if (GetParams())
|
||||
{
|
||||
CString str;
|
||||
XmlAttributes attributes = GetParams()->getAttributes();
|
||||
for (XmlAttributes::iterator it = attributes.begin(); it != attributes.end(); ++it)
|
||||
{
|
||||
str.Format( "%s{ %s } ",(const char*)it->key,(const char*)it->value );
|
||||
volumeParam += str;
|
||||
}
|
||||
}
|
||||
WritePrivateProfileString( "",volumeName,volumeParam,levelPath+"Volumes.ini" );
|
||||
|
||||
return CBaseObject::Export( levelPath,xmlNode );
|
||||
*/
|
||||
}
|
||||
95
Editor/Objects/Volume.h
Normal file
95
Editor/Objects/Volume.h
Normal file
@@ -0,0 +1,95 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2001.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: Volume.h
|
||||
// Version: v1.00
|
||||
// Created: 10/10/2001 by Timur.
|
||||
// Compilers: Visual C++ 6.0
|
||||
// Description: TagPoint object definition.
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __Volume_h__
|
||||
#define __Volume_h__
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "BaseObject.h"
|
||||
|
||||
/*!
|
||||
* CVolume is an spherical or box volume in space.
|
||||
*
|
||||
*/
|
||||
class CVolume : public CBaseObject
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNCREATE(CVolume)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
|
||||
void Display( DisplayContext &dc );
|
||||
|
||||
void SetAngles( const Vec3d &angles );
|
||||
void SetScale( const Vec3d &scale );
|
||||
|
||||
void GetBoundBox( BBox &box );
|
||||
void GetLocalBounds( BBox &box );
|
||||
bool HitTest( HitContext &hc );
|
||||
|
||||
void Serialize( CObjectArchive &ar );
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected:
|
||||
//! Dtor must be protected.
|
||||
CVolume();
|
||||
|
||||
//! Called when one of size parameters change.
|
||||
void OnSizeChange( IVariable *var );
|
||||
|
||||
void DeleteThis() { delete this; };
|
||||
|
||||
//! Can be either sphere or box.
|
||||
bool m_sphere;
|
||||
|
||||
CVariable<float> mv_width;
|
||||
CVariable<float> mv_length;
|
||||
CVariable<float> mv_height;
|
||||
CVariable<float> mv_viewDistance;
|
||||
CVariable<CString> mv_shader;
|
||||
CVariable<Vec3> mv_fogColor;
|
||||
|
||||
//! Local volume space bounding box.
|
||||
BBox m_box;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of TagPoint.
|
||||
*/
|
||||
class CVolumeClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {3141824B-6455-417b-B9A0-76CF1A672369}
|
||||
static const GUID guid = { 0x3141824b, 0x6455, 0x417b, { 0xb9, 0xa0, 0x76, 0xcf, 0x1a, 0x67, 0x23, 0x69 } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_VOLUME; };
|
||||
const char* ClassName() { return "StdVolume"; };
|
||||
const char* Category() { return ""; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CVolume); };
|
||||
int GameCreationOrder() { return 15; };
|
||||
};
|
||||
|
||||
#endif // __Volume_h__
|
||||
202
Editor/Objects/WaterShapeObject.cpp
Normal file
202
Editor/Objects/WaterShapeObject.cpp
Normal file
@@ -0,0 +1,202 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: watershapeobject.cpp
|
||||
// Version: v1.00
|
||||
// Created: 10/12/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "WaterShapeObject.h"
|
||||
#include "Material\MaterialManager.h"
|
||||
|
||||
#include <I3DEngine.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNCREATE(CWaterShapeObject,CShapeObject)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CWaterShapeObject::CWaterShapeObject()
|
||||
{
|
||||
m_waterVolume = 0;
|
||||
|
||||
ZeroStruct( m_materialGUID );
|
||||
|
||||
mv_waterShader = "WaterVolume";
|
||||
mv_waterStreamSpeed = 0;
|
||||
mv_waterTriMinSize = 8.f;
|
||||
mv_waterTriMaxSize = 8.f;
|
||||
mv_bAffectToVolFog = false;
|
||||
|
||||
AddVariable( mv_waterShader,"WaterShader", "Shader", functor(*this,&CWaterShapeObject::OnWaterChange),IVariable::DT_SHADER );
|
||||
AddVariable( mv_waterStreamSpeed, "WaterSpeed", "Speed", functor(*this,&CWaterShapeObject::OnWaterChange) );
|
||||
AddVariable( mv_waterTriMinSize, "TriMinSize", "TriMinSize", functor(*this,&CWaterShapeObject::OnWaterChange) );
|
||||
AddVariable( mv_waterTriMaxSize, "TriMaxSize", "TriMaxSize", functor(*this,&CWaterShapeObject::OnWaterChange) );
|
||||
AddVariable( mv_bAffectToVolFog, "AffectToVolFog", "AffectToVolFog", functor(*this,&CWaterShapeObject::OnWaterChange) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CWaterShapeObject::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
||||
{
|
||||
bool res = CShapeObject::Init( ie,prev,file );
|
||||
if (prev)
|
||||
{
|
||||
m_materialGUID = ((CWaterShapeObject*)prev)->m_materialGUID;
|
||||
}
|
||||
if (IsCreateGameObjects())
|
||||
{
|
||||
m_waterVolume = GetIEditor()->Get3DEngine()->CreateWaterVolume();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CWaterShapeObject::SetName( const CString &name )
|
||||
{
|
||||
bool bChanged = name != GetName();
|
||||
CShapeObject::SetName( name );
|
||||
if (bChanged)
|
||||
{
|
||||
UpdateGameArea();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CWaterShapeObject::Done()
|
||||
{
|
||||
if (m_waterVolume)
|
||||
{
|
||||
GetIEditor()->Get3DEngine()->DeleteWaterVolume(m_waterVolume);
|
||||
}
|
||||
CShapeObject::Done();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CWaterShapeObject::OnWaterChange( IVariable *var )
|
||||
{
|
||||
if (m_waterVolume)
|
||||
{
|
||||
m_waterVolume->SetFlowSpeed( mv_waterStreamSpeed );
|
||||
m_waterVolume->SetAffectToVolFog(mv_bAffectToVolFog);
|
||||
CString strShader = mv_waterShader;
|
||||
m_waterVolume->SetShader( strShader );
|
||||
m_waterVolume->SetTriSizeLimits( mv_waterTriMinSize, mv_waterTriMaxSize );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CWaterShapeObject::SetMaterial( CMaterial *mtl )
|
||||
{
|
||||
StoreUndo( "Assign Material" );
|
||||
m_pMaterial = mtl;
|
||||
if (m_pMaterial)
|
||||
{
|
||||
m_pMaterial->SetUsed();
|
||||
m_materialGUID = m_pMaterial->GetGUID();
|
||||
}
|
||||
else
|
||||
{
|
||||
ZeroStruct(m_materialGUID);
|
||||
}
|
||||
m_bAreaModified = true;
|
||||
UpdateGameArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CWaterShapeObject::Serialize( CObjectArchive &ar )
|
||||
{
|
||||
CShapeObject::Serialize( ar );
|
||||
if (ar.bLoading)
|
||||
{
|
||||
// Loading.
|
||||
ZeroStruct(m_materialGUID);
|
||||
if (ar.node->getAttr( "MaterialGUID",m_materialGUID ))
|
||||
{
|
||||
m_pMaterial = (CMaterial*)GetIEditor()->GetMaterialManager()->FindItem( m_materialGUID );
|
||||
if (!m_pMaterial)
|
||||
{
|
||||
CErrorRecord err;
|
||||
err.error.Format( _T("Material %s for WaterVolume %s not found."),GuidUtil::ToString(m_materialGUID),(const char*)GetName() );
|
||||
err.severity = CErrorRecord::ESEVERITY_WARNING;
|
||||
err.pObject = this;
|
||||
ar.ReportError(err);
|
||||
|
||||
//Warning( "Material %s for WaterVolume %s not found,",GuidUtil::ToString(m_materialGUID),(const char*)GetName() );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_pMaterial->GetParent())
|
||||
SetMaterial( m_pMaterial->GetParent() );
|
||||
m_pMaterial->SetUsed();
|
||||
}
|
||||
}
|
||||
else
|
||||
m_pMaterial = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Saving.
|
||||
if (!GuidUtil::IsEmpty(m_materialGUID))
|
||||
{
|
||||
ar.node->setAttr( "MaterialGUID",m_materialGUID );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
XmlNodeRef CWaterShapeObject::Export( const CString &levelPath,XmlNodeRef &xmlNode )
|
||||
{
|
||||
XmlNodeRef objNode = CShapeObject::Export( levelPath,xmlNode );
|
||||
if (objNode)
|
||||
{
|
||||
if (m_pMaterial)
|
||||
{
|
||||
objNode->setAttr( "Material",m_pMaterial->GetFullName() );
|
||||
}
|
||||
}
|
||||
return objNode;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CWaterShapeObject::UpdateGameArea( bool bRemove )
|
||||
{
|
||||
if (bRemove)
|
||||
return;
|
||||
|
||||
if (m_bIgnoreGameUpdate)
|
||||
return;
|
||||
|
||||
if (m_waterVolume)
|
||||
{
|
||||
std::vector<Vec3> points;
|
||||
if (GetPointCount() > 3)
|
||||
{
|
||||
const Matrix44 &wtm = GetWorldTM();
|
||||
points.resize(GetPointCount());
|
||||
for (int i = 0; i < GetPointCount(); i++)
|
||||
{
|
||||
points[i] = wtm.TransformPointOLD( GetPoint(i) );
|
||||
}
|
||||
m_waterVolume->UpdatePoints( &points[0],points.size(), mv_height );
|
||||
|
||||
CString strShader = mv_waterShader;
|
||||
m_waterVolume->SetName( GetName() );
|
||||
m_waterVolume->SetFlowSpeed( mv_waterStreamSpeed );
|
||||
m_waterVolume->SetAffectToVolFog(mv_bAffectToVolFog);
|
||||
m_waterVolume->SetTriSizeLimits( mv_waterTriMinSize, mv_waterTriMaxSize );
|
||||
m_waterVolume->SetShader( strShader );
|
||||
if (m_pMaterial)
|
||||
m_waterVolume->SetMaterial( m_pMaterial->GetMatInfo() );
|
||||
else
|
||||
m_waterVolume->SetMaterial( 0 );
|
||||
}
|
||||
}
|
||||
m_bAreaModified = false;
|
||||
}
|
||||
86
Editor/Objects/WaterShapeObject.h
Normal file
86
Editor/Objects/WaterShapeObject.h
Normal file
@@ -0,0 +1,86 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: watershapeobject.h
|
||||
// Version: v1.00
|
||||
// Created: 10/12/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __watershapeobject_h__
|
||||
#define __watershapeobject_h__
|
||||
#pragma once
|
||||
|
||||
#include "ShapeObject.h"
|
||||
#include "Material\Material.h"
|
||||
|
||||
class CWaterShapeObject : public CShapeObject
|
||||
{
|
||||
DECLARE_DYNCREATE(CWaterShapeObject)
|
||||
public:
|
||||
CWaterShapeObject();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ovverides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
|
||||
void Done();
|
||||
|
||||
virtual void SetName( const CString &name );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Override materials.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetMaterial( CMaterial *mtl );
|
||||
virtual CMaterial* GetMaterial() const { return m_pMaterial; };
|
||||
|
||||
//void Display( DisplayContext &dc );
|
||||
void Serialize( CObjectArchive &ar );
|
||||
XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected:
|
||||
void OnWaterChange( IVariable *var );
|
||||
virtual void UpdateGameArea( bool bRemove=false );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Water shape parameters.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CVariable<CString> mv_waterShader;
|
||||
CVariable<float> mv_waterStreamSpeed;
|
||||
CVariable<float> mv_waterTriMinSize;
|
||||
CVariable<float> mv_waterTriMaxSize;
|
||||
CVariable<bool> mv_bAffectToVolFog;
|
||||
|
||||
//! Material of this object.
|
||||
TSmartPtr<CMaterial> m_pMaterial;
|
||||
GUID m_materialGUID;
|
||||
|
||||
struct IWaterVolume* m_waterVolume;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Class Description of ShapeObject.
|
||||
*/
|
||||
class CWaterShapeObjectClassDesc : public CObjectClassDesc
|
||||
{
|
||||
public:
|
||||
REFGUID ClassID()
|
||||
{
|
||||
// {3CC1CF42-917A-4c4d-80D2-2A81E6A32BDB}
|
||||
static const GUID guid = { 0x3cc1cf42, 0x917a, 0x4c4d, { 0x80, 0xd2, 0x2a, 0x81, 0xe6, 0xa3, 0x2b, 0xdb } };
|
||||
return guid;
|
||||
}
|
||||
ObjectType GetObjectType() { return OBJTYPE_VOLUME; };
|
||||
const char* ClassName() { return "WaterVolume"; };
|
||||
const char* Category() { return "Area"; };
|
||||
CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CWaterShapeObject); };
|
||||
int GameCreationOrder() { return 16; };
|
||||
};
|
||||
|
||||
#endif // __watershapeobject_h__
|
||||
Reference in New Issue
Block a user