This commit is contained in:
romkazvo
2023-08-07 19:29:24 +08:00
commit 34d6c5d489
4832 changed files with 1389451 additions and 0 deletions

282
Editor/Objects/AIAnchor.cpp Normal file
View 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
View 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
View 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
View 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
View 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
View 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__

View 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
View 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__

View 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;
}

View 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

File diff suppressed because it is too large Load Diff

606
Editor/Objects/BaseObject.h Normal file
View 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__

File diff suppressed because it is too large Load Diff

View 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
View 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
View 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__

View 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 );
}

View 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__

View 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__

View 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 &center,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
};

View 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 &center,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

File diff suppressed because it is too large Load Diff

382
Editor/Objects/Entity.h Normal file
View 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__

View 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;
}

View 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
View 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
View 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__

View 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;
};

View 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
View 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
View 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__

View 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;
*/
}

View 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__

View 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;
}

View 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__

View 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 );
}

View 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__

View 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;
}

View 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__

File diff suppressed because it is too large Load Diff

View 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__

View 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;
}

View 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__

View 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();
}

View 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__

View 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);
}
}

View 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__

View 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 );
}
}

View 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__

File diff suppressed because it is too large Load Diff

View 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__

View 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;
}

View 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
View 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( &params );
}
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( &params );
}
}
}
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
View 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__

View 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;
}

View 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
View 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
View 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__

View 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;
}

View 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__

View 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;
}

View 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
View 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
View 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__

View 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;
}

View 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__