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

1408
Editor/2DViewport.cpp Normal file

File diff suppressed because it is too large Load Diff

176
Editor/2DViewport.h Normal file
View File

@@ -0,0 +1,176 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: 2dviewport.h
// Version: v1.00
// Created: 5/7/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __2dviewport_h__
#define __2dviewport_h__
#if _MSC_VER > 1000
#pragma once
#endif
#include "Viewport.h"
/** 2D Viewport used mostly for indoor editing, Front/Top/Left viewports.
*/
class C2DViewport : public CViewport
{
DECLARE_DYNCREATE(C2DViewport)
public:
C2DViewport();
virtual ~C2DViewport();
virtual void SetType( EViewportType type );
virtual EViewportType GetType() { return m_viewType; }
virtual void ResetContent();
virtual void UpdateContent( int flags );
// Called every frame to update viewport.
virtual void Update();
//! Map world space position to viewport position.
virtual CPoint WorldToView( Vec3d wp );
//! Map viewport position to world space position.
virtual Vec3d ViewToWorld( CPoint vp,bool *collideWithTerrain=0,bool onlyTerrain=false );
//! Map viewport position to world space ray from camera.
virtual void ViewToWorldRay( CPoint vp,Vec3 &raySrc,Vec3 &rayDir );
virtual void OnTitleMenu( CMenu &menu );
virtual void OnTitleMenuCommand( int id );
virtual void DrawBrush( DisplayContext &dc,struct SBrush *brush,const Matrix44 &brushTM,int flags );
virtual void DrawTextLabel( DisplayContext &dc,const Vec3& pos,float size,const CFColor& color,const char *text );
virtual bool HitTest( CPoint point,ObjectHitInfo &hitInfo,int flags=0 );
virtual bool IsBoundsVisible( const BBox &box ) const;
Vec3d SnapToGrid( Vec3d vec );
// ovverided from CViewport.
float GetScreenScaleFactor( const Vec3 &worldPoint );
// Overrided from CViewport.
void OnDragSelectRectangle( CPoint p1,CPoint p2,bool bNormilizeRect=false );
void CenterOnSelection();
Vec3 GetCPVector( const Vec3 &p1,const Vec3 &p2 );
/** Get 2D viewports origin.
*/
Vec3 GetOrigin2D() const;
/** Assign 2D viewports origin.
*/
void SetOrigin2D( const Vec3 &org );
protected:
enum EViewportAxis
{
VPA_XY,
VPA_XZ,
VPA_YZ,
};
void SetAxis( EViewportAxis axis );
// Scrolling / zooming related
virtual void SetScrollOffset( float x,float y,bool bLimits=true );
virtual void GetScrollOffset( float &x,float &y ); // Only x and y components used.
void SetZoom( float fZoomFactor,CPoint center );
// overrides from CViewport.
void SetConstrPlane( CPoint cursor,const Matrix44 &xform );
//! Calculate view transformation matrix.
virtual void CalculateViewTM();
// Render
void Render();
// Draw everything.
virtual void Draw( DisplayContext &dc );
// Draw elements of viewport.
void DrawGrid( DisplayContext &dc,bool bNoXNumbers=false );
void DrawAxis( DisplayContext &dc );
void DrawSelection( DisplayContext &dc );
void DrawObjects( DisplayContext &dc );
void DrawViewerMarker( DisplayContext &dc );
BBox GetWorldBounds( CPoint p1,CPoint p2 );
//////////////////////////////////////////////////////////////////////////
//! Get current screen matrix.
//! Screen matrix transform from World space to Screen space.
const Matrix44& GetScreenTM() const { return m_screenTM; };
//{{AFX_MSG(C2DViewport)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMButtonUp(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnPaint();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
afx_msg void OnDestroy();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
protected:
//////////////////////////////////////////////////////////////////////////
// Variables.
//////////////////////////////////////////////////////////////////////////
IRenderer* m_renderer;
//! XY/XZ/YZ mode of this 2D viewport.
EViewportType m_viewType;
EViewportAxis m_axis;
//! Axis to cull normals with in this Viewport.
int m_cullAxis;
// Viewport origin point.
Vec3 m_origin2D;
// Scrolling / zooming related
CPoint m_cMousePos;
CPoint m_RMouseDownPos;
float m_prevZoomFactor;
CSize m_prevScrollOffset;
CRect m_rcSelect;
CRect m_rcClient;
BBox m_displayBounds;
//! True if should display terrain.
bool m_bShowTerrain;
Matrix44 m_screenTM;
float m_gridAlpha;
COLORREF m_colorGridText;
COLORREF m_colorAxisText;
COLORREF m_colorBackground;
};
#endif // __2dviewport_h__

130
Editor/AI/AIManager.cpp Normal file
View File

@@ -0,0 +1,130 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: aimanager.cpp
// Version: v1.00
// Created: 11/9/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "AIManager.h"
#include "AIGoalLibrary.h"
#include "AiGoal.h"
#include "AiBehaviorLibrary.h"
#include "IAISystem.h"
#include <IScriptSystem.h>
//////////////////////////////////////////////////////////////////////////
// CAI Manager.
//////////////////////////////////////////////////////////////////////////
CAIManager::CAIManager()
{
m_goalLibrary = new CAIGoalLibrary;
m_behaviorLibrary = new CAIBehaviorLibrary;
}
CAIManager::~CAIManager()
{
delete m_behaviorLibrary;
m_behaviorLibrary = 0;
delete m_goalLibrary;
m_goalLibrary = 0;
}
void CAIManager::Init( ISystem *system )
{
m_aiSystem = system->GetAISystem();
if (!m_aiSystem)
return;
//m_goalLibrary->InitAtomicGoals();
m_behaviorLibrary->LoadBehaviors( "Scripts\\AI\\Behaviors\\" );
//enumerate Anchor actions.
EnumAnchorActions();
}
IAISystem* CAIManager::GetAISystem()
{
return GetIEditor()->GetSystem()->GetAISystem();
}
//////////////////////////////////////////////////////////////////////////
void CAIManager::ReloadScripts()
{
GetBehaviorLibrary()->ReloadScripts();
EnumAnchorActions();
}
//////////////////////////////////////////////////////////////////////////
void CAIManager::GetAnchorActions( std::vector<CString> &actions ) const
{
actions.clear();
for (AnchorActions::const_iterator it = m_anchorActions.begin(); it != m_anchorActions.end(); it++)
{
actions.push_back( it->first );
}
}
//////////////////////////////////////////////////////////////////////////
int CAIManager::AnchorActionToId( const char *sAction ) const
{
AnchorActions::const_iterator it = m_anchorActions.find(sAction);
if (it != m_anchorActions.end())
return it->second;
return -1;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
struct CAIAnchorDump : public IScriptObjectDumpSink
{
CAIManager::AnchorActions actions;
CAIAnchorDump( IScriptObject *obj )
{
m_pScriptObject = obj;
}
virtual void OnElementFound(int nIdx,ScriptVarType type) {}
virtual void OnElementFound(const char *sName,ScriptVarType type)
{
if (type == svtNumber)
{
// New behavior.
int val;
if (m_pScriptObject->GetValue(sName,val))
{
actions[sName] = val;
}
}
}
private:
IScriptObject *m_pScriptObject;
};
//////////////////////////////////////////////////////////////////////////
void CAIManager::EnumAnchorActions()
{
IScriptSystem *pScriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
_SmartScriptObject pAIAnchorTable( pScriptSystem,true );
if (pScriptSystem->GetGlobalValue( "AIAnchor",pAIAnchorTable ))
{
CAIAnchorDump anchorDump(pAIAnchorTable);
pAIAnchorTable->Dump( &anchorDump );
m_anchorActions = anchorDump.actions;
}
}

63
Editor/AI/AIManager.h Normal file
View File

@@ -0,0 +1,63 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: aimanager.h
// Version: v1.00
// Created: 11/9/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __aimanager_h__
#define __aimanager_h__
#if _MSC_VER > 1000
#pragma once
#endif
// forward declarations.
class CAIGoalLibrary;
class CAIBehaviorLibrary;
//////////////////////////////////////////////////////////////////////////
class CAIManager
{
public:
CAIManager();
~CAIManager();
void Init( ISystem *system );
IAISystem* GetAISystem();
CAIGoalLibrary* GetGoalLibrary() { return m_goalLibrary; };
CAIBehaviorLibrary* GetBehaviorLibrary() { return m_behaviorLibrary; };
//////////////////////////////////////////////////////////////////////////
//! AI Anchor Actions enumeration.
void GetAnchorActions( std::vector<CString> &actions ) const;
int AnchorActionToId( const char *sAction ) const;
// Enumerate all AI characters.
//////////////////////////////////////////////////////////////////////////
void ReloadScripts();
private:
void EnumAnchorActions();
CAIGoalLibrary* m_goalLibrary;
CAIBehaviorLibrary* m_behaviorLibrary;
IAISystem* m_aiSystem;
//! AI Anchor Actions.
friend struct CAIAnchorDump;
typedef std::map<CString,int> AnchorActions;
AnchorActions m_anchorActions;
};
#endif // __aimanager_h__

64
Editor/AI/AiBehavior.cpp Normal file
View File

@@ -0,0 +1,64 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
// File name: aibehavior.cpp
// Version: v1.00
// Created: 9/4/2002 by Timur.
// Compilers: Visual C++ 7.0
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "aibehavior.h"
#include "..\Util\FileUtil.h"
#include "IScriptSystem.h"
#include "..\Objects\ObjectManager.h"
//////////////////////////////////////////////////////////////////////////
void CAIBehavior::ReloadScript()
{
// Execute script file in script system.
if (m_script.IsEmpty())
return;
if (CFileUtil::CompileLuaFile( GetScript() ))
{
IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
// Script compiled succesfully.
scriptSystem->ReloadScript( m_script );
}
}
//////////////////////////////////////////////////////////////////////////
void CAIBehavior::Edit()
{
CFileUtil::EditTextFile( GetScript() );
}
//////////////////////////////////////////////////////////////////////////
void CAICharacter::ReloadScript()
{
// Execute script file in script system.
if (m_script.IsEmpty())
return;
if (CFileUtil::CompileLuaFile( GetScript() ))
{
IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
// Script compiled succesfully.
scriptSystem->ReloadScript( m_script );
}
}
//////////////////////////////////////////////////////////////////////////
void CAICharacter::Edit()
{
CFileUtil::EditTextFile( GetScript() );
}

90
Editor/AI/AiBehavior.h Normal file
View File

@@ -0,0 +1,90 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
// File name: aibehavior.h
// Version: v1.00
// Created: 21/3/2002 by Timur.
// Compilers: Visual C++ 7.0
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __aibehavior_h__
#define __aibehavior_h__
#if _MSC_VER > 1000
#pragma once
#endif
/** AI Behavior definition.
*/
class CAIBehavior : public CRefCountBase
{
public:
CAIBehavior() {};
virtual ~CAIBehavior() {};
void SetName( const CString& name ) { m_name = name; }
const CString& GetName() { return m_name; }
//! Set name of script that implements this behavior.
void SetScript( const CString &script ) { m_script = script; };
const CString& GetScript() const { return m_script; };
//! Get human readable description of this goal.
const CString& GetDescription() { return m_description; }
//! Set human readable description of this goal.
void SetDescription( const CString& desc ) { m_description = desc; }
//! Force reload of script file.
void ReloadScript();
//! Start editing script file in Text editor.
void Edit();
private:
CString m_name;
CString m_description;
CString m_script;
};
/** AICharacter behaviour definition.
*/
class CAICharacter : public CRefCountBase
{
public:
CAICharacter() {};
virtual ~CAICharacter() {};
void SetName( const CString& name ) { m_name = name; }
const CString& GetName() { return m_name; }
//! Set name of script that implements this behavior.
void SetScript( const CString &script ) { m_script = script; };
const CString& GetScript() const { return m_script; };
//! Get human readable description of this goal.
const CString& GetDescription() { return m_description; }
//! Set human readable description of this goal.
void SetDescription( const CString& desc ) { m_description = desc; }
//! Force reload of script file.
void ReloadScript();
//! Start editing script file in Text editor.
void Edit();
private:
CString m_name;
CString m_description;
CString m_script;
};
typedef TSmartPtr<CAIBehavior> CAIBehaviorPtr;
typedef TSmartPtr<CAICharacter> CAICharacterPtr;
#endif // __aibehavior_h__

View File

@@ -0,0 +1,278 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
// File name: AiBehaviorLibrary.h
// Version: v1.00
// Created: 21/3/2002 by Timur.
// Compilers: Visual C++ 7.0
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "AiBehaviorLibrary.h"
#include "AiBehavior.h"
#include "IScriptSystem.h"
#define AI_CONFIG_FILE "Scripts\\AI\\aiconfig.lua"
//////////////////////////////////////////////////////////////////////////
struct CAIBehaviorsDump : public IScriptObjectDumpSink
{
CAIBehaviorsDump( CAIBehaviorLibrary* lib,IScriptObject *obj )
{
m_pLibrary = lib;
m_pScriptObject = obj;
}
virtual void OnElementFound(int nIdx,ScriptVarType type) {}
virtual void OnElementFound(const char *sName,ScriptVarType type)
{
if (type == svtString)
{
// New behavior.
const char *scriptFile;
if (m_pScriptObject->GetValue(sName,scriptFile))
{
CAIBehavior *behavior = new CAIBehavior;
behavior->SetName(sName);
CString file = scriptFile;
file.Replace( '/','\\' );
behavior->SetScript(file);
behavior->SetDescription( "" );
m_pLibrary->AddBehavior( behavior );
}
}
}
private:
CAIBehaviorLibrary *m_pLibrary;
IScriptObject *m_pScriptObject;
};
//////////////////////////////////////////////////////////////////////////
struct CAICharactersDump : public IScriptObjectDumpSink
{
CAICharactersDump( CAIBehaviorLibrary* lib,IScriptObject *obj )
{
m_pLibrary = lib;
m_pScriptObject = obj;
}
virtual void OnElementFound(int nIdx,ScriptVarType type) {}
virtual void OnElementFound(const char *sName,ScriptVarType type)
{
if (type == svtString)
{
// New behavior.
const char *scriptFile;
if (m_pScriptObject->GetValue(sName,scriptFile))
{
CAICharacter* c = new CAICharacter;
c->SetName(sName);
CString file = scriptFile;
file.Replace( '/','\\' );
c->SetScript(file);
c->SetDescription( "" );
m_pLibrary->AddCharacter( c );
}
}
}
private:
CAIBehaviorLibrary *m_pLibrary;
IScriptObject *m_pScriptObject;
};
//////////////////////////////////////////////////////////////////////////
// CAIBehaviorLibrary implementation.
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
CAIBehaviorLibrary::CAIBehaviorLibrary()
{
}
//////////////////////////////////////////////////////////////////////////
void CAIBehaviorLibrary::AddBehavior( CAIBehavior* behavior )
{
CAIBehaviorPtr g;
if (m_behaviors.Find(behavior->GetName(),g))
{
// Behavior with this name already exist in the library.
}
m_behaviors[behavior->GetName()] = behavior;
}
//////////////////////////////////////////////////////////////////////////
void CAIBehaviorLibrary::RemoveBehavior( CAIBehavior* behavior )
{
m_behaviors.Erase( behavior->GetName() );
}
//////////////////////////////////////////////////////////////////////////
CAIBehavior* CAIBehaviorLibrary::FindBehavior( const CString &name ) const
{
CAIBehaviorPtr behavior=0;
m_behaviors.Find( name,behavior );
return behavior;
}
//////////////////////////////////////////////////////////////////////////
void CAIBehaviorLibrary::ClearBehaviors()
{
m_behaviors.Clear();
}
//////////////////////////////////////////////////////////////////////////
void CAIBehaviorLibrary::LoadBehaviors( const CString &path )
{
m_scriptsPath = path;
ClearBehaviors();
IScriptSystem *pScriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
_SmartScriptObject pAIBehaviorTable( pScriptSystem,true );
if (pScriptSystem->GetGlobalValue( "AIBehaviour",pAIBehaviorTable ))
{
_SmartScriptObject pAvailableTable( pScriptSystem,true );
if (pAIBehaviorTable->GetValue( "AVAILABLE",pAvailableTable ))
{
// Enumerate all behaviours.
CAIBehaviorsDump bdump( this,pAvailableTable );
pAvailableTable->Dump( &bdump );
}
}
/*
int i;
XmlParser xmlParser;
// Scan all behavior files.
std::vector<CString> files;
CFileEnum::ScanDirectory( path,"*.ai",files,true );
for (i = 0; i < files.size(); i++)
{
// Load behavior scripts.
CString file = path + files[i];
XmlNodeRef behaviorsNode = xmlParser.parse(file);
if (!behaviorsNode)
continue;
for (int j = 0; j < behaviorsNode->getChildCount(); j++)
{
XmlNodeRef bhNode = behaviorsNode->getChild(j);
CString name,script,desc;
bhNode->getAttr( "Name",name );
bhNode->getAttr( "Script",script );
bhNode->getAttr( "Description",desc );
char fdir[_MAX_PATH];
_splitpath(files[i],0,fdir,0,0 );
CString scriptFile = path + fdir + script;
// New behavior.
CAIBehavior *behavior = new CAIBehavior;
behavior->SetName(name);
behavior->SetScript(scriptFile);
behavior->SetDescription( desc );
AddBehavior( behavior );
}
}
*/
}
//////////////////////////////////////////////////////////////////////////
void CAIBehaviorLibrary::GetBehaviors( std::vector<CAIBehaviorPtr> &behaviors )
{
// Load behaviours again.
LoadBehaviors( m_scriptsPath );
m_behaviors.GetAsVector(behaviors);
}
//////////////////////////////////////////////////////////////////////////
void CAIBehaviorLibrary::ReloadScripts()
{
LoadBehaviors( m_scriptsPath );
int i;
// Generate uniq set of script files used by behaviors.
std::set<CString> scriptFiles;
std::vector<CAIBehaviorPtr> behaviors;
GetBehaviors( behaviors );
for (i = 0; i < behaviors.size(); i++)
{
scriptFiles.insert( behaviors[i]->GetScript() );
}
IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
// Load script files to script system.
for (std::set<CString>::iterator it = scriptFiles.begin(); it != scriptFiles.end(); it++)
{
CString file = *it;
CLogFile::FormatLine( "Loading AI Behavior Script: %s",(const char*)file );
scriptSystem->ExecuteFile( file );
}
// Reload main AI script.
// IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
scriptSystem->ExecuteFile( AI_CONFIG_FILE,true,true );
}
//////////////////////////////////////////////////////////////////////////
void CAIBehaviorLibrary::LoadCharacters()
{
m_characters.Clear();
IScriptSystem *pScriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
_SmartScriptObject pAIBehaviorTable( pScriptSystem,true );
if (pScriptSystem->GetGlobalValue( "AICharacter",pAIBehaviorTable ))
{
_SmartScriptObject pAvailableTable( pScriptSystem,true );
if (pAIBehaviorTable->GetValue( "AVAILABLE",pAvailableTable ))
{
// Enumerate all characters.
CAICharactersDump bdump( this,pAvailableTable );
pAvailableTable->Dump( &bdump );
}
}
}
//////////////////////////////////////////////////////////////////////////
void CAIBehaviorLibrary::GetCharacters( std::vector<CAICharacterPtr> &characters )
{
LoadCharacters();
m_characters.GetAsVector(characters);
}
//////////////////////////////////////////////////////////////////////////
CAICharacter* CAIBehaviorLibrary::FindCharacter( const CString &name ) const
{
CAICharacterPtr chr=0;
m_characters.Find( name,chr );
return chr;
}
//////////////////////////////////////////////////////////////////////////
void CAIBehaviorLibrary::AddCharacter( CAICharacter* chr )
{
CAICharacterPtr g;
if (m_characters.Find(chr->GetName(),g))
{
// Behavior with this name already exist in the library.
}
m_characters[chr->GetName()] = chr;
}
//////////////////////////////////////////////////////////////////////////
void CAIBehaviorLibrary::RemoveCharacter( CAICharacter* chr )
{
m_characters.Erase( chr->GetName() );
}

View File

@@ -0,0 +1,72 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
// File name: aiBehaviorLibrary.h
// Version: v1.00
// Created: 21/3/2002 by Timur.
// Compilers: Visual C++ 7.0
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __aibehaviorlibrary_h__
#define __aibehaviorlibrary_h__
#if _MSC_VER > 1000
#pragma once
#endif
#include "AiBehavior.h"
/*!
* CAIBehaviorLibrary is collection of global AI behaviors.
*/
class CAIBehaviorLibrary
{
public:
CAIBehaviorLibrary();
~CAIBehaviorLibrary() {};
//! Add new behavior to the library.
void AddBehavior( CAIBehavior* behavior );
//! Remove behavior from the library.
void RemoveBehavior( CAIBehavior* behavior );
CAIBehavior* FindBehavior( const CString &name ) const;
//! Clear all behaviors from library.
void ClearBehaviors();
//! Get all stored behaviors as a vector.
void GetBehaviors( std::vector<CAIBehaviorPtr> &behaviors );
//! Load all behaviors from givven path and add them to library.
void LoadBehaviors( const CString &path );
//! Reload behavior scripts.
void ReloadScripts();
//! Get all available characters in system.
void GetCharacters( std::vector<CAICharacterPtr> &characters );
//! Add new behavior to the library.
void AddCharacter( CAICharacter* chr );
//! Remove behavior from the library.
void RemoveCharacter( CAICharacter* chr );
// Finds specified character.
CAICharacter* FindCharacter( const CString &name ) const;
private:
void LoadCharacters();
StdMap<CString,TSmartPtr<CAIBehavior> > m_behaviors;
StdMap<CString,TSmartPtr<CAICharacter> > m_characters;
CString m_scriptsPath;
};
#endif // __aibehaviorlibrary_h__

71
Editor/AI/AiGoal.cpp Normal file
View File

@@ -0,0 +1,71 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
// File name: aigoal.h
// Version: v1.00
// Created: 21/3/2002 by Timur.
// Compilers: Visual C++ 7.0
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "AiGoal.h"
//////////////////////////////////////////////////////////////////////////
// CAIgoal implementation.
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
CAIGoal::CAIGoal()
{
m_atomic = false;
m_modified = false;
}
//////////////////////////////////////////////////////////////////////////
CAIGoal::~CAIGoal()
{
m_atomic = false;
}
//////////////////////////////////////////////////////////////////////////
void CAIGoal::Serialize( XmlNodeRef &node,bool bLoading )
{
if (bLoading)
{
m_stages.clear();
// Loading.
node->getAttr( "Name",m_name );
m_stages.resize( node->getChildCount() );
for (int i = 0; i < node->getChildCount(); i++)
{
// Write goals stages to xml.
CAIGoalStage &stage = m_stages[i];
XmlNodeRef stageNode = node->getChild(i);
stageNode->getAttr( "Blocking",stage.blocking );
stage.params->copyAttributes( stageNode );
stage.params->delAttr( "Blocking" );
}
}
else
{
// Saving.
node->setAttr( "Name",m_name );
for (int i = 0; i < m_stages.size(); i++)
{
// Write goals stages to xml.
CAIGoalStage &stage = m_stages[i];
XmlNodeRef stageNode = node->newChild( stage.name );
stageNode->copyAttributes( stage.params );
stageNode->setAttr( "Blocking",stage.blocking );
}
}
}

95
Editor/AI/AiGoal.h Normal file
View File

@@ -0,0 +1,95 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
// File name: aigoal.h
// Version: v1.00
// Created: 21/3/2002 by Timur.
// Compilers: Visual C++ 7.0
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __aigoal_h__
#define __aigoal_h__
#if _MSC_VER > 1000
#pragma once
#endif
/*
* CAIGoalStage is single stage of AI goal.
*/
class CAIGoalStage
{
public:
//! Name of goal used by this stage.
CString name;
//! True if this stage will block goal pipeline execution.
bool blocking;
//! Goal parameters.
XmlNodeRef params;
};
/*!
* CAIGoal contain definition of AI goal pipe.
*/
class CAIGoal : public CRefCountBase
{
public:
CAIGoal();
~CAIGoal();
const CString& GetName() { return m_name; }
void SetName( const CString& name ) { m_name = name; }
//! Get human readable description of this goal.
const CString& GetDescription() { return m_description; }
//! Set human readable description of this goal.
void SetDescription( const CString& desc ) { m_description = desc; }
//////////////////////////////////////////////////////////////////////////
//! Return true if this goal is Atomic goal, (atomic goals defined by system)
bool IsAtomic() const { return m_atomic; };
//! Set this goal as atomic.
void SetAtomic( bool atomic ) { m_atomic = atomic; };
//! Return true if goal was modified by user and should be stored in goal database.
bool IsModified() const { return m_modified; };
// Mark this goal as modified.
void SetModified( bool modified ) { m_modified = modified; }
//! Get number of stages in goal.
int GetStageCount() const { return m_stages.size(); };
//! Get goal stage at specified index.
CAIGoalStage& GetStage( int index ) { return m_stages[index]; }
const CAIGoalStage& GetStage( int index ) const { return m_stages[index]; }
void AddStage( const CAIGoalStage &stage ) { m_stages.push_back(stage); }
//! Template for parameters used in goal.
XmlNodeRef& GetParamsTemplate() { return m_paramsTemplate; };
//! Serialize Goal to/from xml.
void Serialize( XmlNodeRef &node,bool bLoading );
private:
CString m_name;
CString m_description;
std::vector<CAIGoalStage> m_stages;
XmlNodeRef m_attributes;
//! True if its atomic goal.
bool m_atomic;
bool m_modified;
//! Parameters template for this goal.
XmlNodeRef m_paramsTemplate;
};
// Define smart pointer to AIGoal
typedef TSmartPtr<CAIGoal> CAIGoalPtr;
#endif // __aigoal_h__

134
Editor/AI/AiGoalLibrary.cpp Normal file
View File

@@ -0,0 +1,134 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
// File name: aigoal.h
// Version: v1.00
// Created: 21/3/2002 by Timur.
// Compilers: Visual C++ 7.0
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "AiGoalLibrary.h"
#include "AiGoal.h"
#include "AiBehaviorLibrary.h"
#include "IAISystem.h"
#include "AIManager.h"
//////////////////////////////////////////////////////////////////////////
// CAIGoalLibrary implementation.
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
CAIGoalLibrary::CAIGoalLibrary()
{
}
//////////////////////////////////////////////////////////////////////////
void CAIGoalLibrary::InitAtomicGoals()
{
// Create Atomic goals.
IAISystem *ai = GetIEditor()->GetAI()->GetAISystem();
char xmlBuf[32768];
strcpy( xmlBuf,"" );
int num = 0;//ai->EnumAtomicGoals( xmlBuf,sizeof(xmlBuf) );
XmlParser parser;
XmlNodeRef node = parser.parseBuffer( xmlBuf );
//FILE *file = fopen( "c:\\test.xml","wt" );
//fprintf( file,"%s",xmlBuf );
//fclose(file);
if (!node)
return;
for (int i = 0; i < node->getChildCount(); i++)
{
// Create new atomic goal.
XmlNodeRef goalNode = node->getChild(i);
CString goalName = goalNode->getTag();
CString goalDesc;
goalNode->getAttr( "Description",goalDesc );
CAIGoalPtr goal = new CAIGoal;
goal->SetName( goalName );
goal->SetDescription( goalDesc );
goal->SetAtomic(true);
XmlNodeRef params = new CXmlNode("Params");
for (int j = 0; j < goalNode->getChildCount(); j++)
{
params->addChild(goalNode->getChild(j));
}
goal->GetParamsTemplate() = params;
AddGoal( goal );
}
CAIGoalPtr goal = new CAIGoal;
goal->SetName( "Attack" );
goal->SetDescription( "Attacks enemy" );
CAIGoalStage stage;
stage.name = "locate";
stage.blocking = true;
goal->AddStage( stage );
stage.name = "approach";
stage.blocking = true;
goal->AddStage( stage );
stage.name = "pathfind";
stage.blocking = true;
goal->AddStage( stage );
//goal->AddStage(
AddGoal( goal );
}
//////////////////////////////////////////////////////////////////////////
void CAIGoalLibrary::AddGoal( CAIGoal* goal )
{
CAIGoalPtr g;
if (m_goals.Find(goal->GetName(),g))
{
// Goal with this name already exist in the library.
}
m_goals[goal->GetName()] = goal;
}
//////////////////////////////////////////////////////////////////////////
void CAIGoalLibrary::RemoveGoal( CAIGoal* goal )
{
m_goals.Erase( goal->GetName() );
}
//////////////////////////////////////////////////////////////////////////
CAIGoal* CAIGoalLibrary::FindGoal( const CString &name ) const
{
CAIGoalPtr goal=0;
m_goals.Find( name,goal );
return goal;
}
//////////////////////////////////////////////////////////////////////////
void CAIGoalLibrary::ClearGoals()
{
m_goals.Clear();
}
//////////////////////////////////////////////////////////////////////////
void CAIGoalLibrary::LoadGoals( const CString &path )
{
// Scan all goal files.
}
//////////////////////////////////////////////////////////////////////////
void CAIGoalLibrary::GetGoals( std::vector<CAIGoalPtr> &goals ) const
{
m_goals.GetAsVector(goals);
}

58
Editor/AI/AiGoalLibrary.h Normal file
View File

@@ -0,0 +1,58 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
// File name: aigoallibrary.h
// Version: v1.00
// Created: 21/3/2002 by Timur.
// Compilers: Visual C++ 7.0
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __aigoallibrary_h__
#define __aigoallibrary_h__
#if _MSC_VER > 1000
#pragma once
#endif
#include "AiGoal.h"
class CAIBehaviorLibrary;
/*!
* CAIGoalLibrary is collection of global AI goals.
*/
class CAIGoalLibrary
{
public:
CAIGoalLibrary();
~CAIGoalLibrary() {};
//! Add new goal to the library.
void AddGoal( CAIGoal* goal );
//! Remove goal from the library.
void RemoveGoal( CAIGoal* goal );
CAIGoal* FindGoal( const CString &name ) const;
//! Clear all goals from library.
void ClearGoals();
//! Get all stored goals as a vector.
void GetGoals( std::vector<CAIGoalPtr> &goals ) const;
//! Load all goals from givven path and add them to library.
void LoadGoals( const CString &path );
//! Initialize atomic goals from AI system.
void InitAtomicGoals();
private:
StdMap<CString,CAIGoalPtr> m_goals;
};
#endif // __aigoallibrary_h__

View File

@@ -0,0 +1,65 @@
// AIAnchorsDialog.cpp : implementation file
//
#include "stdafx.h"
#include "AIAnchorsDialog.h"
#include "AI\AIManager.h"
// CAIAnchorsDialog dialog
IMPLEMENT_DYNAMIC(CAIAnchorsDialog, CDialog)
CAIAnchorsDialog::CAIAnchorsDialog(CWnd* pParent /*=NULL*/)
: CDialog(CAIAnchorsDialog::IDD, pParent)
{
m_sAnchor="";
}
CAIAnchorsDialog::~CAIAnchorsDialog()
{
}
void CAIAnchorsDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_ANCHORS, m_wndAnchorsList);
}
BEGIN_MESSAGE_MAP(CAIAnchorsDialog, CDialog)
ON_LBN_SELCHANGE(IDC_ANCHORS, OnLbnSelchangeAnchors)
END_MESSAGE_MAP()
// CAIAnchorsDialog message handlers
void CAIAnchorsDialog::OnLbnSelchangeAnchors()
{
int nSel=m_wndAnchorsList.GetCurSel();
if (nSel==LB_ERR)
return;
m_wndAnchorsList.GetText(nSel, m_sAnchor);
}
BOOL CAIAnchorsDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_wndAnchorsList.ResetContent();
CAIManager *pAIMgr=GetIEditor()->GetAI();
ASSERT(pAIMgr);
typedef std::vector<CString> TAnchorActionsVec;
TAnchorActionsVec vecAnchorActions;
pAIMgr->GetAnchorActions(vecAnchorActions);
int nSel=-1;
for (TAnchorActionsVec::iterator It=vecAnchorActions.begin();It!=vecAnchorActions.end();++It)
{
int nLastId=m_wndAnchorsList.AddString(*It);
if (m_sAnchor.CompareNoCase(*It)==0)
nSel=nLastId;
}
m_wndAnchorsList.SetCurSel(nSel);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}

32
Editor/AIAnchorsDialog.h Normal file
View File

@@ -0,0 +1,32 @@
#pragma once
// CAIAnchorsDialog dialog
class CAIAnchorsDialog : public CDialog
{
DECLARE_DYNAMIC(CAIAnchorsDialog)
private:
CString m_sAnchor;
CListBox m_wndAnchorsList;
public:
CAIAnchorsDialog(CWnd* pParent = NULL); // standard constructor
virtual ~CAIAnchorsDialog();
void SetAIAnchor(const CString &sAnchor) { m_sAnchor=sAnchor; }
CString GetAIAnchor() { return m_sAnchor; };
// Dialog Data
enum { IDD = IDD_AIANCHORS };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
afx_msg void OnLbnSelchangeAnchors();
public:
virtual BOOL OnInitDialog();
};

View File

@@ -0,0 +1,136 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: aicharactersdialog.cpp
// Version: v1.00
// Created: 13/9/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "AICharactersDialog.h"
#include "Controls\PropertyCtrl.h"
#include "AI\AIManager.h"
#include "AI\AIGoalLibrary.h"
#include "AI\AIBehaviorLibrary.h"
// CAICharactersDialog dialog
IMPLEMENT_DYNAMIC(CAICharactersDialog, CDialog)
CAICharactersDialog::CAICharactersDialog(CWnd* pParent /*=NULL*/)
: CDialog(CAICharactersDialog::IDD, pParent)
{
//m_propWnd = 0;
}
CAICharactersDialog::~CAICharactersDialog()
{
}
void CAICharactersDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT, m_editBtn);
DDX_Control(pDX, IDC_RELOAD, m_reloadBtn);
DDX_Control(pDX, IDC_BEHAVIOR, m_list);
DDX_Control(pDX, IDC_DESCRIPTION, m_description);
}
BEGIN_MESSAGE_MAP(CAICharactersDialog, CDialog)
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_EDIT, OnBnClickedEdit)
ON_BN_CLICKED(IDC_RELOAD, OnBnClickedReload)
ON_LBN_SELCHANGE(IDC_BEHAVIOR, OnLbnSelchangeBehavior)
END_MESSAGE_MAP()
// CAICharactersDialog message handlers
BOOL CAICharactersDialog::OnInitDialog()
{
CDialog::OnInitDialog();
ReloadCharacters();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CAICharactersDialog::OnDestroy()
{
CDialog::OnDestroy();
//delete m_propWnd;
}
//////////////////////////////////////////////////////////////////////////
void CAICharactersDialog::ReloadCharacters()
{
CAIBehaviorLibrary *lib = GetIEditor()->GetAI()->GetBehaviorLibrary();
std::vector<CAICharacterPtr> characters;
lib->GetCharacters( characters );
for (int i = 0; i < characters.size(); i++)
{
m_list.AddString( characters[i]->GetName() );
}
m_list.SelectString( -1,m_aiCharacter );
CAICharacter *character = GetIEditor()->GetAI()->GetBehaviorLibrary()->FindCharacter( m_aiCharacter );
if (character)
{
m_description.SetWindowText( character->GetDescription() );
}
else
{
m_description.SetWindowText( "" );
}
}
void CAICharactersDialog::SetAICharacter( const CString &character )
{
m_aiCharacter = character;
}
void CAICharactersDialog::OnBnClickedEdit()
{
CAICharacter *character = GetIEditor()->GetAI()->GetBehaviorLibrary()->FindCharacter( m_aiCharacter );
if (!character)
return;
character->Edit();
}
void CAICharactersDialog::OnBnClickedReload()
{
CAICharacter *character = GetIEditor()->GetAI()->GetBehaviorLibrary()->FindCharacter( m_aiCharacter );
if (!character)
return;
character->ReloadScript();
}
void CAICharactersDialog::OnLbnSelchangeBehavior()
{
int sel = m_list.GetCurSel();
if (sel == LB_ERR)
return;
m_list.GetText( sel,m_aiCharacter );
CAICharacter *character = GetIEditor()->GetAI()->GetBehaviorLibrary()->FindCharacter( m_aiCharacter );
if (character)
{
m_description.SetWindowText( character->GetDescription() );
}
else
{
m_description.SetWindowText( "" );
}
}

View File

@@ -0,0 +1,68 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: aicharactersdialog.h
// Version: v1.00
// Created: 13/9/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __aicharactersdialog_h__
#define __aicharactersdialog_h__
#if _MSC_VER > 1000
#pragma once
#endif
// CAICharactersDialog dialog
//////////////////////////////////////////////////////////////////////////
class CAICharactersDialog : public CDialog
{
DECLARE_DYNAMIC(CAICharactersDialog)
public:
CAICharactersDialog(CWnd* pParent = NULL); // standard constructor
virtual ~CAICharactersDialog();
// Dialog Data
enum { IDD = IDD_AICHARACTERS };
void SetAICharacter( const CString &chr );
CString GetAICharacter() { return m_aiCharacter; };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
protected:
virtual BOOL OnInitDialog();
afx_msg void OnDestroy();
afx_msg void OnBnClickedEdit();
afx_msg void OnBnClickedReload();
afx_msg void OnLbnSelchangeBehavior();
void ReloadCharacters();
//////////////////////////////////////////////////////////////////////////
// FIELDS
//////////////////////////////////////////////////////////////////////////
CListBox m_list;
CString m_aiCharacter;
CCustomButton m_editBtn;
CCustomButton m_reloadBtn;
CEdit m_description;
};
#endif // __aicharactersdialog_h__

175
Editor/AIDialog.cpp Normal file
View File

@@ -0,0 +1,175 @@
// AIDialog.cpp : implementation file
//
#include "stdafx.h"
#include "AIDialog.h"
#include "Controls\PropertyCtrl.h"
#include "AI\AIManager.h"
#include "AI\AIGoalLibrary.h"
#include "AI\AIBehaviorLibrary.h"
// CAIDialog dialog
IMPLEMENT_DYNAMIC(CAIDialog, CDialog)
CAIDialog::CAIDialog(CWnd* pParent /*=NULL*/)
: CDialog(CAIDialog::IDD, pParent)
{
//m_propWnd = 0;
}
CAIDialog::~CAIDialog()
{
}
void CAIDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT, m_editBtn);
DDX_Control(pDX, IDC_RELOAD, m_reloadBtn);
DDX_Control(pDX, IDC_BEHAVIOR, m_behaviors);
DDX_Control(pDX, IDC_DESCRIPTION, m_description);
}
BEGIN_MESSAGE_MAP(CAIDialog, CDialog)
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_EDIT, OnBnClickedEdit)
ON_BN_CLICKED(IDC_RELOAD, OnBnClickedReload)
ON_LBN_SELCHANGE(IDC_BEHAVIOR, OnLbnSelchangeBehavior)
END_MESSAGE_MAP()
// CAIDialog message handlers
BOOL CAIDialog::OnInitDialog()
{
CDialog::OnInitDialog();
ReloadBehaviors();
/*
XmlNodeRef root("Root");
CAIGoalLibrary *lib = GetIEditor()->GetAI()->GetGoalLibrary();
std::vector<CAIGoalPtr> goals;
lib->GetGoals( goals );
for (int i = 0; i < goals.size(); i++)
{
CAIGoal *goal = goals[i];
XmlNodeRef goalNode = root->newChild(goal->GetName());
goalNode->setAttr("type","List");
// Copy Goal params.
if (goal->GetParamsTemplate())
{
XmlNodeRef goalParams = goal->GetParamsTemplate()->clone();
for (int k = 0; k < goalParams->getChildCount(); k++)
{
goalNode->addChild(goalParams->getChild(k));
}
}
for (int j = 0; j < goal->GetStageCount(); j++)
{
CAIGoalStage &stage = goal->GetStage(j);
CAIGoal *stageGoal = lib->FindGoal(stage.name);
if (stageGoal)
{
XmlNodeRef stageNode = goalNode->newChild(stage.name);
stageNode->setAttr("type","List");
//if (stage.params)
{
XmlNodeRef templ = stageGoal->GetParamsTemplate()->clone();
//CXmlTemplate::GetValues( templ,stage.params );
for (int k = 0; k < templ->getChildCount(); k++)
{
stageNode->addChild(templ->getChild(k));
}
}
}
}
}
XmlParser parser;
root = parser.parse( "C:\\MasterCD\\ai.xml" );
CRect rc( 10,10,300,500 );
m_propWnd = new CPropertiesWindow( root,"Props","Props" );
m_propWnd->Resizable = false;
m_propWnd->OpenChildWindow( GetSafeHwnd(),rc,true );
m_propWnd->ForceRefresh();
m_propWnd->Show(1);
*/
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CAIDialog::OnDestroy()
{
CDialog::OnDestroy();
//delete m_propWnd;
}
//////////////////////////////////////////////////////////////////////////
void CAIDialog::ReloadBehaviors()
{
CAIBehaviorLibrary *lib = GetIEditor()->GetAI()->GetBehaviorLibrary();
std::vector<CAIBehaviorPtr> behaviors;
lib->GetBehaviors( behaviors );
for (int i = 0; i < behaviors.size(); i++)
{
m_behaviors.AddString( behaviors[i]->GetName() );
}
m_behaviors.SelectString( -1,m_aiBehavior );
CAIBehavior *behavior = GetIEditor()->GetAI()->GetBehaviorLibrary()->FindBehavior( m_aiBehavior );
if (behavior)
{
m_description.SetWindowText( behavior->GetDescription() );
}
else
{
m_description.SetWindowText( "" );
}
}
void CAIDialog::SetAIBehavior( const CString &behavior )
{
m_aiBehavior = behavior;
}
void CAIDialog::OnBnClickedEdit()
{
CAIBehavior *behavior = GetIEditor()->GetAI()->GetBehaviorLibrary()->FindBehavior( m_aiBehavior );
if (!behavior)
return;
behavior->Edit();
}
void CAIDialog::OnBnClickedReload()
{
CAIBehavior *behavior = GetIEditor()->GetAI()->GetBehaviorLibrary()->FindBehavior( m_aiBehavior );
if (!behavior)
return;
behavior->ReloadScript();
}
void CAIDialog::OnLbnSelchangeBehavior()
{
int sel = m_behaviors.GetCurSel();
if (sel == LB_ERR)
return;
m_behaviors.GetText( sel,m_aiBehavior );
CAIBehavior *behavior = GetIEditor()->GetAI()->GetBehaviorLibrary()->FindBehavior( m_aiBehavior );
if (behavior)
{
m_description.SetWindowText( behavior->GetDescription() );
}
else
{
m_description.SetWindowText( "" );
}
}

67
Editor/AIDialog.h Normal file
View File

@@ -0,0 +1,67 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
// File name: aidialog.h
// Version: v1.00
// Created: 21/3/2002 by Timur.
// Compilers: Visual C++ 7.0
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __aidialog_h__
#define __aidialog_h__
#if _MSC_VER > 1000
#pragma once
#endif
// CAIDialog dialog
class CAIDialog : public CDialog
{
DECLARE_DYNAMIC(CAIDialog)
public:
CAIDialog(CWnd* pParent = NULL); // standard constructor
virtual ~CAIDialog();
// Dialog Data
enum { IDD = IDD_AICONFIG };
void SetAIBehavior( const CString &behavior );
CString GetAIBehavior() { return m_aiBehavior; };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
protected:
virtual BOOL OnInitDialog();
afx_msg void OnDestroy();
void ReloadBehaviors();
//////////////////////////////////////////////////////////////////////////
// FIELDS
//////////////////////////////////////////////////////////////////////////
CListBox m_behaviors;
CString m_aiBehavior;
CCustomButton m_editBtn;
CCustomButton m_reloadBtn;
CEdit m_description;
afx_msg void OnBnClickedEdit();
afx_msg void OnBnClickedReload();
afx_msg void OnLbnSelchangeBehavior();
};
#endif // __aidialog_h__

213
Editor/AIPointPanel.cpp Normal file
View File

@@ -0,0 +1,213 @@
// AIPointPanel.cpp : implementation file
//
#include "stdafx.h"
#include "AIPointPanel.h"
#include "Objects\AIPoint.h"
// CAIPointPanel dialog
IMPLEMENT_DYNCREATE(CAIPointPanel, CDialog)
CAIPointPanel::CAIPointPanel(CWnd* pParent /*=NULL*/)
: CDialog(CAIPointPanel::IDD, pParent)
, m_type(0)
{
m_object = 0;
Create( IDD,pParent );
}
CAIPointPanel::~CAIPointPanel()
{
}
void CAIPointPanel::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_NODES, m_links);
DDX_Control(pDX, IDC_PICK, m_pickBtn);
DDX_Control(pDX, IDC_SELECT, m_selectBtn);
DDX_Control(pDX, IDC_REMOVE, m_removeBtn);
DDX_Radio(pDX, IDC_WAYPOINT, m_type);
}
BOOL CAIPointPanel::OnInitDialog()
{
CDialog::OnInitDialog();
m_links.SetBkColor( RGB(0xE0,0xE0,0xE0) );
m_pickBtn.SetPickCallback( this,"Pick AIPoint to Link",0 );
return TRUE; // return TRUE unless you set the focus to a control
}
BEGIN_MESSAGE_MAP(CAIPointPanel, CDialog)
ON_BN_CLICKED(IDC_SELECT, OnBnClickedSelect)
ON_BN_CLICKED(IDC_REMOVE, OnBnClickedRemove)
ON_LBN_DBLCLK(IDC_NODES, OnLbnDblclkLinks)
ON_LBN_SELCHANGE(IDC_NODES, OnLbnLinksSelChange)
ON_BN_CLICKED(IDC_WAYPOINT, OnBnClickedWaypoint)
ON_BN_CLICKED(IDC_HIDEPOINT, OnBnClickedHidepoint)
ON_BN_CLICKED(IDC_ENTRYPOINT, OnBnClickedEntrypoint)
ON_BN_CLICKED(IDC_EXITPOINT, OnBnClickedExitpoint)
END_MESSAGE_MAP()
void CAIPointPanel::SetObject( CAIPoint *object )
{
if (m_object)
{
for (int i = 0; i < m_object->GetLinkCount(); i++)
m_object->SelectLink(i,false);
}
assert( object );
m_object = object;
switch (object->GetAIType())
{
case EAIPOINT_WAYPOINT:
m_type = 0;
break;
case EAIPOINT_HIDE:
m_type = 1;
break;
case EAIPOINT_ENTRY:
m_type = 2;
break;
case EAIPOINT_EXIT:
m_type = 3;
break;
}
UpdateData(FALSE);
ReloadLinks();
}
//////////////////////////////////////////////////////////////////////////
void CAIPointPanel::StartPick()
{
// Simulate click on pick button.
m_pickBtn.OnClicked();
}
void CAIPointPanel::ReloadLinks()
{
m_links.ResetContent();
for (int i = 0; i < m_object->GetLinkCount(); i++)
{
CAIPoint *obj = m_object->GetLink(i);
if (obj)
m_links.AddString( obj->GetName() );
}
}
//////////////////////////////////////////////////////////////////////////
void CAIPointPanel::OnBnClickedSelect()
{
assert( m_object );
int sel = m_links.GetCurSel();
if (sel != LB_ERR)
{
CBaseObject *obj = m_object->GetLink(sel);
if (obj)
{
GetIEditor()->ClearSelection();
GetIEditor()->SelectObject( obj );
}
}
}
//////////////////////////////////////////////////////////////////////////
void CAIPointPanel::OnBnClickedRemove()
{
assert( m_object );
int sel = m_links.GetCurSel();
if (sel != LB_ERR)
{
CUndo undo( "Unlink AIPoint" );
CAIPoint *obj = m_object->GetLink(sel);
if (obj)
m_object->RemoveLink( obj );
ReloadLinks();
}
}
//////////////////////////////////////////////////////////////////////////
void CAIPointPanel::OnLbnDblclkLinks()
{
// Select current entity.
OnBnClickedSelect();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void CAIPointPanel::OnPick( CBaseObject *picked )
{
assert( m_object );
CUndo undo( "Link AIPoint" );
m_object->AddLink( (CAIPoint*)picked );
ReloadLinks();
//
// m_entityName.SetWindowText( picked->GetName() );
}
//////////////////////////////////////////////////////////////////////////
bool CAIPointPanel::OnPickFilter( CBaseObject *picked )
{
assert( picked != 0 );
return picked != m_object && picked->IsKindOf( RUNTIME_CLASS(CAIPoint) );
}
//////////////////////////////////////////////////////////////////////////
void CAIPointPanel::OnCancelPick()
{
}
//////////////////////////////////////////////////////////////////////////
void CAIPointPanel::OnBnClickedWaypoint()
{
assert( m_object );
m_object->SetAIType( EAIPOINT_WAYPOINT );
}
//////////////////////////////////////////////////////////////////////////
void CAIPointPanel::OnBnClickedHidepoint()
{
assert( m_object );
m_object->SetAIType( EAIPOINT_HIDE );
}
//////////////////////////////////////////////////////////////////////////
void CAIPointPanel::OnBnClickedEntrypoint()
{
assert( m_object );
m_object->SetAIType( EAIPOINT_ENTRY );
}
//////////////////////////////////////////////////////////////////////////
void CAIPointPanel::OnBnClickedExitpoint()
{
assert( m_object );
m_object->SetAIType( EAIPOINT_EXIT );
}
//////////////////////////////////////////////////////////////////////////
void CAIPointPanel::OnLbnLinksSelChange()
{
assert( m_object );
int sel = m_links.GetCurSel();
if (sel != LB_ERR)
{
// Unselect all others.
for (int i = 0; i < m_object->GetLinkCount(); i++)
{
if (sel == i)
m_object->SelectLink(i,true);
else
m_object->SelectLink(i,false);
}
}
}

54
Editor/AIPointPanel.h Normal file
View File

@@ -0,0 +1,54 @@
#pragma once
#include "Controls\PickObjectButton.h"
class CAIPoint;
// CAIPointPanel dialog
class CAIPointPanel : public CDialog, public IPickObjectCallback
{
DECLARE_DYNCREATE(CAIPointPanel)
public:
CAIPointPanel(CWnd* pParent = NULL); // standard constructor
virtual ~CAIPointPanel();
void SetObject( CAIPoint *object );
void StartPick();
// Dialog Data
enum { IDD = IDD_PANEL_AIPOINT };
protected:
virtual void OnOK() {};
virtual void OnCancel() {};
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnInitDialog();
afx_msg void OnBnClickedSelect();
afx_msg void OnBnClickedRemove();
afx_msg void OnLbnDblclkLinks();
afx_msg void OnLbnLinksSelChange();
DECLARE_MESSAGE_MAP()
void ReloadLinks();
// Ovverriden from IPickObjectCallback
virtual void OnPick( CBaseObject *picked );
virtual bool OnPickFilter( CBaseObject *picked );
virtual void OnCancelPick();
CAIPoint* m_object;
CColoredListBox m_links;
CPickObjectButton m_pickBtn;
CCustomButton m_selectBtn;
CCustomButton m_removeBtn;
int m_type;
public:
afx_msg void OnBnClickedWaypoint();
afx_msg void OnBnClickedHidepoint();
afx_msg void OnBnClickedEntrypoint();
afx_msg void OnBnClickedExitpoint();
};

19
Editor/AIPointPanel.htm Normal file
View File

@@ -0,0 +1,19 @@
<HTML>
<BODY ID=CAIPointPanel BGCOLOR=LIGHTGREY>
<TABLE WIDTH=100%>
<TR>
<TD ALIGN=RIGHT>
<BUTTON STYLE="WIDTH:100" ID="ButtonOK">OK</BUTTON><BR>
<BUTTON STYLE="WIDTH:100" ID="ButtonCancel">Cancel</BUTTON>
</TD>
</TR>
<TR WIDTH=100% HEIGHT=75>
<TD ALIGN=CENTER VALIGN=BOTTOM>
TODO: Place controls here.
</TD>
</TR>
</TABLE>
</BODY>
</HTML>

62
Editor/AlignTool.cpp Normal file
View File

@@ -0,0 +1,62 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: aligntool.cpp
// Version: v1.00
// Created: 13/8/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "AlignTool.h"
#include "Objects\BaseObject.h"
//////////////////////////////////////////////////////////////////////////
bool CAlignPickCallback::m_bActive = false;
//////////////////////////////////////////////////////////////////////////
//! Called when object picked.
void CAlignPickCallback::OnPick( CBaseObject *picked )
{
Matrix44 tm;
tm = picked->GetWorldTM();
{
bool bUndo = !CUndo::IsRecording();
if (bUndo)
GetIEditor()->BeginUndo();
CSelectionGroup *selGroup = GetIEditor()->GetSelection();
selGroup->FilterParents();
for (int i = 0; i < selGroup->GetFilteredCount(); i++)
{
selGroup->GetFilteredObject(i)->SetWorldTM(tm);
}
m_bActive = false;
if (bUndo)
GetIEditor()->AcceptUndo( "Align To Object");
}
delete this;
}
//! Called when pick mode cancelled.
void CAlignPickCallback::OnCancelPick()
{
m_bActive = false;
delete this;
}
//! Return true if specified object is pickable.
bool CAlignPickCallback::OnPickFilter( CBaseObject *filterObject )
{
return true;
};

44
Editor/AlignTool.h Normal file
View File

@@ -0,0 +1,44 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: aligntool.h
// Version: v1.00
// Created: 13/8/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __aligntool_h__
#define __aligntool_h__
#if _MSC_VER > 1000
#pragma once
#endif
#include "EditTool.h"
#include "Objects\ObjectManager.h"
//////////////////////////////////////////////////////////////////////////
class CAlignPickCallback : public IPickObjectCallback
{
public:
CAlignPickCallback() { m_bActive = true; };
//! Called when object picked.
virtual void OnPick( CBaseObject *picked );
//! Called when pick mode cancelled.
virtual void OnCancelPick();
//! Return true if specified object is pickable.
virtual bool OnPickFilter( CBaseObject *filterObject );
static bool IsActive() { return m_bActive; }
private:
static bool m_bActive;
};
#endif // __aligntool_h__

176
Editor/AnimObject.cpp Normal file
View File

@@ -0,0 +1,176 @@
#include "StdAfx.h"
#include "AnimObject.h"
#include "ASE\ASEParser.h"
#include <I3DEngine.h>
#include <IMovieSystem.h>
#include <ITimer.h>
//////////////////////////////////////////////////////////////////////////
CAnimObject::CAnimObject()
{
m_3dEngine = GetIEditor()->Get3DEngine();
m_bbox[0].SetMax();
m_bbox[1].SetMin();
m_angles.Set(0,0,0);
m_bNoUpdate = false;
}
//////////////////////////////////////////////////////////////////////////
CAnimObject::~CAnimObject()
{
ReleaseNodes();
}
//////////////////////////////////////////////////////////////////////////
void CAnimObject::ReleaseNodes()
{
for (int i = 0; i < m_nodes.size(); i++)
{
delete m_nodes[i];
}
m_nodes.clear();
}
//////////////////////////////////////////////////////////////////////////
CAnimObject::Node* CAnimObject::CreateNode( const char *szNodeName )
{
// Try to create object.
IStatObj *obj = m_3dEngine->MakeObject( m_fileName.c_str(),szNodeName );
if (!obj)
return 0;
obj->GetBoxMin().AddToBounds( m_bbox[0],m_bbox[1] );
obj->GetBoxMax().AddToBounds( m_bbox[0],m_bbox[1] );
Node *node = new Node;
node->m_name = szNodeName;
node->m_object = obj;
m_nodes.push_back(node);
return node;
}
//////////////////////////////////////////////////////////////////////////
void CAnimObject::Draw( const SRendParams &rp )
{
SRendParams nodeRP = rp;
for (int i = 0; i < m_nodes.size(); i++)
{
Node *node = m_nodes[i];
if (node->m_object)
{
Matrix tm = GetNodeMatrix(node);
tm = node->m_invOrigTM * tm;
nodeRP.pMatrix = &tm;
m_nodes[i]->m_object->Render(nodeRP);
}
}
}
//////////////////////////////////////////////////////////////////////////
void CAnimObject::Animate( float time )
{
for (int i = 0; i < m_nodes.size(); i++)
{
Node *node = m_nodes[i];
if (node->m_object)
{
if (node->m_posTrack)
{
Vec3 pos(0,0,0);
node->m_posTrack->GetValue( time,pos );
node->m_pos = pos;
node->m_bMatrixValid = false;
}
if (node->m_rotTrack)
{
Quat q(1,0,0,0);
node->m_rotTrack->GetValue( time,q );
node->m_rotate = q;
node->m_bMatrixValid = false;
}
if (node->m_scaleTrack)
{
Vec3 scale(1,1,1);
node->m_scaleTrack->GetValue( time,scale );
node->m_scale = scale;
node->m_bMatrixValid = false;
}
}
}
}
//////////////////////////////////////////////////////////////////////////
Matrix& CAnimObject::GetNodeMatrix( Node *node )
{
// fixme.
node->m_bMatrixValid = false;
assert(node);
if (!node->m_bMatrixValid)
{
// Make local matrix.
node->m_rotate.GetMatrix(node->m_tm);
node->m_tm.ScaleMatrix( node->m_scale.x,node->m_scale.y,node->m_scale.z );
node->m_tm.SetTranslation( node->m_pos );
node->m_bMatrixValid = true;
if (node->m_parent)
{
// Combine with parent matrix.
Matrix &parentTM = GetNodeMatrix(node->m_parent);
node->m_tm = node->m_tm * parentTM;
}
}
return node->m_tm;
}
//////////////////////////////////////////////////////////////////////////
bool CAnimObject::Load( const char *fileName,const char *aseFile )
{
m_fileName = fileName;
CASEParser aseParser;
if (aseParser.Parse( this,aseFile ))
{
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////
const CDLight* CAnimObject::GetBoundLight (int nIndex)
{
return 0;
}
//////////////////////////////////////////////////////////////////////////
//! Draw the character shadow volumes into the stencil buffer using a set of specified
//! rendering parameters ( for indoors )
void CAnimObject::RenderShadowVolumes(const SRendParams *rParams)
{
}
//! Draw the character without shaders for shadow mapping
void CAnimObject::DrawForShadow(const Vec3d & vTranslationPlus)
{
}
//////////////////////////////////////////////////////////////////////////
void CAnimObject::Update( Vec3d vPos, float fRadius, unsigned uFlags)
{
float time = GetIEditor()->GetSystem()->GetITimer()->GetCurrTime();
Animate( time );
}
//////////////////////////////////////////////////////////////////////////
bool CAnimObject::IsModelFileEqual (const char* szFileName)
{
return stricmp(szFileName,m_fileName.c_str()) == 0;
}

288
Editor/AnimObject.h Normal file
View File

@@ -0,0 +1,288 @@
#ifndef __AnimObject_h__
#define __AnimObject_h__
#pragma once
struct IAnimTrack;
#include "ICryAnimation.h"
//////////////////////////////////////////////////////////////////////////
class CAnimObject : public ICryCharInstance
{
public:
// Node in animated object.
struct Node
{
std::string m_name; // Node name.
//! Current node position (in object space).
Vec3 m_pos;
//! Current node rotation (in object space).
Quat m_rotate;
//! Original node scale (in object space).
Vec3 m_scale;
//! Node transformation matrix in world space.
Matrix m_tm;
//! Inverse tranform of Original node transformation.
Matrix m_invOrigTM;
//! True if current matrix is valid.
bool m_bMatrixValid;
//! parent node.
Node* m_parent;
//! Static object controlled by this node.
IStatObj* m_object;
// Animation tracks.
IAnimTrack* m_posTrack;
IAnimTrack* m_rotTrack;
IAnimTrack* m_scaleTrack;
Node()
{
m_tm.Identity();
m_invOrigTM.Identity();
m_parent = 0;
m_object = 0;
m_posTrack = 0;
m_rotTrack = 0;
m_scaleTrack = 0;
m_bMatrixValid = false;
m_pos.Set(0,0,0);
m_rotate.Identity();
m_scale.Set(1,1,1);
}
};
//////////////////////////////////////////////////////////////////////////
CAnimObject();
virtual ~CAnimObject();
//! Creates new node.
Node* CreateNode( const char *szNodeName );
//! Animate object to specified time.
void Animate( float time );
bool Load( const char *fileName,const char *aseFile );
virtual void Release()
{
delete this;
}
//////////////////////////////////////////////////////////////////////////
// ICryCharInstance implementation.
//////////////////////////////////////////////////////////////////////////
//! Returns the interface for animations applicable to this model
// Set rendering flags like (draw/notdraw) and position offset
virtual void SetFlags(int nFlags) {};
virtual int GetFlags() { return 0; };
//! Set shader template to be used with character
virtual bool SetShaderTemplateName(const char *TemplName, int Id, const char *ShaderName=0) { return true; };
//! Get shader template
virtual const char * GetShaderTemplateName() { return ""; };
//! Set refract coef. for refractive shader
virtual void SetShaderFloat(const char *Name, float fVal, const char *ShaderName=NULL) {};
//! Draw the character using a set of specified rendering parameters ( for outdoors )
virtual void Draw(const SRendParams & RendParams);
//! Interface for the renderer - returns the CDLight describing the light in this character;
//! returns NULL if there's no light with such index
//! ICryCharInstance owns this light. This light may be destructed without notice upon next call to
//! any other function but GetLight(). Nobody may every modify it.
virtual const class CDLight* GetBoundLight (int nIndex);
//! Draw the character shadow volumes into the stencil buffer using a set of specified
//! rendering parameters ( for indoors )
virtual void RenderShadowVolumes(const SRendParams *rParams);
//! Draw the character without shaders for shadow mapping
virtual void DrawForShadow(const Vec3d & vTranslationPlus = Vec3d(0,0,0));
//! Return dynamic bbox of object
virtual void GetBBox(Vec3d& Mins, Vec3d& Maxs)
{
Mins = m_bbox[0];
Maxs = m_bbox[1];
}
//! Return dynamic center of object
virtual const Vec3d GetCenter()
{
return 0.5f*(m_bbox[1] + m_bbox[0]);
}
//! Return dynamic radius of object
virtual const float GetRadius()
{
return (m_bbox[1] - m_bbox[0]).Length();
}
//! Attach object to bone (Return false if bone not found)
ObjectBindingHandle AttachObjectToBone(IStatObj * pWeaponModel, const char * szBoneName, bool bUseRelativeToDefPoseMatrix = true)
{
return 0;
}
//! Enables/Disables the Default Idle Animation restart.
//! If this feature is enabled, then the last looped animation will be played back after the current (non-loop) animation is finished.
//! Only those animations started with the flag bTreatAsDefaultIdleAnimation == true will be taken into account
void EnableLastIdleAnimationRestart (unsigned nLayer, bool bEnable = true) {}
//! Start specified animation
bool StartAnimation (const char * szAnimName, float fBlendTime=0.125f, int nLayerID=0, bool bTreatAsDefaultIdleAnimation = true)
{
return false;
}
//! Start specified animation. THe name StartAnimation2 suggest that this is the new version of StartAnimation, while
//! the old StartAnimation is kept for backward compatibility. This version introduces the animation blend-in and blend-out times (different)
bool StartAnimation2 (const char* szAnimName, float fBlendInTime = 0.125f, float fBlendOutTime = 0.125f, int nLayerID=0, bool bTreatAsDefaultIdleAnimation = true)
{
return false;
}
//! Return current animation name ( Return 0 if animations stoped )
const char* GetCurAnimation() { return ""; };
//! Resets all animation layers ( stops all animations )
virtual void ResetAnimations() {};
//! Set animations speed scale
//! This is the scale factor that affects the animation speed of the character.
//! All the animations are played with the constant real-time speed multiplied by this factor.
//! So, 0 means still animations (stuck at some frame), 1 - normal, 2 - twice as fast, 0.5 - twice slower than normal.
virtual void SetAnimationSpeed(float speed)
{
m_animSpeed = speed;
}
//! Enable object animation time update. If the bUpdate flag is false, subsequent calls to Update will not animate the character
virtual void EnableTimeUpdate(bool bUpdate)
{
m_bNoUpdate = bUpdate;
}
//! Set the current time of the given layer, in seconds
virtual void SetLayerTime (int nLayer, float fTimeSeconds) {};
//! Step animation (call this function every frame to animate character)
virtual void Update( Vec3d vPos = Vec3d(0,0,0), float fRadius=0, unsigned uFlags = 0);
//! Synchronizes state with character physical animation; should be called after all updates (such as animation, game bones updates, etc.)
virtual void UpdatePhysics() {};
//! IK (Used by physics engine)
virtual void BuildPhysicalEntity(IPhysicalEntity *pent,float mass,int surface_idx,float stiffness_scale=1.0f,int nLod=0)
{};
virtual IPhysicalEntity *CreateCharacterPhysics(IPhysicalEntity *pHost, float mass,int surface_idx,float stiffness_scale, int nLod=0)
{
return 0;
}
virtual int CreateAuxilaryPhysics(IPhysicalEntity *pHost, int nLod=0)
{
return false;
};
virtual IPhysicalEntity *GetCharacterPhysics(const char *pRootBoneName=0) { return 0; };
virtual void SynchronizeWithPhysicalEntity(IPhysicalEntity *pent) {};
virtual IPhysicalEntity *RelinquishCharacterPhysics() { return 0; };
virtual void SetLimbIKGoal(int limbid, vectorf ptgoal=vectorf(1E10f,0,0), int ik_flags=0, float addlen=0, vectorf goal_normal=vectorf(zero)) {};
virtual vectorf GetLimbEndPos(int limbid) { return vectorf(0,0,0); };
virtual void AddImpact(int partid, vectorf point,vectorf impact) {};
virtual int TranslatePartIdToDeadBody(int partid) { return 0; };
virtual vectorf GetOffset() { return vectorf(0,0,0); };
virtual void SetOffset(vectorf offset) {};
//! Direct access to the specified bone
virtual ICryBone * GetBoneByName(const char * szName) { return 0; };
//! Pose character bones
virtual bool SetAnimationFrame(const char * szString, int nFrame) { return false; };
virtual void AddAnimationEventSink(ICharInstanceSink * pCharInstanceSink) {};
//! Counterpart to AddAnimationEventSink
virtual void RemoveAnimationEventSink(ICharInstanceSink * pCharInstanceSink) {};
//! Enables receiving OnStart/OnEnd of specified animation from this character instance
//! The specified sink also receives the additional animation events specified through AddAnimationEvent interface for this animation
virtual void AddAnimationEventSink(const char* szAnimName, ICharInstanceSink * pCharInstanceSink) {};
//! Counterpart to the AddAnimationEventSink
virtual void RemoveAnimationEventSink(const char* szAnimName, ICharInstanceSink * pCharInstanceSink) {};
//! Adds an animation event; whenever the character plays the specified frame of the specified animation,
//! it calls back the animation event sinkreceiving OnEvent notification of specified animation for all instances using this model
virtual bool AddAnimationEvent(const char * szAnimName, int nFrameID, int nUserData) { return true; };
//! Deletes the animation event; from now on the sink won't be receiving the animation this event
virtual bool RemoveAnimationEvent (const char* szAnimName, int nFrameID, int nUserData) { return true; };
//! Callback interface
//! Enables receiving OnStart/OnEnd of specified animation from this character instance
virtual void SetAnimationSinkForInstance(const char * szAnimName, ICharInstanceSink * pCharInstanceSink) {};
//! Returns the model interface
virtual ICryCharModel* GetModel()
{
return &m_characterModel;
}
//! Start/stop to spawn particles on character body
virtual void EnableParticleEmitter(struct ParticleParams & SpawnParticleParams, bool bEnable, bool bOnlyUpLookingFaces=false) {};
//! Return position of helper of the static object which is attached to animated object
virtual Vec3d GetTPVWeaponHelper(const char * szHelperName, ObjectBindingHandle pInfo ) { return Vec3d(0,0,0); };
//! Set the twining type. If replace - animations of second layer will overwrite first, otherwise it will sum
virtual void SetTwiningMode(AnimTwinMode eTwinMode ) {};
//! Return damage zone id for specified bone id
virtual int GetDamageTableValue (int nId) { return 0; };
//! Renderer calls this function to allow update the video vertex buffers right before the rendering
virtual void ProcessSkinning(float modelmatrix[], int nTemplate) {};
//! returns true if the character is playing any animation now (so bbox is changing)
virtual bool IsCharacterActive() { return true; };
void SetAngles( const Vec3d& angles ) { m_angles = angles; }
Vec3d& GetAngles() { return m_angles; }
//! Spawn decal on the walls, static objects, terrain and entities
virtual void CreateDecal(CryEngineDecalInfo& Decal) {};
virtual bool IsModelFileEqual (const char* szFileName);
//////////////////////////////////////////////////////////////////////////
private:
void ReleaseNodes();
Matrix& GetNodeMatrix( Node *node );
//! Name of cgf.
std::string m_fileName;
// Animated nodes.
std::vector<Node*> m_nodes;
I3DEngine *m_3dEngine;
//! Animation speed.
float m_animSpeed;
bool m_bNoUpdate;
// Bounding box.
Vec3d m_bbox[2];
Vec3d m_angles;
struct SCharModel : public ICryCharModel
{
virtual ICryAnimationSet* GetAnimationSet () { return 0; };
virtual const char * GetBoneName(int nId) const { return ""; };
virtual int NumBones() const { return 0; };
virtual float GetScale() const { return 0; };
};
SCharModel m_characterModel;
};
#endif // __AnimObject_h__

338
Editor/AnimationContext.cpp Normal file
View File

@@ -0,0 +1,338 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: animationcontext.cpp
// Version: v1.00
// Created: 7/5/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "AnimationContext.h"
#include "IMovieSystem.h"
#include "ITimer.h"
#include "GameEngine.h"
#include "Objects\SelectionGroup.h"
#include "IObjectManager.h"
#include "Viewport.h"
#include "ViewManager.h"
//using namespace std;
//////////////////////////////////////////////////////////////////////////
CAnimationContext::CAnimationContext()
{
m_paused = 0;
m_playing = false;
m_recording = false;
m_timeRange.Set(0,0);
m_timeMarker.Set(0,0);
m_currTime = 0;
m_fTimeScale = 1.0f;
m_sequence = 0;
m_bLooping = false;
m_bAutoRecording = false;
m_fRecordingTimeStep = 0;
m_bEncodeAVI = false;
}
//////////////////////////////////////////////////////////////////////////
void CAnimationContext::SetSequence( IAnimSequence *seq )
{
if (m_sequence)
{
SetTime(0);
m_sequence->Deactivate();
}
m_sequence = seq;
if (m_sequence)
{
m_timeRange = m_sequence->GetTimeRange();
m_timeMarker=m_timeRange;
m_sequence->Activate();
ForceAnimation();
}
}
//////////////////////////////////////////////////////////////////////////
void CAnimationContext::SetTime( float t )
{
if (t < m_timeRange.start)
t = m_timeRange.start;
if (t > m_timeRange.end)
t = m_timeRange.end;
if (fabs(m_currTime-t) < 0.001f)
return;
m_currTime = t;
m_fRecordingCurrTime = t;
ForceAnimation();
}
//////////////////////////////////////////////////////////////////////////
void CAnimationContext::Pause()
{
assert( m_paused >= 0 );
m_paused++;
if (m_recording)
GetIEditor()->GetMovieSystem()->SetRecording(false);
GetIEditor()->GetMovieSystem()->Pause();
if (m_sequence)
m_sequence->Pause();
if (m_bEncodeAVI)
PauseAVIEncoding(true);
}
//////////////////////////////////////////////////////////////////////////
void CAnimationContext::Resume()
{
assert( m_paused > 0 );
m_paused--;
if (m_recording && m_paused == 0)
GetIEditor()->GetMovieSystem()->SetRecording(true);
GetIEditor()->GetMovieSystem()->Resume();
if (m_sequence)
m_sequence->Resume();
if (m_bEncodeAVI)
PauseAVIEncoding(false);
}
//////////////////////////////////////////////////////////////////////////
void CAnimationContext::SetRecording( bool recording )
{
if (recording == m_recording)
return;
m_paused = 0;
m_recording = recording;
m_playing = false;
if (!recording && m_fRecordingTimeStep != 0)
SetAutoRecording( false,0 );
// If started recording, assume we have modified the document.
GetIEditor()->SetModifiedFlag();
GetIEditor()->GetMovieSystem()->SetRecording(recording);
if (m_bEncodeAVI)
StopAVIEncoding();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void CAnimationContext::SetPlaying( bool playing )
{
if (playing == m_playing)
return;
m_paused = 0;
m_playing = playing;
m_recording = false;
GetIEditor()->GetMovieSystem()->SetRecording(false);
if (playing)
{
GetIEditor()->GetMovieSystem()->Resume();
if (m_sequence)
m_sequence->Resume();
if (m_bEncodeAVI)
StartAVIEncoding();
}
else
{
GetIEditor()->GetMovieSystem()->Pause();
GetIEditor()->GetMovieSystem()->SetSequenceStopBehavior( IMovieSystem::ONSTOP_GOTO_START_TIME );
GetIEditor()->GetMovieSystem()->StopAllSequences();
GetIEditor()->GetMovieSystem()->SetSequenceStopBehavior( IMovieSystem::ONSTOP_GOTO_END_TIME );
if (m_sequence)
m_sequence->Pause();
if (m_bEncodeAVI)
StopAVIEncoding();
}
/*
if (!playing && m_sequence != 0)
m_sequence->Reset();
*/
}
//////////////////////////////////////////////////////////////////////////
void CAnimationContext::Update()
{
if (m_paused > 0 || !(m_playing || m_bAutoRecording))
return;
ITimer *pTimer = GetIEditor()->GetSystem()->GetITimer();
if (!m_bAutoRecording)
{
if (m_sequence != NULL)
{
SAnimContext ac;
ac.dt = 0;
ac.fps = pTimer->GetFrameRate();
ac.time = m_currTime;
ac.bSingleFrame = (!m_playing) || (m_fTimeScale!=1.0f);
m_sequence->Animate( ac );
}
float dt = pTimer->GetFrameTime();
m_currTime += dt * m_fTimeScale;
if (!m_recording)
GetIEditor()->GetMovieSystem()->Update(dt);
}
else
{
float dt = pTimer->GetFrameTime();
m_fRecordingCurrTime += dt*m_fTimeScale;
if (fabs(m_fRecordingCurrTime-m_currTime) > m_fRecordingTimeStep)
m_currTime += m_fRecordingTimeStep;
}
if (m_currTime > m_timeMarker.end)
{
if (m_bAutoRecording)
{
SetAutoRecording(false,0);
}
else
{
if (m_bLooping)
m_currTime = m_timeMarker.start;
else
SetPlaying(false);
}
}
if (m_bAutoRecording)
{
// This is auto recording mode.
// Send sync with physics event to all selected entities.
GetIEditor()->GetSelection()->SendEvent( EVENT_PHYSICS_GETSTATE );
}
}
//////////////////////////////////////////////////////////////////////////
void CAnimationContext::ForceAnimation()
{
// Before animating node, pause recording.
Pause();
if (m_sequence)
{
SAnimContext ac;
ac.dt = 0;
ac.fps = GetIEditor()->GetSystem()->GetITimer()->GetFrameRate();
ac.time = m_currTime;
ac.bSingleFrame = true;
m_sequence->Animate( ac );
}
Resume();
}
//////////////////////////////////////////////////////////////////////////
void CAnimationContext::ResetAnimations( bool bPlayOnLoad )
{
if (m_sequence)
{
SetTime(0);
}
GetIEditor()->GetMovieSystem()->Reset(bPlayOnLoad);
}
//////////////////////////////////////////////////////////////////////////
void CAnimationContext::SetAutoRecording( bool bEnable,float fTimeStep )
{
if (bEnable)
{
m_bAutoRecording = true;
m_fRecordingTimeStep = fTimeStep;
// Turn on fixed time step.
ICVar *fixed_time_step = GetIEditor()->GetSystem()->GetIConsole()->GetCVar( "fixed_time_step" );
if (fixed_time_step)
{
//fixed_time_step->Set( m_fRecordingTimeStep );
}
// Enables physics/ai.
GetIEditor()->GetGameEngine()->SetSimulationMode(true);
SetRecording(bEnable);
}
else
{
m_bAutoRecording = false;
m_fRecordingTimeStep = 0;
// Turn off fixed time step.
ICVar *fixed_time_step = GetIEditor()->GetSystem()->GetIConsole()->GetCVar( "fixed_time_step" );
if (fixed_time_step)
{
//fixed_time_step->Set( 0 );
}
// Disables physics/ai.
GetIEditor()->GetGameEngine()->SetSimulationMode(false);
}
}
//////////////////////////////////////////////////////////////////////////
void CAnimationContext::PlayToAVI( bool bEnable,const char *aviFilename )
{
if (bEnable && aviFilename)
{
m_bEncodeAVI = true;
m_aviFilename = aviFilename;
}
else
{
m_bEncodeAVI = false;
}
}
//////////////////////////////////////////////////////////////////////////
bool CAnimationContext::IsPlayingToAVI() const
{
return m_bEncodeAVI;
}
//////////////////////////////////////////////////////////////////////////
void CAnimationContext::StartAVIEncoding()
{
CViewport* pViewport = GetIEditor()->GetViewManager()->GetActiveViewport();
if (pViewport)
{
pViewport->StartAVIRecording( m_aviFilename );
}
}
//////////////////////////////////////////////////////////////////////////
void CAnimationContext::StopAVIEncoding()
{
CViewport* pViewport = GetIEditor()->GetViewManager()->GetActiveViewport();
if (pViewport)
{
pViewport->StopAVIRecording();
}
}
//////////////////////////////////////////////////////////////////////////
void CAnimationContext::PauseAVIEncoding( bool bPause )
{
CViewport* pViewport = GetIEditor()->GetViewManager()->GetActiveViewport();
if (pViewport)
{
pViewport->PauseAVIRecording( bPause );
}
}

200
Editor/AnimationContext.h Normal file
View File

@@ -0,0 +1,200 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: animationcontext.h
// Version: v1.00
// Created: 7/5/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __animationcontext_h__
#define __animationcontext_h__
#if _MSC_VER > 1000
#pragma once
#endif
struct IAnimSequence;
/** CAnimationContext stores information about current editable animation sequence.
Stores information about whenever animation is being recorded know,
currect sequence, current time in sequence etc.
*/
class CAnimationContext
{
public:
//////////////////////////////////////////////////////////////////////////
// Constructors.
//////////////////////////////////////////////////////////////////////////
/** Constructor.
*/
CAnimationContext();
//////////////////////////////////////////////////////////////////////////
// Accessors
//////////////////////////////////////////////////////////////////////////
/** Return current animation time in active sequence.
@return Current time.
*/
float GetTime() const { return m_currTime; };
void SetTimeScale(float fScale) { m_fTimeScale=fScale; }
/** Get currently edited sequence.
*/
IAnimSequence* GetSequence() const { return m_sequence; };
/** Set time markers to play within.
*/
void SetMarkers(Range Marker) { m_timeMarker=Marker; }
/** Get time markers to play within.
*/
Range GetMarkers() { return m_timeMarker; }
/** Get time range of active animation sequence.
*/
Range GetTimeRange() const { return m_timeRange; }
/** Returns true if editor is recording animations now.
*/
bool IsRecording() const { return m_recording && m_paused==0; };
/** Returns true if editor is playing animation now.
*/
bool IsPlaying() const { return m_playing && m_paused==0; };
/** Returns true if currently playing or recording is paused.
*/
bool IsPaused() const { return m_paused > 0; }
/** Return if animation context is now in playing mode.
In difference from IsPlaying function this function not affected by pause state.
*/
bool IsPlayMode() const { return m_playing; };
/** Return if animation context is now in recording mode.
In difference from IsRecording function this function not affected by pause state.
*/
bool IsRecordMode() const { return m_recording; };
/** Returns true if currently looping as activated.
*/
bool IsLoopMode() const { return m_bLooping; }
/** Enable/Disable looping.
*/
void SetLoopMode(bool bLooping) { m_bLooping=bLooping; }
//////////////////////////////////////////////////////////////////////////
// Operators
//////////////////////////////////////////////////////////////////////////
/** Set current animation time in active sequence.
@param seq New active time.
*/
void SetTime( float t );
/** Set active editing sequence.
@param seq New active sequence.
*/
void SetSequence( IAnimSequence *seq );
/** Start animation recorduing.
Automatically stop playing.
@param recording True to start recording, false to stop.
*/
void SetRecording( bool playing );
/** Enables/Disables automatic recording, sets the time step for each recorded frame.
*/
void SetAutoRecording( bool bEnable,float fTimeStep );
//! Check if autorecording enabled.
bool IsAutoRecording() const { return m_bAutoRecording; };
/** Start/Stop animation playing.
Automatically stop recording.
@param playing True to start playing, false to stop.
*/
void SetPlaying( bool playing );
/** Pause animation playing/recording.
*/
void Pause();
/** Resume animation playing/recording.
*/
void Resume();
/** Called every frame to update all animations if animation should be playing.
*/
void Update();
/** Force animation for current sequence.
*/
void ForceAnimation();
/** Reset all animation sequences to zero time.
*/
void ResetAnimations( bool bPlayOnLoad );
//////////////////////////////////////////////////////////////////////////
// Enables playback of sequence with encoding to the AVI.
// Arguments:
// bEnable - Enables/Disables writing to the AVI when playing sequence.
// aviFilename - Filename of avi file, must be with .avi extension.
void PlayToAVI( bool bEnable,const char *aviFilename=NULL );
bool IsPlayingToAVI() const;
private:
//////////////////////////////////////////////////////////////////////////
void StartAVIEncoding();
void StopAVIEncoding();
void PauseAVIEncoding( bool bPause );
//! Current time within active animation sequence.
float m_currTime;
float m_fTimeScale;
// Recording time step.
float m_fRecordingTimeStep;
float m_fRecordingCurrTime;
bool m_bAutoRecording;
//! Time range of active animation sequence.
Range m_timeRange;
Range m_timeMarker;
//! Currently active animation sequence.
TSmartPtr<IAnimSequence> m_sequence;
bool m_bLooping;
//! True if editor is recording animations now.
bool m_recording;
//! True if editor is plaing animation now.
bool m_playing;
//! Stores how many times animation have been paused prior to calling resume.
int m_paused;
//////////////////////////////////////////////////////////////////////////
//! When set encoding to the AVI while playing.
bool m_bEncodeAVI;
//! Name of the AVI file.
CString m_aviFilename;
};
#endif // __animationcontext_h__

View File

@@ -0,0 +1,100 @@
#include "StdAfx.h"
#include "animationserializer.h"
#include "cryeditdoc.h"
#include "mission.h"
#include "IMovieSystem.h"
#include "Util\PakFile.h"
CAnimationSerializer::CAnimationSerializer(void)
{
}
CAnimationSerializer::~CAnimationSerializer(void)
{
}
//////////////////////////////////////////////////////////////////////////
void CAnimationSerializer::SaveSequence( IAnimSequence *seq,const char *szFilePath, bool bSaveEmpty )
{
assert( seq != 0 );
XmlNodeRef sequenceNode = new CXmlNode( "Sequence" );
seq->Serialize( sequenceNode,false, false );
sequenceNode->saveToFile( szFilePath );
}
IAnimSequence* CAnimationSerializer::LoadSequence( const char *szFilePath )
{
IAnimSequence *seq = 0;
XmlParser parser;
XmlNodeRef sequenceNode = parser.parse( szFilePath );
if (sequenceNode)
{
seq = GetIEditor()->GetMovieSystem()->LoadSequence( sequenceNode );
}
return seq;
}
//////////////////////////////////////////////////////////////////////////
void CAnimationSerializer::SaveAllSequences( const char *szPath,CPakFile &pakFile )
{
IMovieSystem *movSys = GetIEditor()->GetMovieSystem();
XmlNodeRef movieNode=new CXmlNode("MovieData");
for (int i=0;i<GetIEditor()->GetDocument()->GetMissionCount();i++)
{
CMission *pMission=GetIEditor()->GetDocument()->GetMission(i);
pMission->ExportAnimations(movieNode);
}
string sFilename=string(szPath)+"MovieData.xml";
//movieNode->saveToFile(sFilename.c_str());
XmlString xml = movieNode->getXML();
CMemFile file;
file.Write( xml.c_str(),xml.length() );
pakFile.UpdateFile( sFilename.c_str(),file );
}
//////////////////////////////////////////////////////////////////////////
void CAnimationSerializer::LoadAllSequences( const char *szPath )
{
CString dir = Path::AddBackslash(szPath);
std::vector<CFileUtil::FileDesc> files;
CFileUtil::ScanDirectory( dir,"*.seq",files,false );
for (int i = 0; i < files.size(); i++)
{
// Construct the full filepath of the current file
LoadSequence( dir + files[i].filename );
}
}
//////////////////////////////////////////////////////////////////////////
void CAnimationSerializer::SerializeSequences( XmlNodeRef &xmlNode,bool bLoading )
{
if (bLoading)
{
// Load.
IMovieSystem *movSys = GetIEditor()->GetMovieSystem();
movSys->RemoveAllSequences();
int num = xmlNode->getChildCount();
for (int i = 0; i < num; i++)
{
XmlNodeRef seqNode = xmlNode->getChild(i);
movSys->LoadSequence( seqNode );
}
}
else
{
// Save.
IMovieSystem *movSys = GetIEditor()->GetMovieSystem();
ISequenceIt *It=movSys->GetSequences();
IAnimSequence *seq=It->first();
while (seq)
{
XmlNodeRef seqNode = xmlNode->newChild( "Sequence" );
seq->Serialize( seqNode,false );
seq=It->next();
}
It->Release();
}
}

View File

@@ -0,0 +1,57 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: animationserializer.h
// Version: v1.00
// Created: 22/5/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __animationserializer_h__
#define __animationserializer_h__
#if _MSC_VER > 1000
#pragma once
#endif
// forward declarations.
struct IAnimSequence;
struct IAnimBlock;
class CPakFile;
/** Used by Editor to serialize animation data.
*/
class CAnimationSerializer
{
public:
CAnimationSerializer();
~CAnimationSerializer();
/** Save all animation sequences to files in givven directory.
*/
void SerializeSequences( XmlNodeRef &xmlNode,bool bLoading );
/** Saves single animation sequence to file in givven directory.
*/
void SaveSequence( IAnimSequence *seq,const char *szFilePath, bool bSaveEmpty=true );
/** Load sequence from file.
*/
IAnimSequence* LoadSequence( const char *szFilePath );
/** Save all animation sequences to files in givven directory.
*/
void SaveAllSequences( const char *szPath,CPakFile &pakFile );
/** Load all animation sequences from givven directory.
*/
void LoadAllSequences( const char *szPath );
};
#endif // __animationserializer_h__

509
Editor/Ase/ASEParser.cpp Normal file
View File

@@ -0,0 +1,509 @@
#include "StdAfx.h"
#include "AseParser.h"
#include "ASETokens.h"
#include <IMovieSystem.h>
//////////////////////////////////////////////////////////////////////////
CASEParser::CASEParser()
{
m_currentPos = 0;
m_animObject = 0;
m_node = 0;
}
//////////////////////////////////////////////////////////////////////////
float CASEParser::TickToTime( int ticks )
{
return (float)ticks / (m_scene.ticksPerFrame*m_scene.frameSpeed);
}
//////////////////////////////////////////////////////////////////////////
bool CASEParser::Compare( const char* token, const char* id )
{
if (!token)
return FALSE;
return stricmp(token, id) == 0;
}
//////////////////////////////////////////////////////////////////////////
char* CASEParser::GetToken()
{
static char str[512];
char* p;
int ch;
BOOL quoted = FALSE;
p = str;
// Skip white space
while (isspace(ch = GetChar()) && !IsEof());
// Are we at end of file?
if (IsEof())
{
return NULL;
}
if (ch == '\"')
{
quoted = TRUE;
}
// Read everything that is not white space into the token buffer
do
{
*p = ch;
p++;
ch = GetChar();
if (ch == '\"')
{
quoted = FALSE;
}
} while ((quoted || !isspace(ch)) && !IsEof());
*p = '\0';
if (str[0] == '\0')
return NULL;
return str;
}
// Skip to the end of this block.
bool CASEParser::SkipBlock()
{
char* token;
int level = 1;
do
{
token = GetToken();
if (Compare(token, "{"))
level++;
else if (Compare(token, "}"))
level--;
} while (level > 0);
return true;
}
//////////////////////////////////////////////////////////////////////////
Vec3d CASEParser::GetVec3()
{
char* token;
Vec3d p;
token = GetToken();
p.x = (float)atof(token);
token = GetToken();
p.y = (float)atof(token);
token = GetToken();
p.z = (float)atof(token);
return p;
}
//////////////////////////////////////////////////////////////////////////
Quat CASEParser::GetQuat()
{
char* token;
Quat q;
token = GetToken();
q.x = (float)atof(token);
token = GetToken();
q.y = (float)atof(token);
token = GetToken();
q.z = (float)atof(token);
token = GetToken();
q.w = (float)atof(token);
return q;
}
//////////////////////////////////////////////////////////////////////////
float CASEParser::GetFloat()
{
char* token;
float f;
token = GetToken();
f = (float)atof(token);
return f;
}
//////////////////////////////////////////////////////////////////////////
int CASEParser::GetInt()
{
char* token;
int i;
token = GetToken();
i = atoi(token);
return i;
}
//////////////////////////////////////////////////////////////////////////
const char* CASEParser::GetString()
{
static std::string str;
str = GetToken();
str = str.substr( 1,str.length()-2 );
return str.c_str();
}
//////////////////////////////////////////////////////////////////////////
CAnimObject::Node* CASEParser::FindNode( const char *sNodeName )
{
NodeMap::iterator it = m_nodeMap.find(sNodeName);
if (it == m_nodeMap.end())
return 0;
return it->second;
}
//////////////////////////////////////////////////////////////////////////
Vec3 CASEParser::ScalePosition( const Vec3 &pos )
{
return pos * (1.0f/100.0f);
}
//////////////////////////////////////////////////////////////////////////
void CASEParser::ParseGeomNode()
{
Vec3 nodePos(0,0,0);
Vec3 nodeScale(1,1,1);
Vec3 nodeRotAxis(0,0,0);
float nodeRotAngle = 0;
// New node.
m_node = 0;
int level = 0;
const char *str;
char *token;
do
{
token = GetToken();
if (Compare(token, "{"))
level++;
else if (Compare(token, "}"))
level--;
else if (Compare(token,ASE_NODE_NAME))
{
if (level == 1)
{
str = GetString();
m_node = m_animObject->CreateNode(str);
m_nodeMap[str] = m_node;
}
continue;
}
if (!m_node)
continue;
if (Compare(token,ASE_NODE_PARENT))
{
str = GetString();
m_node->m_parent = FindNode(str);
}
else if (Compare(token,ASE_TM_POS))
{
nodePos = ScalePosition(GetVec3());
}
else if (Compare(token,ASE_TM_SCALE))
{
nodeScale = GetVec3();
}
else if (Compare(token,ASE_TM_ROTANGLE))
{
nodeRotAngle = GetFloat();
}
else if (Compare(token,ASE_TM_ROTAXIS))
{
nodeRotAxis = GetVec3();
}
else if (Compare(token,ASE_TM_ANIMATION))
{
ParseTMAnimation();
}
} while (level > 0);
if (m_node)
{
Quat q;
q.SetFromAngleAxis( nodeRotAngle,nodeRotAxis );
m_node->m_pos = nodePos;
m_node->m_scale = nodeScale;
m_node->m_rotate = q;
Matrix tm;
q.GetMatrix(tm);
tm.ScaleMatrix( nodeScale.x,nodeScale.y,nodeScale.z );
tm.SetTranslation( nodePos );
tm.Invert();
if (m_node->m_parent)
m_node->m_invOrigTM = tm * m_node->m_parent->m_invOrigTM;
else
m_node->m_invOrigTM = tm;
}
}
//////////////////////////////////////////////////////////////////////////
void CASEParser::ParseTMAnimation()
{
std::vector<ITcbKey> posTableTcb;
std::vector<ITcbKey> rotTableTcb;
std::vector<ITcbKey> scaleTableTcb;
// Optimize allocations.
posTableTcb.reserve( 10 );
rotTableTcb.reserve( 10 );
scaleTableTcb.reserve( 10 );
// Parse node animation.
Quat prevQ;
prevQ.Identity();
int level = 0;
char *token;
do
{
token = GetToken();
if (Compare(token, "{"))
level++;
else if (Compare(token, "}"))
level--;
else if (Compare(token,ASE_CONTROL_POS_TCB))
{
// Tcb Position controller.
m_node->m_posTrack = GetIEditor()->GetMovieSystem()->CreateTrack( ATRACK_TCB_VECTOR );
m_node->m_posTrack->SetFlags( ATRACK_CYCLE );
}
else if (Compare(token,ASE_CONTROL_ROT_TCB))
{
// Tcb Position controller.
m_node->m_rotTrack = GetIEditor()->GetMovieSystem()->CreateTrack( ATRACK_TCB_QUAT );
m_node->m_rotTrack->SetFlags( ATRACK_CYCLE );
}
else if (Compare(token,ASE_CONTROL_SCALE_TCB))
{
// Tcb Position controller.
m_node->m_scaleTrack = GetIEditor()->GetMovieSystem()->CreateTrack( ATRACK_TCB_VECTOR );
m_node->m_scaleTrack->SetFlags( ATRACK_CYCLE );
}
/*********************************************************************/
//
// Controller keys
//
/*********************************************************************/
else if (Compare(token, ASE_POS_SAMPLE) || Compare(token, ASE_POS_KEY))
{
/*
PosKeeper* p = new PosKeeper;
p->t = GetInt();
p->val = GetVec3();
// Bezier tangents
p->inTan = p->val;
p->outTan = p->val;
p->flags = 0;
p->type = kBez;
posTable.Append(1, &p, 5);
*/
}
else if (Compare(token, ASE_BEZIER_POS_KEY))
{
/*
PosKeeper* p = new PosKeeper;
p->t = GetInt();
p->val = GetVec3();
// Bezier tangents
p->inTan = GetVec3();
p->outTan = GetVec3();
p->flags = GetInt();
p->type = kBez;
posTable.Append(1, &p, 5);
*/
}
else if (Compare(token, ASE_TCB_POS_KEY))
{
ITcbKey key;
key.time = TickToTime(GetInt());
key.SetVec3( ScalePosition(GetVec3()) );
key.tens = GetFloat();
key.cont = GetFloat();
key.bias = GetFloat();
key.easeto = GetFloat();
key.easefrom = GetFloat();
posTableTcb.push_back(key);
}
else if (Compare(token, ASE_TCB_ROT_KEY))
{
ITcbKey key;
key.time = TickToTime(GetInt());
Vec3 axis = GetVec3();
float angle = GetFloat();
key.tens = GetFloat();
key.cont = GetFloat();
key.bias = GetFloat();
key.easeto = GetFloat();
key.easefrom = GetFloat();
Quat q;
q.SetFromAngleAxis( angle,axis );
// Rotation in ASE file is relative, so we must convert it to absolute.
q = q * prevQ;
prevQ = q;
key.SetQuat(q);
rotTableTcb.push_back(key);
}
else if (Compare(token, ASE_TCB_SCALE_KEY))
{
ITcbKey key;
key.time = TickToTime(GetInt());
key.SetVec3( GetVec3() );
key.tens = GetFloat();
key.cont = GetFloat();
key.bias = GetFloat();
key.easeto = GetFloat();
key.easefrom = GetFloat();
scaleTableTcb.push_back(key);
}
} while (level > 0);
if (m_node->m_posTrack)
{
m_node->m_posTrack->SetNumKeys(posTableTcb.size());
for (int i = 0; i < posTableTcb.size(); i++)
{
m_node->m_posTrack->SetKey( i,&posTableTcb[i] );
}
}
if (m_node->m_rotTrack)
{
m_node->m_rotTrack->SetNumKeys(rotTableTcb.size());
for (int i = 0; i < rotTableTcb.size(); i++)
{
m_node->m_rotTrack->SetKey( i,&rotTableTcb[i] );
}
/*
FILE *file = fopen( "Objects\\sampl.txt","wt" );
prevQ.Identity();
// Sample rot track.
for (int t = 0; t < 14400; t+= 160)
{
Quat qval;
m_node->m_rotTrack->GetValue( t,qval );
Quat q = qval / prevQ;
prevQ = qval;
q = q.GetAngleAxis();
fprintf( file,"%d: %.4f,%.4f,%.4f,%.4f\n",t,q.x,q.y,q.z,q.w );
}
fclose(file);
*/
}
if (m_node->m_scaleTrack)
{
m_node->m_scaleTrack->SetNumKeys(scaleTableTcb.size());
for (int i = 0; i < scaleTableTcb.size(); i++)
{
m_node->m_scaleTrack->SetKey( i,&scaleTableTcb[i] );
}
}
}
//////////////////////////////////////////////////////////////////////////
// Get scene parameters from the file
void CASEParser::ParseSceneParams()
{
char* token;
int level = 0;
do
{
token = GetToken();
if (Compare(token, ASE_FIRSTFRAME))
{
m_scene.firstFrame = GetInt();
}
else if (Compare(token, ASE_LASTFRAME))
{
m_scene.lastFrame = GetInt();
}
else if (Compare(token, ASE_FRAMESPEED))
{
m_scene.frameSpeed = GetInt();
}
else if (Compare(token, ASE_TICKSPERFRAME))
{
m_scene.ticksPerFrame = GetInt();
}
else if (Compare(token, "{"))
level++;
else if (Compare(token, "}"))
level--;
} while (level > 0);
}
//////////////////////////////////////////////////////////////////////////
bool CASEParser::ParseString( CAnimObject *object,const char *buffer )
{
m_animObject = object;
m_buffer = buffer;
char *token;
while (token = GetToken())
{
if (Compare(token,ASE_SCENE))
{
ParseSceneParams();
}
else if (Compare(token,ASE_GEOMETRY))
{
ParseGeomNode();
}
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CASEParser::Parse( CAnimObject *object,const char *filename )
{
m_animObject = object;
FILE *file = fopen(filename,"rb");
if (file)
{
fseek( file,0,SEEK_END );
int fsize = ftell(file);
fseek( file,0,SEEK_SET );
char *buf = new char[fsize+1];
fread( buf,fsize,1,file );
buf[fsize] = 0;
ParseString( m_animObject,buf );
delete []buf;
fclose(file);
}
return true;
}

72
Editor/Ase/ASEParser.h Normal file
View File

@@ -0,0 +1,72 @@
#ifndef __ASEParser_h__
#define __ASEParser_h__
#pragma once
#include "AnimObject.h"
//////////////////////////////////////////////////////////////////////////
class CASEParser
{
public:
CASEParser();
bool ParseString( CAnimObject *object,const char *buffer );
bool Parse( CAnimObject *object,const char *filename );
private:
void ParseGeomNode();
void ParseTMAnimation();
void ParseSceneParams();
CAnimObject::Node* FindNode( const char *sNodeName );
//! Convert ticks to time in seconds.
float TickToTime( int ticks );
Vec3 ScalePosition( const Vec3 &pos );
// Get a next token from the stream.
char* GetToken();
bool SkipBlock();
// Do a string comparison
bool Compare( const char* token, const char* id );
//! Get vector from the stream.
Vec3d GetVec3();
//! Get quaternion from the stream.
Quat GetQuat();
//! Get float from the stream.
float GetFloat();
//! Get integer from the stream.
int GetInt();
// Get a string from the stream and strip leading and trailing quotes.
const char* GetString();
//! Get next character in stream.
char GetChar() { return m_buffer[m_currentPos++]; }
//! Check if reached end of input buffer.
bool IsEof() { return m_currentPos == m_buffer.size(); }
//! Input buffer.
std::string m_buffer;
//! Current position in buffer.
int m_currentPos;
//! Current animation object.
CAnimObject *m_animObject;
//! Current node.
CAnimObject::Node* m_node;
typedef std::map<std::string,CAnimObject::Node*> NodeMap;
NodeMap m_nodeMap;
// Stores global object parameters.
struct SceneParams
{
int firstFrame;
int lastFrame;
int frameSpeed;
int ticksPerFrame;
};
SceneParams m_scene;
};
#endif __ASEParser_h__

336
Editor/Ase/ASETokens.h Normal file
View File

@@ -0,0 +1,336 @@
#ifndef __ASETokens_h__
#define __ASETokens_h__
#pragma once
// Top level category ID's
#define ASE_SCENE _T("*SCENE")
#define ASE_GEOMETRY _T("*GEOMOBJECT")
#define ASE_SHAPE _T("*SHAPEOBJECT")
#define ASE_CAMERA _T("*CAMERAOBJECT")
#define ASE_LIGHT _T("*LIGHTOBJECT")
#define ASE_HELPER _T("*HELPEROBJECT")
#define ASE_MATERIAL_LIST _T("*MATERIAL_LIST")
// Hierarchy
#define ASE_GROUP _T("*GROUP")
// Node related ID's
#define ASE_NODE_TM _T("*NODE_TM")
#define ASE_NODE_NAME _T("*NODE_NAME")
#define ASE_NODE_PARENT _T("*NODE_PARENT")
// Object (node) properties
#define ASE_PROP_MOTIONBLUR _T("*PROP_MOTIONBLUR")
#define ASE_PROP_CASTSHADOW _T("*PROP_CASTSHADOW")
#define ASE_PROP_RECVSHADOW _T("*PROP_RECVSHADOW")
// Mesh related ID's
#define ASE_MESH _T("*MESH")
#define ASE_MESH_NORMALS _T("*MESH_NORMALS")
#define ASE_MESH_NUMVERTEX _T("*MESH_NUMVERTEX")
#define ASE_MESH_NUMFACES _T("*MESH_NUMFACES")
#define ASE_MESH_VERTEX_LIST _T("*MESH_VERTEX_LIST")
#define ASE_MESH_VERTEX _T("*MESH_VERTEX")
#define ASE_MESH_FACE_LIST _T("*MESH_FACE_LIST")
#define ASE_MESH_FACE _T("*MESH_FACE")
#define ASE_MESH_SMOOTHING _T("*MESH_SMOOTHING")
#define ASE_MESH_MTLID _T("*MESH_MTLID")
#define ASE_MESH_NUMTVERTEX _T("*MESH_NUMTVERTEX")
#define ASE_MESH_NUMTVFACES _T("*MESH_NUMTVFACES")
#define ASE_MESH_TVERTLIST _T("*MESH_TVERTLIST")
#define ASE_MESH_TVERT _T("*MESH_TVERT")
#define ASE_MESH_TFACELIST _T("*MESH_TFACELIST")
#define ASE_MESH_TFACE _T("*MESH_TFACE")
#define ASE_MESH_NUMCVERTEX _T("*MESH_NUMCVERTEX")
#define ASE_MESH_NUMCVFACES _T("*MESH_NUMCVFACES")
#define ASE_MESH_CVERTLIST _T("*MESH_CVERTLIST")
#define ASE_MESH_VERTCOL _T("*MESH_VERTCOL")
#define ASE_MESH_CFACELIST _T("*MESH_CFACELIST")
#define ASE_MESH_CFACE _T("*MESH_CFACE")
// New for R3 - indicates a block with new map channel information
#define ASE_MESH_MAPPINGCHANNEL _T("*MESH_MAPPINGCHANNEL")
// End new
#define ASE_MESH_FACEMAPLIST _T("*MESH_FACEMAPLIST")
#define ASE_MESH_FACEMAP _T("*MESH_FACEMAP")
#define ASE_MESH_FACEVERT _T("*MESH_FACEMAPVERT")
#define ASE_MESH_FACENORMAL _T("*MESH_FACENORMAL")
#define ASE_MESH_VERTEXNORMAL _T("*MESH_VERTEXNORMAL")
#define ASE_MESH_ANIMATION _T("*MESH_ANIMATION")
// Shape ID's
#define ASE_SHAPE_LINECOUNT _T("*SHAPE_LINECOUNT")
#define ASE_SHAPE_LINE _T("*SHAPE_LINE")
#define ASE_SHAPE_VERTEX_KNOT _T("*SHAPE_VERTEX_KNOT")
#define ASE_SHAPE_VERTEX_INTERP _T("*SHAPE_VERTEX_INTERP")
#define ASE_SHAPE_VERTEXCOUNT _T("*SHAPE_VERTEXCOUNT")
#define ASE_SHAPE_CLOSED _T("*SHAPE_CLOSED")
// Light ID's
#define ASE_LIGHT_SETTINGS _T("*LIGHT_SETTINGS")
#define ASE_LIGHT_TYPE _T("*LIGHT_TYPE")
#define ASE_LIGHT_COLOR _T("*LIGHT_COLOR")
#define ASE_LIGHT_INTENS _T("*LIGHT_INTENS")
#define ASE_LIGHT_HOTSPOT _T("*LIGHT_HOTSPOT")
#define ASE_LIGHT_FALLOFF _T("*LIGHT_FALLOFF")
#define ASE_LIGHT_ATTNSTART _T("*LIGHT_ATTNSTART")
#define ASE_LIGHT_ATTNEND _T("*LIGHT_ATTNEND")
#define ASE_LIGHT_ASPECT _T("*LIGHT_ASPECT")
#define ASE_LIGHT_SHADOWS _T("*LIGHT_SHADOWS")
#define ASE_LIGHT_USELIGHT _T("*LIGHT_USELIGHT")
#define ASE_LIGHT_SPOTSHAPE _T("*LIGHT_SPOTSHAPE")
#define ASE_LIGHT_TDIST _T("*LIGHT_TDIST")
#define ASE_LIGHT_MAPBIAS _T("*LIGHT_MAPBIAS")
#define ASE_LIGHT_MAPRANGE _T("*LIGHT_MAPRANGE")
#define ASE_LIGHT_MAPSIZE _T("*LIGHT_MAPSIZE")
#define ASE_LIGHT_RAYBIAS _T("*LIGHT_RAYBIAS")
#define ASE_LIGHT_USEGLOBAL _T("*LIGHT_USEGLOBAL")
#define ASE_LIGHT_ABSMAPBIAS _T("*LIGHT_ABSMAPBIAS")
#define ASE_LIGHT_OVERSHOOT _T("*LIGHT_OVERSHOOT")
#define ASE_LIGHT_EXCLUSIONLIST _T("*LIGHT_EXCLUDELIST")
#define ASE_LIGHT_NUMEXCLUDED _T("*LIGHT_NUMEXCLUDED")
#define ASE_LIGHT_EXCLUDED _T("*LIGHT_EXCLUDED")
#define ASE_LIGHT_EXCLINCLUDE _T("*LIGHT_EXCLUDED_INCLUDE")
#define ASE_LIGHT_EXCL_AFFECT_ILLUM _T("*LIGHT_EXCLUDED_AFFECT_ILLUM")
#define ASE_LIGHT_EXCL_AFFECT_SHAD _T("*LIGHT_EXCLUDED_AFFECT_SHADOW")
#define ASE_LIGHT_ANIMATION _T("*LIGHT_ANIMATION")
#define ASE_LIGHT_TYPE_OMNI _T("Omni")
#define ASE_LIGHT_TYPE_TARG _T("Target")
#define ASE_LIGHT_TYPE_DIR _T("Directional")
#define ASE_LIGHT_TYPE_FREE _T("Free")
#define ASE_LIGHT_SHAD_OFF _T("Off")
#define ASE_LIGHT_SHAD_MAP _T("Mapped")
#define ASE_LIGHT_SHAD_RAY _T("Raytraced")
#define ASE_LIGHT_SHAPE_CIRC _T("Circle")
#define ASE_LIGHT_SHAPE_RECT _T("Rect")
// Camera ID's
#define ASE_CAMERA_SETTINGS _T("*CAMERA_SETTINGS")
#define ASE_CAMERA_HITHER _T("*CAMERA_HITHER")
#define ASE_CAMERA_YON _T("*CAMERA_YON")
#define ASE_CAMERA_NEAR _T("*CAMERA_NEAR")
#define ASE_CAMERA_FAR _T("*CAMERA_FAR")
#define ASE_CAMERA_FOV _T("*CAMERA_FOV")
#define ASE_CAMERA_TDIST _T("*CAMERA_TDIST")
#define ASE_CAMERA_ANIMATION _T("*CAMERA_ANIMATION")
#define ASE_CAMERA_TYPE _T("*CAMERA_TYPE")
#define ASE_CAMERATYPE_TARGET _T("Target")
#define ASE_CAMERATYPE_FREE _T("Free")
// Helper objects
#define ASE_HELPER_CLASS _T("*HELPER_CLASS")
// Controller ID's
#define ASE_CONTROL_POINT3_TCB _T("*CONTROL_POINT3_TCB")
#define ASE_CONTROL_POINT3_BEZIER _T("*CONTROL_POINT3_BEZIER")
#define ASE_CONTROL_COLOR_BEZIER _T("*CONTROL_COLOR_BEZIER")
#define ASE_CONTROL_POINT3_SAMPLE _T("*CONTROL_POINT3_SAMPLE")
#define ASE_CONTROL_FLOAT_TCB _T("*CONTROL_FLOAT_TCB")
#define ASE_CONTROL_FLOAT_BEZIER _T("*CONTROL_FLOAT_BEZIER")
#define ASE_CONTROL_FLOAT_LINEAR _T("*CONTROL_FLOAT_LINEAR")
#define ASE_CONTROL_FLOAT_SAMPLE _T("*CONTROL_FLOAT_SAMPLE")
// "Track" is the identification of a sampled controller
#define ASE_POS_TRACK _T("*CONTROL_POS_TRACK")
#define ASE_ROT_TRACK _T("*CONTROL_ROT_TRACK")
#define ASE_SCALE_TRACK _T("*CONTROL_SCALE_TRACK")
// Sampled keys
#define ASE_POS_SAMPLE _T("*CONTROL_POS_SAMPLE")
#define ASE_ROT_SAMPLE _T("*CONTROL_ROT_SAMPLE")
#define ASE_SCALE_SAMPLE _T("*CONTROL_SCALE_SAMPLE")
// Specific controller keys
#define ASE_POS_KEY _T("*CONTROL_POS_KEY")
#define ASE_ROT_KEY _T("*CONTROL_ROT_KEY")
#define ASE_SCALE_KEY _T("*CONTROL_SCALE_KEY")
#define ASE_POINT3_KEY _T("*CONTROL_POINT3_KEY")
#define ASE_FLOAT_KEY _T("*CONTROL_FLOAT_KEY")
// TCB Keys have Tens, cont, bias, easeIn, easeOut
#define ASE_TCB_POINT3_KEY _T("*CONTROL_TCB_POINT3_KEY")
#define ASE_TCB_FLOAT_KEY _T("*CONTROL_TCB_FLOAT_KEY")
#define ASE_TCB_POS_KEY _T("*CONTROL_TCB_POS_KEY")
#define ASE_TCB_ROT_KEY _T("*CONTROL_TCB_ROT_KEY")
#define ASE_TCB_SCALE_KEY _T("*CONTROL_TCB_SCALE_KEY")
// Bezier keys have inTan, outTan
#define ASE_BEZIER_FLOAT_KEY _T("*CONTROL_BEZIER_FLOAT_KEY")
#define ASE_BEZIER_POINT3_KEY _T("*CONTROL_BEZIER_POINT3_KEY")
#define ASE_BEZIER_POS_KEY _T("*CONTROL_BEZIER_POS_KEY")
#define ASE_BEZIER_SCALE_KEY _T("*CONTROL_BEZIER_SCALE_KEY")
#define ASE_CONTROL_POS_LINEAR _T("*CONTROL_POS_LINEAR")
#define ASE_CONTROL_POS_TCB _T("*CONTROL_POS_TCB")
#define ASE_CONTROL_POS_BEZIER _T("*CONTROL_POS_BEZIER")
#define ASE_CONTROL_ROT_LINEAR _T("*CONTROL_ROT_LINEAR")
#define ASE_CONTROL_ROT_TCB _T("*CONTROL_ROT_TCB")
#define ASE_CONTROL_ROT_BEZIER _T("*CONTROL_ROT_BEZIER")
#define ASE_CONTROL_SCALE_LINEAR _T("*CONTROL_SCALE_LINEAR")
#define ASE_CONTROL_SCALE_TCB _T("*CONTROL_SCALE_TCB")
#define ASE_CONTROL_SCALE_BEZIER _T("*CONTROL_SCALE_BEZIER")
// IK Node Info
#define ASE_IKTERMINATOR _T("*IK_TERMINATOR")
#define ASE_IKROT_PINNED _T("*IK_ROT_PINNED")
#define ASE_IKPOS_PINNED _T("*IK_POS_PINNED")
// IK Joints
#define ASE_IKJOINT _T("*IK_JOINT")
#define ASE_IKTYPE _T("*IK_TYPE")
#define ASE_IKDOF _T("*IK_DOF")
#define ASE_IKXACTIVE _T("*IK_XACTIVE")
#define ASE_IKYACTIVE _T("*IK_YACTIVE")
#define ASE_IKZACTIVE _T("*IK_ZACTIVE")
#define ASE_IKXLIMITED _T("*IK_XLIMITED")
#define ASE_IKYLIMITED _T("*IK_YLIMITED")
#define ASE_IKZLIMITED _T("*IK_ZLIMITED")
#define ASE_IKXEASE _T("*IK_XEASE")
#define ASE_IKYEASE _T("*IK_YEASE")
#define ASE_IKZEASE _T("*IK_ZEASE")
#define ASE_IKLIMITEXACT _T("*IK_LIMITEXACT")
#define ASE_IKJOINTINFO _T("*IK_JOINTINFO")
#define ASE_IKTYPEPOS _T("Position")
#define ASE_IKTYPEROT _T("Rotation")
// Material / Texture related ID's
#define ASE_WIRECOLOR _T("*WIREFRAME_COLOR")
#define ASE_MATERIAL _T("*MATERIAL")
#define ASE_MATERIAL_COUNT _T("*MATERIAL_COUNT")
#define ASE_MATERIAL_REF _T("*MATERIAL_REF")
#define ASE_NUMSUBMTLS _T("*NUMSUBMTLS")
#define ASE_SUBMATERIAL _T("*SUBMATERIAL")
#define ASE_MATNAME _T("*MATERIAL_NAME")
#define ASE_MATCLASS _T("*MATERIAL_CLASS")
#define ASE_MAT_SHADE_CONST _T("Constant")
#define ASE_MAT_SHADE_PHONG _T("Phong")
#define ASE_MAT_SHADE_METAL _T("Metal")
#define ASE_MAT_SHADE_BLINN _T("Blinn")
#define ASE_MAT_SHADE_OTHER _T("Other")
#define ASE_MAP_XPTYPE_FLT _T("Filter")
#define ASE_MAP_XPTYPE_SUB _T("Subtractive")
#define ASE_MAP_XPTYPE_ADD _T("Additive")
#define ASE_MAP_XPTYPE_OTH _T("Other")
#define ASE_BMP_FILT_PYR _T("Pyramidal")
#define ASE_BMP_FILT_SAT _T("SAT")
#define ASE_BMP_FILT_NONE _T("None")
#define ASE_FALLOFF_OUT _T("Out")
#define ASE_FALLOFF_IN _T("In")
#define ASE_MAPTYPE_EXP _T("Explicit")
#define ASE_MAPTYPE_SPH _T("Spherical")
#define ASE_MAPTYPE_CYL _T("Cylindrical")
#define ASE_MAPTYPE_SHR _T("Shrinkwrap")
#define ASE_MAPTYPE_SCR _T("Screen")
#define ASE_AMBIENT _T("*MATERIAL_AMBIENT")
#define ASE_DIFFUSE _T("*MATERIAL_DIFFUSE")
#define ASE_SPECULAR _T("*MATERIAL_SPECULAR")
#define ASE_SHINE _T("*MATERIAL_SHINE")
#define ASE_SHINE_STRENGTH _T("*MATERIAL_SHINESTRENGTH")
#define ASE_TRANSPARENCY _T("*MATERIAL_TRANSPARENCY")
#define ASE_WIRESIZE _T("*MATERIAL_WIRESIZE")
#define ASE_SHADING _T("*MATERIAL_SHADING")
#define ASE_XP_FALLOFF _T("*MATERIAL_XP_FALLOFF")
#define ASE_SELFILLUM _T("*MATERIAL_SELFILLUM")
#define ASE_TWOSIDED _T("*MATERIAL_TWOSIDED")
#define ASE_WIRE _T("*MATERIAL_WIRE")
#define ASE_WIREUNITS _T("*MATERIAL_WIREUNITS")
#define ASE_FALLOFF _T("*MATERIAL_FALLOFF")
#define ASE_FACEMAP _T("*MATERIAL_FACEMAP")
#define ASE_SOFTEN _T("*MATERIAL_SOFTEN")
#define ASE_XP_TYPE _T("*MATERIAL_XP_TYPE")
#define ASE_TEXNAME _T("*MAP_NAME")
#define ASE_TEXCLASS _T("*MAP_CLASS")
#define ASE_TEXSUBNO _T("*MAP_SUBNO")
#define ASE_TEXAMOUNT _T("*MAP_AMOUNT")
#define ASE_BITMAP _T("*BITMAP")
#define ASE_TEX_INVERT _T("*BITMAP_INVERT")
#define ASE_BMP_FILTER _T("*BITMAP_FILTER")
#define ASE_MAPTYPE _T("*MAP_TYPE")
#define ASE_U_OFFSET _T("*UVW_U_OFFSET")
#define ASE_V_OFFSET _T("*UVW_V_OFFSET")
#define ASE_U_TILING _T("*UVW_U_TILING")
#define ASE_V_TILING _T("*UVW_V_TILING")
#define ASE_ANGLE _T("*UVW_ANGLE")
#define ASE_BLUR _T("*UVW_BLUR")
#define ASE_BLUR_OFFSET _T("*UVW_BLUR_OFFSET")
#define ASE_NOISE_AMT _T("*UVW_NOUSE_AMT")
#define ASE_NOISE_SIZE _T("*UVW_NOISE_SIZE")
#define ASE_NOISE_LEVEL _T("*UVW_NOISE_LEVEL")
#define ASE_NOISE_PHASE _T("*UVW_NOISE_PHASE")
// Sub texture types
#define ASE_MAP_GENERIC _T("*MAP_GENERIC")
#define ASE_MAP_AMBIENT _T("*MAP_AMBIENT")
#define ASE_MAP_DIFFUSE _T("*MAP_DIFFUSE")
#define ASE_MAP_SPECULAR _T("*MAP_SPECULAR")
#define ASE_MAP_SHINE _T("*MAP_SHINE")
#define ASE_MAP_SHINESTRENGTH _T("*MAP_SHINESTRENGTH")
#define ASE_MAP_SELFILLUM _T("*MAP_SELFILLUM")
#define ASE_MAP_OPACITY _T("*MAP_OPACITY")
#define ASE_MAP_FILTERCOLOR _T("*MAP_FILTERCOLOR")
#define ASE_MAP_BUMP _T("*MAP_BUMP")
#define ASE_MAP_REFLECT _T("*MAP_REFLECT")
#define ASE_MAP_REFRACT _T("*MAP_REFRACT")
// TM related ID's
#define ASE_TM_ROW0 _T("*TM_ROW0")
#define ASE_TM_ROW1 _T("*TM_ROW1")
#define ASE_TM_ROW2 _T("*TM_ROW2")
#define ASE_TM_ROW3 _T("*TM_ROW3")
#define ASE_TM_POS _T("*TM_POS")
#define ASE_TM_ROTAXIS _T("*TM_ROTAXIS")
#define ASE_TM_ROTANGLE _T("*TM_ROTANGLE")
#define ASE_TM_SCALE _T("*TM_SCALE")
#define ASE_TM_SCALEAXIS _T("*TM_SCALEAXIS")
#define ASE_TM_SCALEAXISANG _T("*TM_SCALEAXISANG")
#define ASE_TM_ANIMATION _T("*TM_ANIMATION")
// TM Inheritance flags
#define ASE_INHERIT_POS _T("*INHERIT_POS")
#define ASE_INHERIT_ROT _T("*INHERIT_ROT")
#define ASE_INHERIT_SCL _T("*INHERIT_SCL")
// Scene related ID's
#define ASE_FILENAME _T("*SCENE_FILENAME")
#define ASE_FIRSTFRAME _T("*SCENE_FIRSTFRAME")
#define ASE_LASTFRAME _T("*SCENE_LASTFRAME")
#define ASE_FRAMESPEED _T("*SCENE_FRAMESPEED")
#define ASE_TICKSPERFRAME _T("*SCENE_TICKSPERFRAME")
#define ASE_ENVMAP _T("*SCENE_ENVMAP")
#define ASE_STATICBGCOLOR _T("*SCENE_BACKGROUND_STATIC")
#define ASE_ANIMBGCOLOR _T("*SCENE_BACKGROUND_ANIM")
#define ASE_STATICAMBIENT _T("*SCENE_AMBIENT_STATIC")
#define ASE_ANIMAMBIENT _T("*SCENE_AMBIENT_ANIM")
#define ASE_VISIBILITY_TRACK _T("*NODE_VISIBILITY_TRACK")
// Generic ID's that can show up here and there
#define ASE_TIMEVALUE _T("*TIMEVALUE")
#define ASE_COMMENT _T("*COMMENT")
#define ASE_FILEID _T("*3DSMAX_ASCIIEXPORT")
#define ASE_BOUNDINGBOX_MIN _T("*BOUNDINGBOX_MIN")
#define ASE_BOUNDINGBOX_MAX _T("*BOUNDINGBOX_MAX")
#endif // __ASETokens_h__

144
Editor/BaseLibrary.cpp Normal file
View File

@@ -0,0 +1,144 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: baselibrary.cpp
// Version: v1.00
// Created: 22/1/2003 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "BaseLibrary.h"
#include "BaseLibraryItem.h"
#include "BaseLibraryManager.h"
//////////////////////////////////////////////////////////////////////////
// CBaseLibrary implementation.
//////////////////////////////////////////////////////////////////////////
CBaseLibrary::CBaseLibrary( CBaseLibraryManager *pManager )
{
m_pManager = pManager;
m_bModified = false;
m_bLevelLib = false;
}
//////////////////////////////////////////////////////////////////////////
CBaseLibrary::~CBaseLibrary()
{
m_items.clear();
}
//////////////////////////////////////////////////////////////////////////
IDataBaseManager* CBaseLibrary::GetManager()
{
return m_pManager;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibrary::RemoveAllItems()
{
AddRef();
for (int i = 0; i < m_items.size(); i++)
{
// Clear library item.
m_items[i]->m_library = NULL;
}
m_items.clear();
Release();
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibrary::SetName( const CString &name )
{
m_name = name;
/*
// Make a file name from name of library.
CString path = Path::GetPath( m_filename );
m_filename = m_name;
m_filename.Replace( ' ','_' );
m_filename = path + m_filename + ".xml";
*/
SetModified();
}
//////////////////////////////////////////////////////////////////////////
const CString& CBaseLibrary::GetName() const
{
return m_name;
}
//////////////////////////////////////////////////////////////////////////
bool CBaseLibrary::Save()
{
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CBaseLibrary::Load( const CString &filename )
{
m_filename = filename;
SetModified(false);
return true;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibrary::SetModified( bool bModified )
{
m_bModified = bModified;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void CBaseLibrary::AddItem( IDataBaseItem* item )
{
CBaseLibraryItem *pLibItem = (CBaseLibraryItem*)item;
// Check if item is already assigned to this library.
if (pLibItem->m_library != this)
{
pLibItem->m_library = this;
m_items.push_back( pLibItem );
SetModified();
m_pManager->RegisterItem( pLibItem );
}
}
//////////////////////////////////////////////////////////////////////////
IDataBaseItem* CBaseLibrary::GetItem( int index )
{
assert( index >= 0 && index < m_items.size() );
return m_items[index];
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibrary::RemoveItem( IDataBaseItem* item )
{
for (int i = 0; i < m_items.size(); i++)
{
if (m_items[i] == item)
{
m_items.erase( m_items.begin()+i );
SetModified();
break;
}
}
}
//////////////////////////////////////////////////////////////////////////
IDataBaseItem* CBaseLibrary::FindItem( const CString &name )
{
for (int i = 0; i < m_items.size(); i++)
{
if (stricmp(m_items[i]->GetName(),name) == 0)
{
return m_items[i];
}
}
return NULL;
}

100
Editor/BaseLibrary.h Normal file
View File

@@ -0,0 +1,100 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: baselibrary.h
// Version: v1.00
// Created: 22/1/2003 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __baselibrary_h__
#define __baselibrary_h__
#pragma once
#include "IDataBaseLibrary.h"
class CBaseLibraryManager;
/** This a base class for all Libraries used by Editor.
*/
class CBaseLibrary : public TRefCountBase<IDataBaseLibrary>
{
public:
CBaseLibrary( CBaseLibraryManager *pManager );
~CBaseLibrary();
//! Set library name.
virtual void SetName( const CString &name );
//! Get library name.
const CString& GetName() const;
//! Set new filename for this library.
void SetFilename( const CString &filename ) { m_filename = filename; };
const CString& GetFilename() const { return m_filename; };
virtual bool Save() = 0;
virtual bool Load( const CString &filename ) = 0;
virtual void Serialize( XmlNodeRef &node,bool bLoading ) = 0;
//! Mark library as modified.
void SetModified( bool bModified=true );
//! Check if library was modified.
bool IsModified() const { return m_bModified; };
//////////////////////////////////////////////////////////////////////////
// Working with items.
//////////////////////////////////////////////////////////////////////////
//! Add a new prototype to library.
void AddItem( IDataBaseItem* item );
//! Get number of known prototypes.
int GetItemCount() const { return m_items.size(); }
//! Get prototype by index.
IDataBaseItem* GetItem( int index );
//! Delete item by pointer of item.
void RemoveItem( IDataBaseItem* item );
//! Delete all items from library.
void RemoveAllItems();
//! Find library item by name.
//! Using linear search.
IDataBaseItem* FindItem( const CString &name );
//! Check if this library is local level library.
bool IsLevelLibrary() const { return m_bLevelLib; };
//! Set library to be level library.
void SetLevelLibrary( bool bEnable ) { m_bLevelLib = bEnable; };
//////////////////////////////////////////////////////////////////////////
//! Return manager for this library.
IDataBaseManager* GetManager();
private:
//! Name of the library.
CString m_name;
//! Filename of the library.
CString m_filename;
//! Flag set when library was modified.
bool m_bModified;
//! Level library is saved within the level .cry file and is local for this level.
bool m_bLevelLib;
//////////////////////////////////////////////////////////////////////////
// Manager.
CBaseLibraryManager *m_pManager;
// Array of all our library items.
std::vector<TSmartPtr<CBaseLibraryItem> > m_items;
};
#endif // __baselibrary_h__

View File

@@ -0,0 +1,667 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: entityprotlibdialog.cpp
// Version: v1.00
// Created: 22/1/2003 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "BaseLibraryDialog.h"
#include "StringDlg.h"
//#include "BaseLibraryItemManager.h"
#include "BaseLibrary.h"
#include "BaseLibraryItem.h"
#include "BaseLibraryManager.h"
//#include "SelectEntityClsDialog.h"
#include "Clipboard.h"
#include "ErrorReport.h"
#include <IEntitySystem.h>
#include <EntityDesc.h>
#define IDC_LIBRARY_ITEMS_TREE AFX_IDW_PANE_FIRST
IMPLEMENT_DYNAMIC(CBaseLibraryDialog,CToolbarDialog)
//////////////////////////////////////////////////////////////////////////
// CBaseLibraryDialog implementation.
//////////////////////////////////////////////////////////////////////////
CBaseLibraryDialog::CBaseLibraryDialog( UINT nID,CWnd *pParent )
: CToolbarDialog(nID, pParent)
{
// Register as doc listener.
GetIEditor()->RegisterDocListener(this);
m_bIgnoreSelectionChange = false;
m_pItemManager = 0;
// Load cusrors.
m_hCursorDefault = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
m_hCursorNoDrop = AfxGetApp()->LoadCursor(IDC_NODROP);
m_hCursorCreate = AfxGetApp()->LoadCursor(IDC_HIT_CURSOR);
m_hCursorReplace = AfxGetApp()->LoadCursor(IDC_HAND_INTERNAL);
m_bLibsLoaded = false;
}
CBaseLibraryDialog::~CBaseLibraryDialog()
{
}
void CBaseLibraryDialog::DoDataExchange(CDataExchange* pDX)
{
CToolbarDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CBaseLibraryDialog, CToolbarDialog)
ON_COMMAND( ID_DB_ADDLIB,OnAddLibrary )
ON_COMMAND( ID_DB_DELLIB,OnRemoveLibrary )
ON_COMMAND( ID_DB_REMOVE,OnRemoveItem )
ON_COMMAND( ID_DB_RENAME,OnRenameItem )
ON_COMMAND( ID_DB_SAVE,OnSave )
ON_COMMAND( ID_DB_EXPORTLIBRARY,OnExportLibrary )
ON_COMMAND( ID_DB_LOADLIB,OnLoadLibrary )
ON_COMMAND( ID_DB_RELOAD,OnReloadLib )
ON_CBN_SELENDOK( ID_DB_LIBRARY,OnChangedLibrary )
ON_NOTIFY(TVN_SELCHANGED, IDC_LIBRARY_ITEMS_TREE, OnSelChangedItemTree)
ON_NOTIFY(TVN_KEYDOWN, IDC_LIBRARY_ITEMS_TREE, OnKeyDownItemTree)
ON_COMMAND( ID_DB_CUT,OnCut )
ON_COMMAND( ID_DB_COPY,OnCopy )
ON_COMMAND( ID_DB_PASTE,OnPaste )
ON_COMMAND( ID_DB_CLONE,OnClone )
ON_UPDATE_COMMAND_UI( ID_DB_COPY,OnUpdateSelected )
ON_UPDATE_COMMAND_UI( ID_DB_CUT,OnUpdateSelected )
ON_UPDATE_COMMAND_UI( ID_DB_CLONE,OnUpdateSelected )
ON_UPDATE_COMMAND_UI( ID_DB_PASTE,OnUpdatePaste )
ON_WM_SIZE()
ON_WM_DESTROY()
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnDestroy()
{
SelectItem( 0 );
m_pLibrary = 0;
m_pCurrentItem = 0;
m_itemsToTree.clear();
// Unregister listener from document.
GetIEditor()->UnregisterDocListener(this);
CToolbarDialog::OnDestroy();
}
// CTVSelectKeyDialog message handlers
BOOL CBaseLibraryDialog::OnInitDialog()
{
CToolbarDialog::OnInitDialog();
CRect rc;
// Attach it to the control
m_treeCtrl.Create( WS_VISIBLE|WS_CHILD|WS_TABSTOP|WS_BORDER|TVS_HASBUTTONS|TVS_SHOWSELALWAYS|
TVS_LINESATROOT|TVS_HASLINES|TVS_FULLROWSELECT,rc,this,IDC_LIBRARY_ITEMS_TREE );
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
//////////////////////////////////////////////////////////////////////////
// Create the toolbar
void CBaseLibraryDialog::InitToolbar()
{
// Tool bar must be already created in derived class.
ASSERT( m_toolbar.m_hWnd );
// Resize the toolbar
CRect rc;
GetClientRect(rc);
m_toolbar.SetWindowPos(NULL, 0, 0, rc.right, 70, SWP_NOZORDER);
CSize sz = m_toolbar.CalcDynamicLayout(TRUE,TRUE);
//////////////////////////////////////////////////////////////////////////
int index;
index = m_toolbar.CommandToIndex(ID_DB_LIBRARY);
if (index >= 0)
{
m_toolbar.SetButtonInfo(index,ID_DB_LIBRARY, TBBS_SEPARATOR, 150);
m_toolbar.GetItemRect(index,&rc);
rc.top++;
rc.bottom += 400;
}
m_libraryCtrl.Create( WS_CHILD|WS_VISIBLE|WS_TABSTOP|CBS_DROPDOWNLIST|CBS_SORT,rc,this,ID_DB_LIBRARY );
m_libraryCtrl.SetParent( &m_toolbar );
m_libraryCtrl.SetFont( CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT)) );
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnSize(UINT nType, int cx, int cy)
{
CToolbarDialog::OnSize(nType, cx, cy);
// resize splitter window.
if (m_toolbar.m_hWnd)
{
CRect rc;
GetClientRect(rc);
m_toolbar.SetWindowPos(NULL, 0, 0, rc.right, 70, SWP_NOZORDER);
}
RecalcLayout();
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnNewDocument()
{
m_bLibsLoaded = false;
// Clear all prototypes and libraries.
SelectItem(0);
m_libraryCtrl.ResetContent();
m_selectedLib = "";
};
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnLoadDocument()
{
m_bLibsLoaded = false;
ReloadLibs();
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnCloseDocument()
{
m_bLibsLoaded = false;
SelectLibrary( "" );
SelectItem( 0 );
}
//////////////////////////////////////////////////////////////////////////
CBaseLibrary* CBaseLibraryDialog::FindLibrary( const CString &libraryName )
{
return (CBaseLibrary*)m_pItemManager->FindLibrary( libraryName );
}
CBaseLibrary* CBaseLibraryDialog::NewLibrary( const CString &libraryName )
{
return (CBaseLibrary*)m_pItemManager->AddLibrary( libraryName );
}
void CBaseLibraryDialog::DeleteLibrary( CBaseLibrary *pLibrary )
{
m_pItemManager->DeleteLibrary( pLibrary->GetName() );
}
void CBaseLibraryDialog::DeleteItem( CBaseLibraryItem *pItem )
{
m_pItemManager->DeleteItem( pItem );
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::ReloadLibs()
{
SelectItem(0);
CString selectedLib;
m_libraryCtrl.ResetContent();
bool bFound = false;
for (int i = 0; i < m_pItemManager->GetLibraryCount(); i++)
{
CString library = m_pItemManager->GetLibrary(i)->GetName();
if (selectedLib.IsEmpty())
selectedLib = library;
m_libraryCtrl.AddString( library );
}
m_selectedLib = "";
SelectLibrary( selectedLib );
m_bLibsLoaded = true;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::ReloadItems()
{
m_bIgnoreSelectionChange = true;
m_treeCtrl.SetRedraw(FALSE);
m_selectedGroup = "";
m_pCurrentItem = 0;
m_itemsToTree.clear();
m_treeCtrl.DeleteAllItems();
m_bIgnoreSelectionChange = false;
if (!m_pLibrary)
{
m_treeCtrl.SetRedraw(TRUE);
return;
}
m_bIgnoreSelectionChange = true;
std::map<CString,HTREEITEM> groupMap;
//HTREEITEM hLibItem = m_treeCtrl.InsertItem( m_selectedLib,0,0 );
HTREEITEM hLibItem = TVI_ROOT;
for (int i = 0; i < m_pLibrary->GetItemCount(); i++)
{
CBaseLibraryItem *pItem = (CBaseLibraryItem*)m_pLibrary->GetItem(i);
CString group = pItem->GetGroupName();
CString name = pItem->GetShortName();
HTREEITEM hGroupItem = hLibItem;
if (!group.IsEmpty())
{
hGroupItem = stl::find_in_map( groupMap,group,(HTREEITEM)0 );
if (!hGroupItem)
{
hGroupItem = m_treeCtrl.InsertItem( group,0,1,hLibItem );
//m_treeCtrl.Expand( hGroupItem,TVE_EXPAND );
groupMap[group] = hGroupItem;
}
}
InsertItemToTree( pItem,hGroupItem );
}
m_treeCtrl.SortChildren( hLibItem );
m_treeCtrl.Expand( hLibItem,TVE_EXPAND );
m_treeCtrl.SetRedraw(TRUE);
m_bIgnoreSelectionChange = false;
}
//////////////////////////////////////////////////////////////////////////
HTREEITEM CBaseLibraryDialog::InsertItemToTree( CBaseLibraryItem *pItem,HTREEITEM hParent )
{
assert( pItem );
HTREEITEM hItem = m_treeCtrl.InsertItem( pItem->GetShortName(),2,3,hParent );
//m_treeCtrl.SetItemState( hItem, TVIS_BOLD,TVIS_BOLD );
m_treeCtrl.SetItemData( hItem,(DWORD_PTR)pItem );
m_itemsToTree[pItem] = hItem;
return hItem;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::SelectLibrary( const CString &library )
{
CWaitCursor wait;
if (m_selectedLib != library)
{
SelectItem(0);
m_pLibrary = FindLibrary( library );
if (m_pLibrary)
{
m_selectedLib = library;
}
else
{
m_selectedLib = "";
}
ReloadItems();
}
m_libraryCtrl.SelectString( -1,m_selectedLib );
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnChangedLibrary()
{
CString library;
m_libraryCtrl.GetWindowText(library);
if (library != m_selectedLib)
{
SelectLibrary( library );
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnAddLibrary()
{
CStringDlg dlg( _T("New Library Name"),this );
if (dlg.DoModal() == IDOK)
{
if (!dlg.GetString().IsEmpty())
{
SelectItem(0);
// Make new library.
CString library = dlg.GetString();
NewLibrary( library );
ReloadLibs();
SelectLibrary( library );
GetIEditor()->SetModifiedFlag();
}
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnExportLibrary()
{
if (!m_pLibrary)
return;
CString filename;
if (CFileUtil::SelectSaveFile( "Library Files (*.xml)|*.xml","xml","Materials",filename ))
{
XmlNodeRef libNode = new CXmlNode( "MaterialLibrary" );
m_pLibrary->Serialize( libNode,false );
libNode->saveToFile( filename );
}
}
void CBaseLibraryDialog::SetItemName( CBaseLibraryItem *item,const CString &groupName,const CString &itemName )
{
assert( item );
// Make prototype name.
CString name;
if (!groupName.IsEmpty())
name = groupName + ".";
name += itemName;
CString fullName = item->GetLibrary()->GetName() + "." + name;
IDataBaseItem *pOtherItem = m_pItemManager->FindItemByName( fullName );
if (pOtherItem && pOtherItem != item)
{
// Ensure uniqness of name.
Warning( "Duplicate Item Name %s",(const char*)name );
}
else
{
item->SetName( name );
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnAddItem()
{
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnRemoveItem()
{
if (m_pCurrentItem)
{
// Remove prototype from prototype manager and library.
CString str;
str.Format( _T("Delete %s?"),(const char*)m_pCurrentItem->GetName() );
if (MessageBox(str,_T("Delete Confirmation"),MB_YESNO|MB_ICONQUESTION) == IDYES)
{
TSmartPtr<CBaseLibraryItem> pCurrent = m_pCurrentItem;
DeleteItem( pCurrent );
HTREEITEM hItem = stl::find_in_map( m_itemsToTree,pCurrent,(HTREEITEM)0 );
if (hItem)
{
m_treeCtrl.DeleteItem( hItem );
m_itemsToTree.erase( pCurrent );
}
GetIEditor()->SetModifiedFlag();
}
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnRenameItem()
{
if (m_pCurrentItem)
{
CStringGroupDlg dlg;
dlg.SetGroup( m_pCurrentItem->GetGroupName() );
dlg.SetString( m_pCurrentItem->GetShortName() );
if (dlg.DoModal() == IDOK)
{
TSmartPtr<CBaseLibraryItem> curItem = m_pCurrentItem;
SetItemName( curItem,dlg.GetGroup(),dlg.GetString() );
ReloadItems();
SelectItem( curItem,true );
//m_pCurrentItem->Update();
}
GetIEditor()->SetModifiedFlag();
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnRemoveLibrary()
{
CString library = m_selectedLib;
if (library.IsEmpty())
return;
if (m_pLibrary->IsModified())
{
CString ask;
ask.Format( "Save changes to the library %s?",(const char*)library );
if (AfxMessageBox( ask,MB_YESNO|MB_ICONQUESTION ) == IDYES)
{
OnSave();
}
}
CString ask;
ask.Format( "When removing library All items contained in this library will be deleted.\r\nAre you sure you want to remove libarary %s?\r\n(Note: Library file will not be deleted from the disk)",(const char*)library );
if (AfxMessageBox( ask,MB_YESNO|MB_ICONQUESTION ) == IDYES)
{
SelectItem(0);
DeleteLibrary( m_pLibrary );
m_selectedLib = "";
m_pLibrary = 0;
ReloadLibs();
GetIEditor()->SetModifiedFlag();
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnSelChangedItemTree(NMHDR* pNMHDR, LRESULT* pResult)
{
if (m_bIgnoreSelectionChange)
return;
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
m_pCurrentItem = 0;
if (m_treeCtrl)
{
HTREEITEM hItem = pNMTreeView->itemNew.hItem;
if (hItem != 0 && hItem != TVI_ROOT)
{
// Change currently selected item.
CBaseLibraryItem *prot = (CBaseLibraryItem*)m_treeCtrl.GetItemData(hItem);
if (prot)
{
SelectItem( prot );
}
else
{
SelectItem( 0 );
m_selectedGroup = m_treeCtrl.GetItemText(hItem);
}
}
else
{
SelectItem(0);
}
}
*pResult = 0;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnKeyDownItemTree(NMHDR* pNMHDR, LRESULT* pResult)
{
GetAsyncKeyState(VK_CONTROL);
bool bCtrl = GetAsyncKeyState(VK_CONTROL) != 0;
// Key press in items tree view.
NMTVKEYDOWN *nm = (NMTVKEYDOWN*)pNMHDR;
if (bCtrl && (nm->wVKey == 'c' || nm->wVKey == 'C'))
{
OnCopy(); // Ctrl+C
}
if (bCtrl && (nm->wVKey == 'v' || nm->wVKey == 'V'))
{
OnPaste(); // Ctrl+V
}
if (bCtrl && (nm->wVKey == 'x' || nm->wVKey == 'X'))
{
OnCut(); // Ctrl+X
}
if (bCtrl && (nm->wVKey == 'd' || nm->wVKey == 'D'))
{
OnClone(); // Ctrl+D
}
if (nm->wVKey == VK_DELETE)
{
OnRemoveItem();
}
if (nm->wVKey == VK_INSERT)
{
OnAddItem();
}
}
//////////////////////////////////////////////////////////////////////////
bool CBaseLibraryDialog::CanSelectItem( CBaseLibraryItem *pItem )
{
assert( pItem );
// Check if this item is in dialogs manager.
if (m_pItemManager->FindItem(pItem->GetGUID()) == pItem)
return true;
return false;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::SelectItem( CBaseLibraryItem *item,bool bForceReload )
{
if (item == m_pCurrentItem && !bForceReload)
return;
if (item)
{
// Selecting item from different library.
if (item->GetLibrary() != m_pLibrary)
{
// Select library first.
SelectLibrary( item->GetLibrary()->GetName() );
}
}
m_pCurrentItem = item;
if (item)
{
m_selectedGroup = item->GetGroupName();
}
else
m_selectedGroup = "";
m_pCurrentItem = item;
// Set item visible.
HTREEITEM hItem = stl::find_in_map( m_itemsToTree,item,(HTREEITEM)0 );
if (hItem)
{
m_treeCtrl.SelectItem(hItem);
m_treeCtrl.EnsureVisible(hItem);
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::Update()
{
// do nothing here.
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnSave()
{
m_pItemManager->SaveAllLibs();
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::Reload()
{
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::SetActive( bool bActive )
{
if (bActive && !m_bLibsLoaded)
{
ReloadLibs();
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnUpdateSelected( CCmdUI* pCmdUI )
{
if (m_pCurrentItem)
pCmdUI->Enable( TRUE );
else
pCmdUI->Enable( FALSE );
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnUpdatePaste( CCmdUI* pCmdUI )
{
CClipboard clipboard;
if (clipboard.IsEmpty())
pCmdUI->Enable( FALSE );
else
pCmdUI->Enable( TRUE );
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnClone()
{
OnCopy();
OnPaste();
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnCut()
{
if (m_pCurrentItem)
{
OnCopy();
OnRemoveItem();
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnReloadLib()
{
if (!m_pLibrary)
return;
CString libname = m_pLibrary->GetName();
CString file = m_pLibrary->GetFilename();
if (m_pLibrary->IsModified())
{
CString str;
str.Format( "Layer %s was modified.\nReloading layer will discard all modifications to this library!",
(const char*)libname );
if (AfxMessageBox( str,MB_OKCANCEL|MB_ICONQUESTION ) != IDOK)
return;
}
m_pItemManager->DeleteLibrary( libname );
m_pItemManager->LoadLibrary( file );
ReloadLibs();
SelectLibrary( libname );
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryDialog::OnLoadLibrary()
{
CErrorsRecorder errorRecorder;
// Load new material library.
CString file;
if (CFileUtil::SelectFile( "*.xml",m_pItemManager->GetLibsPath(),file ))
{
CString relFile = GetIEditor()->GetRelativePath(file);
if (!relFile.IsEmpty())
{
IDataBaseLibrary *matLib = m_pItemManager->LoadLibrary( relFile );
ReloadLibs();
if (matLib)
SelectLibrary( matLib->GetName() );
}
}
}

156
Editor/BaseLibraryDialog.h Normal file
View File

@@ -0,0 +1,156 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: BaseLibraryDialog.h
// Version: v1.00
// Created: 22/1/2003 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __baselibrarydialog_h__
#define __baselibrarydialog_h__
#pragma once
//#include "XTToolkit.h"
#include "ToolbarDialog.h"
#include "Controls\SplitterWndEx.h"
#include "Controls\TreeCtrlEx.h"
#include "Controls\PropertyCtrl.h"
#include "Controls\PreviewModelCtrl.h"
class CBaseLibrary;
class CBaseLibraryItem;
class CBaseLibraryManager;
/** Base class for all BasLibrary base dialogs.
Provides common methods for handling library items.
*/
class CBaseLibraryDialog : public CToolbarDialog,public IDocListener
{
DECLARE_DYNAMIC(CBaseLibraryDialog);
public:
CBaseLibraryDialog( UINT nID,CWnd *pParent );
~CBaseLibraryDialog();
//! Reload all data in dialog.
virtual void Reload();
// Called every frame.
virtual void Update();
//! This dialog is activated.
virtual void SetActive( bool bActive );
virtual void SelectLibrary( const CString &library );
virtual void SelectItem( CBaseLibraryItem *item,bool bForceReload=false );
virtual bool CanSelectItem( CBaseLibraryItem *pItem );
//! Returns menu for this dialog.
virtual UINT GetDialogMenuID() { return 0; };
protected:
virtual void OnOK() {};
virtual void OnCancel() {};
void DoDataExchange(CDataExchange* pDX);
BOOL OnInitDialog();
afx_msg void OnDestroy();
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnSelChangedItemTree(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnKeyDownItemTree(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnUpdateSelected( CCmdUI* pCmdUI );
afx_msg void OnUpdatePaste( CCmdUI* pCmdUI );
virtual afx_msg void OnAddLibrary();
virtual afx_msg void OnRemoveLibrary();
virtual afx_msg void OnAddItem();
virtual afx_msg void OnRemoveItem();
virtual afx_msg void OnRenameItem();
virtual afx_msg void OnChangedLibrary();
virtual afx_msg void OnExportLibrary();
virtual afx_msg void OnSave();
virtual afx_msg void OnReloadLib();
virtual afx_msg void OnLoadLibrary();
//////////////////////////////////////////////////////////////////////////
// Must be overloaded in derived classes.
//////////////////////////////////////////////////////////////////////////
virtual CBaseLibrary* FindLibrary( const CString &libraryName );
virtual CBaseLibrary* NewLibrary( const CString &libraryName );
virtual void DeleteLibrary( CBaseLibrary *pLibrary );
virtual void DeleteItem( CBaseLibraryItem *pItem );
//////////////////////////////////////////////////////////////////////////
// Some functions can be overriden to modify standart functionality.
//////////////////////////////////////////////////////////////////////////
virtual void InitToolbar();
virtual void ReloadLibs();
virtual void ReloadItems();
virtual HTREEITEM InsertItemToTree( CBaseLibraryItem *pItem,HTREEITEM hParent );
virtual void SetItemName( CBaseLibraryItem *item,const CString &groupName,const CString &itemName );
//////////////////////////////////////////////////////////////////////////
// IDocListener listener implementation
//////////////////////////////////////////////////////////////////////////
virtual void OnNewDocument();
virtual void OnLoadDocument();
virtual void OnCloseDocument();
virtual void OnMissionChange() {};
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Copying and cloning of items.
//////////////////////////////////////////////////////////////////////////
virtual void OnCopy() = 0;
virtual void OnPaste() = 0;
virtual void OnCut();
virtual void OnClone();
DECLARE_MESSAGE_MAP()
// Dialog Toolbar.
CDlgToolBar m_toolbar;
// Tree control.
CTreeCtrl m_treeCtrl;
// Library control.
CComboBox m_libraryCtrl;
// Map of library items to tree ctrl.
typedef std::map<CBaseLibraryItem*,HTREEITEM> ItemsToTreeMap;
ItemsToTreeMap m_itemsToTree;
//CXTToolBar m_toolbar;
// Name of currently selected library.
CString m_selectedLib;
CString m_selectedGroup;
bool m_bLibsLoaded;
//! Selected library.
TSmartPtr<CBaseLibrary> m_pLibrary;
//! Selected Item.
TSmartPtr<CBaseLibraryItem> m_pCurrentItem;
//! Pointer to item manager.
CBaseLibraryManager* m_pItemManager;
//////////////////////////////////////////////////////////////////////////
// Dragging support.
//////////////////////////////////////////////////////////////////////////
CBaseLibraryItem *m_pDraggedItem;
CImageList* m_dragImage;
bool m_bIgnoreSelectionChange;
HCURSOR m_hCursorDefault;
HCURSOR m_hCursorNoDrop;
HCURSOR m_hCursorCreate;
HCURSOR m_hCursorReplace;
};
#endif // __baselibrarydialog_h__

138
Editor/BaseLibraryItem.cpp Normal file
View File

@@ -0,0 +1,138 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: baselibraryitem.cpp
// Version: v1.00
// Created: 22/1/2003 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "BaseLibraryItem.h"
#include "BaseLibrary.h"
#include "BaseLibraryManager.h"
//////////////////////////////////////////////////////////////////////////
// CBaseLibraryItem implementation.
//////////////////////////////////////////////////////////////////////////
CBaseLibraryItem::CBaseLibraryItem()
{
m_library = 0;
GenerateId();
}
CBaseLibraryItem::~CBaseLibraryItem()
{
}
//////////////////////////////////////////////////////////////////////////
CString CBaseLibraryItem::GetFullName() const
{
CString name;
if (m_library)
name = m_library->GetName() + ".";
name += m_name;
return name;
}
//////////////////////////////////////////////////////////////////////////
CString CBaseLibraryItem::GetGroupName()
{
CString str = GetName();
int p = str.Find('.');
if (p >= 0)
{
return str.Mid(0,p);
}
return "";
}
//////////////////////////////////////////////////////////////////////////
CString CBaseLibraryItem::GetShortName()
{
CString str = GetName();
int p = str.Find('.');
if (p >= 0)
{
return str.Mid(p+1);
}
return str;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryItem::SetName( const CString &name )
{
m_name = name;
}
//////////////////////////////////////////////////////////////////////////
const CString& CBaseLibraryItem::GetName() const
{
return m_name;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryItem::GenerateId()
{
GUID guid;
CoCreateGuid( &guid );
SetGUID(guid);
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryItem::SetGUID( REFGUID guid )
{
if (m_library)
{
((CBaseLibraryManager*)m_library->GetManager())->RegisterItem( this,guid );
}
m_guid = guid;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryItem::Serialize( SerializeContext &ctx )
{
//assert(m_library);
XmlNodeRef node = ctx.node;
if (ctx.bLoading)
{
CString name = m_name;
// Loading
node->getAttr( "Name",name );
if (!ctx.bUniqName)
{
SetName( name );
}
else
{
SetName( GetLibrary()->GetManager()->MakeUniqItemName(name) );
}
if (!ctx.bCopyPaste)
{
GUID guid;
if (node->getAttr( "Id",guid ))
SetGUID(guid);
}
}
else
{
// Saving.
node->setAttr( "Name",m_name );
node->setAttr( "Id",m_guid );
}
}
//////////////////////////////////////////////////////////////////////////
IDataBaseLibrary* CBaseLibraryItem::GetLibrary() const
{
return m_library;
}

86
Editor/BaseLibraryItem.h Normal file
View File

@@ -0,0 +1,86 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: baselibraryitem.h
// Version: v1.00
// Created: 22/1/2003 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __baselibraryitem_h__
#define __baselibraryitem_h__
#pragma once
#include "IDataBaseItem.h"
class CBaseLibrary;
//////////////////////////////////////////////////////////////////////////
/** Base class for all items contained in BaseLibraray.
*/
class CBaseLibraryItem : public TRefCountBase<IDataBaseItem>
{
public:
CBaseLibraryItem();
~CBaseLibraryItem();
//! Set item name.
//! Its virtual, in case you want to override it in derrived item.
virtual void SetName( const CString &name );
//! Get item name.
const CString& GetName() const;
//! Get full item name, including name of library.
//! Name formed by adding dot after name of library
//! eg. library Pickup and item PickupRL form full item name: "Pickups.PickupRL".
CString GetFullName() const;
//! Get only nameof group from prototype.
CString GetGroupName();
//! Get short name of prototype without group.
CString GetShortName();
//! Return Library this item are contained in.
//! Item can only be at one library.
IDataBaseLibrary* GetLibrary() const;
//////////////////////////////////////////////////////////////////////////
//! Serialize library item to archive.
virtual void Serialize( SerializeContext &ctx );
//////////////////////////////////////////////////////////////////////////
//! Generate new unique id for this item.
void GenerateId();
//! Returns GUID of this material.
REFGUID GetGUID() const { return m_guid; }
//! Validate item for errors.
virtual void Validate() {};
//////////////////////////////////////////////////////////////////////////
//! Gathers resources by this item.
virtual void GatherUsedResources( CUsedResources &resources ) {};
protected:
void SetGUID( REFGUID guid );
friend class CBaseLibrary;
friend class CBaseLibraryManager;
// Name of this prototype.
CString m_name;
//! Reference to prototype library who contains this prototype.
TSmartPtr<CBaseLibrary> m_library;
//! Every base library item have unique id.
GUID m_guid;
};
TYPEDEF_AUTOPTR(CBaseLibraryItem);
#endif // __baselibraryitem_h__

View File

@@ -0,0 +1,437 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: baselibrarymanager.cpp
// Version: v1.00
// Created: 10/6/2003 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "BaseLibraryManager.h"
#include "BaseLibrary.h"
#include "BaseLibraryItem.h"
#include "ErrorReport.h"
//////////////////////////////////////////////////////////////////////////
// CBaseLibraryManager implementation.
//////////////////////////////////////////////////////////////////////////
CBaseLibraryManager::CBaseLibraryManager()
{
}
//////////////////////////////////////////////////////////////////////////
CBaseLibraryManager::~CBaseLibraryManager()
{
ClearAll();
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::ClearAll()
{
// Delete all items from all libraries.
for (int i = 0; i < m_libs.size(); i++)
{
m_libs[i]->RemoveAllItems();
}
m_itemsMap.clear();
m_libs.clear();
}
//////////////////////////////////////////////////////////////////////////
IDataBaseLibrary* CBaseLibraryManager::FindLibrary( const CString &library )
{
for (int i = 0; i < m_libs.size(); i++)
{
if (stricmp(library,m_libs[i]->GetName()) == 0)
{
return m_libs[i];
}
}
return NULL;
}
//////////////////////////////////////////////////////////////////////////
IDataBaseItem* CBaseLibraryManager::FindItem( REFGUID guid ) const
{
CBaseLibraryItem* pMtl = stl::find_in_map( m_itemsMap,guid,(CBaseLibraryItem*)0 );
return pMtl;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::SplitFullItemName( const CString &fullItemName,CString &libraryName,CString &itemName )
{
int p;
p = fullItemName.Find( '.' );
if (p < 0)
{
libraryName = "";
itemName = fullItemName;
return;
}
libraryName = fullItemName.Mid(0,p);
itemName = fullItemName.Mid(p+1);
}
//////////////////////////////////////////////////////////////////////////
IDataBaseItem* CBaseLibraryManager::FindItemByName( const CString &fullItemName )
{
CString libraryName,itemName;
SplitFullItemName( fullItemName,libraryName,itemName );
if (libraryName.IsEmpty())
{
Error( _T("Cannot Find Item, Library name must be specified before \".\" : %s"),(const char*)fullItemName );
return 0;
}
IDataBaseLibrary *lib = FindLibrary( libraryName );
if (!lib)
{
Error( _T("Cannot Find Library: %s"),(const char*)libraryName );
return 0;
}
return lib->FindItem( itemName );
}
//////////////////////////////////////////////////////////////////////////
IDataBaseItem* CBaseLibraryManager::CreateItem( IDataBaseLibrary *pLibrary )
{
assert( pLibrary );
// Add item to this library.
TSmartPtr<CBaseLibraryItem> pItem = MakeNewItem();
pLibrary->AddItem( pItem );
pItem->GenerateId();
return pItem;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::DeleteItem( IDataBaseItem* pItem )
{
assert( pItem );
m_itemsMap.erase( pItem->GetGUID() );
if (pItem->GetLibrary())
{
pItem->GetLibrary()->RemoveItem( pItem );
}
// Delete all objects from object manager that have
//GetIEditor()->GetObjectManager()->GetObjects( objects );
}
//////////////////////////////////////////////////////////////////////////
IDataBaseLibrary* CBaseLibraryManager::LoadLibrary( const CString &filename )
{
// If library is already loaded ignore it.
for (int i = 0; i < m_libs.size(); i++)
{
if (stricmp(filename,m_libs[i]->GetFilename()) == 0)
{
Error( _T("Loading Duplicate Library: %s"),(const char*)filename );
return 0;
}
}
TSmartPtr<CBaseLibrary> pLib = MakeNewLibrary();
if (!pLib->Load( filename ))
{
Error( _T("Failed to Load Item Library: %s"),(const char*)filename );
return 0;
}
if (FindLibrary(pLib->GetName()) != 0)
{
Error( _T("Loading Duplicate Library: %s"),(const char*)pLib->GetName() );
return 0;
}
m_libs.push_back( pLib );
return pLib;
}
//////////////////////////////////////////////////////////////////////////
IDataBaseLibrary* CBaseLibraryManager::AddLibrary( const CString &library )
{
// Check if library with same name already exist.
IDataBaseLibrary* pBaseLib = FindLibrary(library);
if (pBaseLib)
return pBaseLib;
CBaseLibrary *lib = MakeNewLibrary();
lib->SetName( library );
// Set filename of this library.
// Make a filename from name of library.
CString filename = library;
filename.Replace( ' ','_' );
filename = GetLibsPath() + filename + ".xml";
lib->SetFilename( filename );
m_libs.push_back( lib );
return lib;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::DeleteLibrary( const CString &library )
{
for (int i = 0; i < m_libs.size(); i++)
{
if (stricmp(library,m_libs[i]->GetName()) == 0)
{
CBaseLibrary *pLibrary = m_libs[i];
// Check if not level library, they cannot be deleted.
if (!pLibrary->IsLevelLibrary())
{
for (int j = 0; j < pLibrary->GetItemCount(); j++)
{
UnregisterItem( (CBaseLibraryItem*)pLibrary->GetItem(j) );
}
m_libs.erase( m_libs.begin() + i );
}
break;
}
}
}
//////////////////////////////////////////////////////////////////////////
IDataBaseLibrary* CBaseLibraryManager::GetLibrary( int index ) const
{
assert( index >= 0 && index < m_libs.size() );
return m_libs[index];
};
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::SaveAllLibs()
{
for (int i = 0; i < GetLibraryCount(); i++)
{
// Check if library is modified.
IDataBaseLibrary *pLibrary = GetLibrary(i);
if (pLibrary->IsLevelLibrary())
continue;
if (pLibrary->IsModified())
{
if (pLibrary->Save())
{
pLibrary->SetModified(false);
}
}
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::Serialize( XmlNodeRef &node,bool bLoading )
{
CString rootNodeName = GetRootNodeName();
if (bLoading)
{
CString libsPath = GetLibsPath();
if (!libsPath.IsEmpty())
CFileUtil::CreateDirectory( libsPath );
XmlNodeRef libs = node->findChild( rootNodeName );
if (libs)
{
for (int i = 0; i < libs->getChildCount(); i++)
{
// Load only library name.
XmlNodeRef libNode = libs->getChild(i);
if (strcmp(libNode->getTag(),"LevelLibrary") == 0)
{
m_pLevelLibrary->Serialize( libNode,bLoading );
}
else
{
CString libName;
if (libNode->getAttr( "Name",libName ))
{
// Load this library.
CString filename = libName;
filename.Replace( ' ','_' );
filename = GetLibsPath() + filename + ".xml";
if (!FindLibrary(libName))
{
LoadLibrary( filename );
}
}
}
}
}
}
else
{
// Save all libraries.
XmlNodeRef libs = node->newChild( rootNodeName );
for (int i = 0; i < GetLibraryCount(); i++)
{
IDataBaseLibrary* pLib = GetLibrary(i);
if (pLib->IsLevelLibrary())
{
// Level libraries are saved in in level.
XmlNodeRef libNode = libs->newChild( "LevelLibrary" );
pLib->Serialize( libNode,bLoading );
}
else
{
// Save only library name.
XmlNodeRef libNode = libs->newChild( "Library" );
libNode->setAttr( "Name",pLib->GetName() );
}
}
SaveAllLibs();
}
}
//////////////////////////////////////////////////////////////////////////
CString CBaseLibraryManager::MakeUniqItemName( const CString &srcName )
{
// Remove all numbers from the end of name.
CString typeName = srcName;
int len = typeName.GetLength();
while (len > 0 && isdigit(typeName[len-1]))
len--;
typeName = typeName.Left(len);
CString tpName = typeName;
int num = 0;
for (ItemsMap::iterator it = m_itemsMap.begin(); it != m_itemsMap.end(); ++it)
{
CBaseLibraryItem *pItem = it->second;
const char *name = pItem->GetName();
if (strncmp(name,tpName,len) == 0)
{
int n = atoi(name+len) + 1;
num = MAX( num,n );
}
}
CString str;
str.Format( "%s%d",(const char*)typeName,num );
return str;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::Validate()
{
for (ItemsMap::iterator it = m_itemsMap.begin(); it != m_itemsMap.end(); ++it)
{
it->second->Validate();
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::RegisterItem( CBaseLibraryItem *pItem,REFGUID newGuid )
{
assert(pItem);
bool bNewItem = true;
REFGUID oldGuid = pItem->GetGUID();
if (!GuidUtil::IsEmpty(oldGuid))
{
bNewItem = false;
m_itemsMap.erase( oldGuid );
}
if (GuidUtil::IsEmpty(newGuid))
return;
CBaseLibraryItem *pOldItem = stl::find_in_map( m_itemsMap,newGuid,(CBaseLibraryItem*)0 );
if (!pOldItem)
{
pItem->m_guid = newGuid;
m_itemsMap[newGuid] = pItem;
}
else
{
if (pOldItem != pItem)
{
ReportDuplicateItem( pItem,pOldItem );
}
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::RegisterItem( CBaseLibraryItem *pItem )
{
assert(pItem);
if (GuidUtil::IsEmpty(pItem->GetGUID()))
return;
CBaseLibraryItem *pOldItem = stl::find_in_map( m_itemsMap,pItem->GetGUID(),(CBaseLibraryItem*)0 );
if (!pOldItem)
{
m_itemsMap[pItem->GetGUID()] = pItem;
}
else
{
if (pOldItem != pItem)
{
ReportDuplicateItem( pItem,pOldItem );
}
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::ReportDuplicateItem( CBaseLibraryItem *pItem,CBaseLibraryItem *pOldItem )
{
CString sLibName;
if (pOldItem->GetLibrary())
sLibName = pOldItem->GetLibrary()->GetName();
CErrorRecord err;
err.error.Format( "Item %s with duplicate GUID to loaded item %s ignored",(const char*)pItem->GetFullName(),(const char*)pOldItem->GetFullName() );
GetIEditor()->GetErrorReport()->ReportError( err );
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::UnregisterItem( CBaseLibraryItem *pItem )
{
m_itemsMap.erase( pItem->GetGUID() );
}
//////////////////////////////////////////////////////////////////////////
CString CBaseLibraryManager::MakeFullItemName( IDataBaseLibrary *pLibrary,const CString &group,const CString &itemName )
{
assert(pLibrary);
CString name = pLibrary->GetName() + ".";
if (!group.IsEmpty())
name += group + ".";
name += itemName;
return name;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::GatherUsedResources( CUsedResources &resources )
{
for (int lib = 0; lib < GetLibraryCount(); lib++)
{
IDataBaseLibrary *pLib = GetLibrary(lib);
for (int i = 0; i < pLib->GetItemCount(); i++)
{
pLib->GetItem(i)->GatherUsedResources( resources );
}
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::OnNewDocument()
{
ClearAll();
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::OnLoadDocument()
{
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::OnCloseDocument()
{
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::OnMissionChange()
{
}

130
Editor/BaseLibraryManager.h Normal file
View File

@@ -0,0 +1,130 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: baselibrarymanager.h
// Version: v1.00
// Created: 10/6/2003 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __baselibrarymanager_h__
#define __baselibrarymanager_h__
#pragma once
#include "IDataBaseItem.h"
#include "IDataBaseLibrary.h"
#include "IDataBaseManager.h"
class CBaseLibraryItem;
class CBaseLibrary;
/** Manages all Libraries and Items.
*/
class CBaseLibraryManager : public TRefCountBase<IDataBaseManager>, public IDocListener
{
public:
CBaseLibraryManager();
~CBaseLibraryManager();
//! Clear all libraries.
virtual void ClearAll();
//////////////////////////////////////////////////////////////////////////
// IDocListener implementation.
//////////////////////////////////////////////////////////////////////////
virtual void OnNewDocument();
virtual void OnLoadDocument();
virtual void OnCloseDocument();
virtual void OnMissionChange();
//////////////////////////////////////////////////////////////////////////
// Library items.
//////////////////////////////////////////////////////////////////////////
//! Make a new item in specified library.
virtual IDataBaseItem* CreateItem( IDataBaseLibrary *pLibrary );
//! Delete item from library and manager.
virtual void DeleteItem( IDataBaseItem* pItem );
//! Find Item by its GUID.
virtual IDataBaseItem* FindItem( REFGUID guid ) const;
virtual IDataBaseItem* FindItemByName( const CString &fullItemName );
//////////////////////////////////////////////////////////////////////////
// Libraries.
//////////////////////////////////////////////////////////////////////////
//! Add Item library.
virtual IDataBaseLibrary* AddLibrary( const CString &library );
virtual void DeleteLibrary( const CString &library );
//! Get number of libraries.
virtual int GetLibraryCount() const { return m_libs.size(); };
//! Get Item library by index.
virtual IDataBaseLibrary* GetLibrary( int index ) const;
//! Find Items Library by name.
virtual IDataBaseLibrary* FindLibrary( const CString &library );
//! Load Items library.
virtual IDataBaseLibrary* LoadLibrary( const CString &filename );
//! Save all modified libraries.
virtual void SaveAllLibs();
//! Serialize property manager.
virtual void Serialize( XmlNodeRef &node,bool bLoading );
//! Export items to game.
virtual void Export( XmlNodeRef &node ) {};
//void AddNotifyListener(
//! Returns unique name base on input name.
virtual CString MakeUniqItemName( const CString &name );
virtual CString MakeFullItemName( IDataBaseLibrary *pLibrary,const CString &group,const CString &itemName );
//! Root node where this library will be saved.
virtual CString GetRootNodeName() = 0;
//! Path to libraries in this manager.
virtual CString GetLibsPath() = 0;
//////////////////////////////////////////////////////////////////////////
//! Validate library items for errors.
void Validate();
//////////////////////////////////////////////////////////////////////////
void GatherUsedResources( CUsedResources &resources );
//////////////////////////////////////////////////////////////////////////
void RegisterItem( CBaseLibraryItem *pItem,REFGUID newGuid );
void RegisterItem( CBaseLibraryItem *pItem );
void UnregisterItem( CBaseLibraryItem *pItem );
protected:
void SplitFullItemName( const CString &fullItemName,CString &libraryName,CString &itemName );
//////////////////////////////////////////////////////////////////////////
// Must be overriden.
//! Makes a new Item.
virtual CBaseLibraryItem* MakeNewItem() = 0;
virtual CBaseLibrary* MakeNewLibrary() = 0;
//////////////////////////////////////////////////////////////////////////
virtual void ReportDuplicateItem( CBaseLibraryItem *pItem,CBaseLibraryItem *pOldItem );
//! Array of all loaded entity items libraries.
std::vector<TSmartPtr<CBaseLibrary> > m_libs;
// There is always one current level library.
TSmartPtr<CBaseLibrary> m_pLevelLibrary;
// GUID to item map.
typedef std::map<GUID,TSmartPtr<CBaseLibraryItem>,guid_less_predicate> ItemsMap;
ItemsMap m_itemsMap;
};
#endif // __baselibrarymanager_h__

2155
Editor/Brush/Brush.cpp Normal file

File diff suppressed because it is too large Load Diff

210
Editor/Brush/Brush.h Normal file
View File

@@ -0,0 +1,210 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: brush.h
// Version: v1.00
// Created: 9/7/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __brush_h__
#define __brush_h__
#if _MSC_VER > 1000
#pragma once
#endif
#include "BrushPlane.h"
#include "BrushPoly.h"
#include "BrushFace.h"
// forward declrations.
struct SBrushPlane;
struct SBrushPoly;
class CEdMesh;
class CBrushIndoor;
#define DIST_EPSILON 0.01f
//////////////////////////////////////////////////////////////////////////
// Brush flags.
//////////////////////////////////////////////////////////////////////////
enum BrushFlags
{
BRF_HIDE = 0x01,
BRF_FAILMODEL = 0x02,
BRF_TEMP = 0x04,
BRF_NODEL = 0x08,
BRF_LIGHTVOLUME = 0x10,
BRF_SHOW_AFTER = 0x20,
BRF_RE_VALID = 0x40, //!< Set if render elements are valid.
};
//////////////////////////////////////////////////////////////////////////
/** Holds selected data from inside brush.
*/
struct SBrushSubSelection
{
// Points contained in brush sub-selection.
std::vector<Vec3*> points;
//! Adds point to brush sub-selection.
bool AddPoint( Vec3 *pnt );
//! Clear all points in brush sub-selection.
void Clear();
};
//////////////////////////////////////////////////////////////////////////
/** Indoor Brush
*/
struct SBrush : public CRefCountBase
{
public:
//! Ctor.
SBrush();
//! Dtor (virtual)
virtual ~SBrush();
//! Assignment operator.
SBrush& operator = (const SBrush& b);
//! Create brush planes from bounding box.
void Create( const Vec3 &mins,const Vec3& maxs,SMapTexInfo *ti );
//! Create Solid brush out of planes.
//! @return False if solid brush cannot be created.
bool BuildSolid( bool bRemoveEmptyFaces=false,bool bBuildRE=false );
//! Remove brush faces that are empty.
void RemoveEmptyFaces();
SBrush* Clone( bool bBuildSolid );
//! Calculates brush volume.
//! @return Return volume of this brush.
float GetVolume();
//! Move brush by delta offset.
void Move( Vec3d& delta );
void ClipPrefabModels(bool bClip);
//! Transform all planes of this brush by specified matrix.
//! @param bBuild if true after transform face of brush will be build out of planes.
void Transform( Matrix44 &tm,bool bBuild=true );
//! Snap all plane points of brush to the specified grid.
void SnapToGrid();
//! Check if ray intersect brush, and return nearest face hit by the ray.
//! @return Nearest face that was hit by ray.
//! @param rayOrigin Source point of ray (in Brush Space).
//! @param rayDir Normilized ray direction vector (in Brush Space).
//! @param dist Returns distance from ray origin to the hit point on the brush.
SBrushFace* Ray( Vec3d rayOrigin,Vec3d rayDir, float *dist );
//! Select brush sides to SubSelection.
void SelectSide( Vec3d Origin, Vec3d Dir,bool shear,SBrushSubSelection &subSelection );
//! Select brush face to SubSelection.
//! Called by select side.
void SelectFace( SBrushFace *f,bool shear,SBrushSubSelection &subSelection );
//! Create polygon for one of brush faces.
SBrushPoly* CreateFacePoly( SBrushFace *f );
//! Detect on which side of plane this brush lies.
//! @return Side cane be SIDE_FRONT or SIDE_BACK.
int OnSide (SBrushPlane *plane);
//! Split brush by face and return front and back brushes resulting from split..
//! @param front Returns splitted front part of brush.
//! @param back Returns splitted back part of brush.
void SplitByFace( SBrushFace *f, SBrush* &front, SBrush* &back );
//! Split brush by plane and return front and back brushes resulting from split..
//! @param front Returns splitted front part of brush.
//! @param back Returns splitted back part of brush.
void SplitByPlane (SBrushPlane *plane, SBrush* &front, SBrush* &back);
//! Fit texture coordinates to match brush size.
void FitTexture(int nX, int nY);
//! Check if 3D point is inside volume of the brush.
bool IsInside(const Vec3d &vPoint);
//! Check if volumes of 2 brushes intersect.
bool IsIntersect(SBrush *b);
//! Intersect 2 brushes, and returns list of all brush parts resulting from intersections.
bool Intersect(SBrush *b, std::vector<SBrush*>& List);
void SetShader(SMapTexInfo *ti);
void Draw();
bool DrawModel(bool b);
void AddToList(CCObject *obj);
bool AddToListModel(bool b);
//! Return ammount of memory allocated for this brush.
int GetMemorySize();
//! Remove faces from brush.
void ClearFaces();
//! Serialize brush parameters to xml node.
void Serialize( XmlNodeRef &xmlNode,bool bLoading );
//! Set transformation matrix.
void SetMatrix( const Matrix44 &tm );
//! Get tranformation matrix.
const Matrix44& GetMatrix() const { return m_matrix; };
//! Render brush.
void Render( IRenderer *renderer,const Vec3 &objectSpaceCamSrc );
// Set prefab geometry used for brush.
void SetPrefabGeom( CEdMesh *mesh );
void ResetToPrefabSize();
IStatObj* GetIndoorGeom();
//! Assign indoor owning this brush.
void SetIndoor( CBrushIndoor *indoor );
//! Fill mesh with geometry from brush.
//CIndexedMesh* CreateGeometry();
//////////////////////////////////////////////////////////////////////////
// Obsolete
//////////////////////////////////////////////////////////////////////////
void MakeSelFace( SBrushFace *f );
public:
BBox m_bounds;
std::vector<SBrushFace*> m_Faces;
//! This brush transformation matrix.
Matrix44 m_matrix;
int m_flags;
//! Original prefab geometry.
TSmartPtr<CEdMesh> m_prefabGeom;
//! Geometry used in indoor.
IStatObj *m_indoorGeom;
private:
//! Caluclate planes of brush faces.
void MakeFacePlanes();
//! Build render element for each face.
bool BuildRenderElements();
};
#endif // __brush_h__

View File

@@ -0,0 +1,333 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: brushexporter.cpp
// Version: v1.00
// Created: 15/12/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "BrushExporter.h"
#include "CryEditDoc.h"
#include "Objects\BrushObject.h"
#include "Objects\Group.h"
#include "Objects\ObjectManager.h"
#include "Material\Material.h"
#include "Brush.h"
#include "list2.h"
#include "Util\Pakfile.h"
#include <I3DEngine.h>
#define BRUSH_FILE "brush.lst"
//////////////////////////////////////////////////////////////////////////
void CBrushExporter::SaveMesh()
{
/*
std::vector<CBrushObject*> objects;
m_indoor->GetObjects( objects );
for (int i = 0; i < objects.size(); i++)
{
SaveObject( objects[i] );
}
*/
}
int CBrushExporter::AddChunk( const CHUNK_HEADER &hdr,CMemFile &file )
{
int fsize = file.GetLength();
return m_file.AddChunk( hdr,file.Detach(),fsize );
}
//////////////////////////////////////////////////////////////////////////
void CBrushExporter::SaveObject( CBrushObject *obj )
{
SBrush *brush = obj->GetBrush();
IStatObj *geom = brush->GetIndoorGeom();
if (!geom)
return;
CLeafBuffer *buf = geom->GetLeafBuffer();
int numVerts = buf->m_SecVertCount;
int posStride,normalStride,uvStride;
unsigned char *verts = buf->GetPosPtr( posStride );
unsigned char *normals = buf->GetNormalPtr( normalStride );
unsigned char *uvs = buf->GetUVPtr( uvStride );
int numTris;
ushort *pInds = buf->GetIndices(&numTris);
numTris /= 3;
MESH_CHUNK_DESC chunk;
chunk.HasBoneInfo = false;
chunk.HasVertexCol = false;
chunk.nFaces = numTris;
chunk.nTVerts = numVerts;
chunk.nVerts = numVerts;
chunk.VertAnimID = 0;
CMemFile memfile;
CArchive ar( &memfile, CArchive::store );
ar.Write( &chunk,sizeof(chunk) );
std::vector<CryVertex> arrVerts;
std::vector<CryFace> arrFaces;
std::vector<CryUV> arrUVs;
std::vector<CryTexFace> arrTexFaces;
int i;
// fill the vertices in
arrVerts.resize(numVerts);
arrUVs.resize(numVerts);
for(i=0;i<numVerts;i++)
{
CryVertex& vert = arrVerts[i];
vert.p = *((Vec3d*)(verts));
vert.n = *((Vec3d*)(normals));
arrUVs[i] = *((CryUV*)(uvs));
normals += normalStride;
verts += posStride;
uvs += uvStride;
}
// fill faces.
arrFaces.resize(numTris);
arrTexFaces.resize(numTris);
for (i = 0; i < numTris; i++)
{
CryFace& mf = arrFaces[i];
CryTexFace& texf = arrTexFaces[i];
mf.v0 = pInds[i*3];
mf.v1 = pInds[i*3+1];
mf.v2 = pInds[i*3+2];
mf.SmGroup = 0;
mf.MatID = -1;
texf.t0 = mf.v0;
texf.t1 = mf.v1;
texf.t2 = mf.v2;
}
// Save verts.
ar.Write( &arrVerts[0], sizeof(arrVerts[0]) * arrVerts.size() );
// Save faces.
ar.Write( &arrFaces[0], sizeof(arrFaces[0]) * arrFaces.size() );
// Save UVs
ar.Write( &arrUVs[0], sizeof(arrUVs[0]) * arrUVs.size() );
// Save tex faces.
ar.Write( &arrTexFaces[0], sizeof(arrTexFaces[0]) * arrTexFaces.size() );
ar.Close();
int meshChunkId = AddChunk( chunk.chdr,memfile );
//////////////////////////////////////////////////////////////////////////
// Add node.
//////////////////////////////////////////////////////////////////////////
NODE_CHUNK_DESC ncd;
ZeroStruct(ncd);
ncd.MatID = 0;
ncd.nChildren = 0;
ncd.ObjectID = meshChunkId;
ncd.ParentID = 0;
ncd.IsGroupHead = false;
ncd.IsGroupMember = false;
ncd.rot.SetIdentity();
ncd.tm.SetIdentity();
strcpy( ncd.name,"$0_sector_outside" );
m_file.AddChunk( ncd.chdr,&ncd,sizeof(ncd) );
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void CBrushExporter::ExportBrushes( const CString &path,const CString &levelName,CPakFile &pakFile )
{
CLogFile::WriteLine( "Exporting Brushes...");
int i;
CString filename = Path::Make( path,BRUSH_FILE );
// Export first brushes geometries.
//if (!CFileUtil::OverwriteFile( filename ))
//return;
// Delete the old one.
//DeleteFile( filename );
CMemFile file;
//////////////////////////////////////////////////////////////////////////
// Clear export data.
//////////////////////////////////////////////////////////////////////////
std::vector<CBaseObject*> objects;
GetIEditor()->GetObjectManager()->GetObjects( objects );
m_levelName = levelName;
for (i = 0; i < objects.size(); i++)
{
if (objects[i]->GetType() != OBJTYPE_BRUSH)
continue;
// Cast to brush.
CBrushObject *obj = (CBrushObject*)objects[i];
ExportBrush( path,obj );
}
if (m_geoms.empty() || m_brushes.empty())
{
// Nothing to export.
pakFile.RemoveFile( filename );
return;
}
//////////////////////////////////////////////////////////////////////////
// Export to file.
//////////////////////////////////////////////////////////////////////////
/*
CFile file;
if (!file.Open( filename,CFile::modeCreate|CFile::modeWrite ))
{
Error( "Unable to open indoor geometry brush.lst file %s for writing",(const char*)filename );
return;
}
*/
//////////////////////////////////////////////////////////////////////////
// Write brush file header.
//////////////////////////////////////////////////////////////////////////
SExportedBrushHeader header;
ZeroStruct( header );
memcpy( header.signature,BRUSH_FILE_SIGNATURE,3 );
header.filetype = BRUSH_FILE_TYPE;
header.version = BRUSH_FILE_VERSION;
file.Write( &header,sizeof(header) );
//////////////////////////////////////////////////////////////////////////
// Write materials.
//////////////////////////////////////////////////////////////////////////
int numMtls = m_materials.size();
file.Write( &numMtls,sizeof(numMtls) );
for (i = 0; i < numMtls; i++)
{
// write geometry description.
file.Write( &m_materials[i],sizeof(m_materials[i]) );
}
//////////////////////////////////////////////////////////////////////////
// Write geometries.
//////////////////////////////////////////////////////////////////////////
// Write number of brush geometries.
int numGeoms = m_geoms.size();
file.Write( &numGeoms,sizeof(numGeoms) );
for (i = 0; i < m_geoms.size(); i++)
{
// write geometry description.
file.Write( &m_geoms[i],sizeof(m_geoms[i]) );
}
//////////////////////////////////////////////////////////////////////////
// Write brush instances.
//////////////////////////////////////////////////////////////////////////
// write number of brushes.
int numBrushes = m_brushes.size();
file.Write( &numBrushes,sizeof(numBrushes) );
for (i = 0; i < m_brushes.size(); i++)
{
// write geometry description.
file.Write( &m_brushes[i],sizeof(m_brushes[i]) );
}
pakFile.UpdateFile( filename,file );
CLogFile::WriteString("Done.");
}
//////////////////////////////////////////////////////////////////////////
void CBrushExporter::ExportBrush( const CString &path,CBrushObject *brushObject )
{
IStatObj *prefab = brushObject->GetPrefabGeom();
if (!prefab)
{
return;
}
CString geomName = prefab->GetFileName();
int geomIndex = stl::find_in_map( m_geomIndexMap,geomName,-1 );
if (geomIndex < 0)
{
// add new geometry.
SExportedBrushGeom geom;
ZeroStruct( geom );
geom.size = sizeof(geom);
strcpy( geom.filename,geomName );
geom.flags = 0;
geom.m_minBBox = prefab->GetBoxMin();
geom.m_maxBBox = prefab->GetBoxMax();
m_geoms.push_back( geom );
geomIndex = m_geoms.size()-1;
m_geomIndexMap[geomName] = geomIndex;
}
CMaterial *pMtl = brushObject->GetMaterial();
int mtlIndex = -1;
if (pMtl)
{
mtlIndex = stl::find_in_map( m_mtlMap,pMtl,-1 );
if (mtlIndex < 0)
{
SExportedBrushMaterial mtl;
mtl.size = sizeof(mtl);
strncpy( mtl.material,pMtl->GetFullName(),sizeof(mtl.material) );
m_materials.push_back(mtl);
mtlIndex = m_materials.size()-1;
m_mtlMap[pMtl] = mtlIndex;
}
}
SExportedBrushGeom *pBrushGeom = &m_geoms[geomIndex];
if (pBrushGeom)
{
if (brushObject->IsRecieveLightmap())
pBrushGeom->flags |= SExportedBrushGeom::SUPPORT_LIGHTMAP;
IStatObj *pBrushStatObj = brushObject->GetPrefabGeom();
if (pBrushStatObj)
{
if (pBrushStatObj->GetPhysGeom(0) == NULL && pBrushStatObj->GetPhysGeom(1) == NULL)
{
pBrushGeom->flags |= SExportedBrushGeom::NO_PHYSICS;
}
}
}
SExportedBrush expbrush;
expbrush.size = sizeof(expbrush);
ZeroStruct( expbrush );
CGroup *pGroup = brushObject->GetGroup();
if (pGroup)
{
expbrush.mergeId = pGroup->GetGeomMergeId();
}
expbrush.id = brushObject->GetId().Data1;
//HACK, Remove GetTranspose later, when Matrix44 fixed.
expbrush.matrix = Matrix34( GetTransposed44(brushObject->GetBrushMatrix()) );
expbrush.geometry = geomIndex;
expbrush.flags = brushObject->GetRenderFlags();
expbrush.material = mtlIndex;
expbrush.ratioLod = brushObject->GetRatioLod();
expbrush.ratioViewDist = brushObject->GetRatioViewDist();
m_brushes.push_back( expbrush );
}

View File

@@ -0,0 +1,109 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: brushexporter.h
// Version: v1.00
// Created: 15/12/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __brushexporter_h__
#define __brushexporter_h__
#pragma once
#include "Util\ChunkFile.h"
// forward declarations.
class CChunkFile;
class CBrushObject;
class CPakFile;
#define BRUSH_FILE_TYPE 1
#define BRUSH_FILE_VERSION 3
#define BRUSH_FILE_SIGNATURE "CRY"
//////////////////////////////////////////////////////////////////////////
// Brush Export structures.
//////////////////////////////////////////////////////////////////////////
#pragma pack(push,1)
struct SExportedBrushHeader
{
char signature[3]; // File signature.
int filetype; // File type.
int version; // File version.
};
struct SExportedBrushGeom
{
enum EFlags
{
SUPPORT_LIGHTMAP = 0x01,
NO_PHYSICS = 0x02,
};
int size; // Size of this sructure.
char filename[128];
int flags; //! @see EFlags
Vec3 m_minBBox;
Vec3 m_maxBBox;
};
struct SExportedBrushMaterial
{
int size;
char material[64];
};
struct SExportedBrush
{
int size; // Size of this sructure.
int id;
int geometry;
int material;
int flags;
int mergeId;
Matrix34 matrix;
uchar ratioLod;
uchar ratioViewDist;
uchar reserved1;
uchar reserved2;
};
#pragma pack(pop)
//////////////////////////////////////////////////////////////////////////
/** Export brushes from specified Indoor to .bld file.
*/
class CBrushExporter
{
public:
void ExportBrushes( const CString &path,const CString &levelName,CPakFile &pakFile );
private:
void ExportBrush( const CString &path,CBrushObject *brush );
void SaveMesh();
void SaveObject( CBrushObject *brush );
int AddChunk( const CHUNK_HEADER &hdr,CMemFile &file );
CChunkFile m_file;
int nodeCount;
CString m_levelName;
//////////////////////////////////////////////////////////////////////////
typedef std::map<CString,int,stl::less_stricmp<CString> > GeomIndexMap;
GeomIndexMap m_geomIndexMap;
std::map<CMaterial*,int> m_mtlMap;
std::vector<SExportedBrushGeom> m_geoms;
std::vector<SExportedBrush> m_brushes;
std::vector<SExportedBrushMaterial> m_materials;
};
#endif // __brushexporter_h__

721
Editor/Brush/BrushFace.cpp Normal file
View File

@@ -0,0 +1,721 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: brushface.cpp
// Version: v1.00
// Created: 8/7/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History: Based on Andrey's Indoor editor.
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "BrushFace.h"
#include "BrushPlane.h"
#include "BrushPoly.h"
#include "Brush.h"
#include "BrushMtl.h"
#include <CREPolyMesh.h>
// Local namespace.
namespace
{
//! Creates boundary plane.
inline void CreateBoundaryPlane( SBrushPlane *src, Vec3d& p1, Vec3d& p2, SBrushPlane *dst )
{
Vec3d vv;
vv = p2 - p1;
dst->normal = src->normal ^ vv;
dst->normal.Normalize();
dst->dist = dst->normal | p1;
}
//static Vec3d m_TexVecs[2];
//static float m_TexShift[2];
}
//////////////////////////////////////////////////////////////////////////
//
// SBrushFace implementation.
//
//////////////////////////////////////////////////////////////////////////
SBrushFace& SBrushFace::operator = (const SBrushFace& f)
{
int i;
m_Prefabs = NULL;
for (i=0; i<3; i++)
{
m_PlanePts[i] = f.m_PlanePts[i];
}
m_TexInfo = f.m_TexInfo;
m_Plane = f.m_Plane;
if (f.m_Poly)
{
m_Poly = new SBrushPoly;
*m_Poly = *f.m_Poly;
}
m_color = f.m_color;
m_mtl = f.m_mtl;
m_RE = NULL;
return *this;
}
//////////////////////////////////////////////////////////////////////////
void SBrushFace::MakePlane()
{
m_Plane.Make( m_PlanePts[0],m_PlanePts[1],m_PlanePts[2] );
}
//////////////////////////////////////////////////////////////////////////
void SBrushFace::TextureVectors(Vec3d& tVecx, Vec3d& tVecy, float& tShiftx, float& tShifty)
{
Vec3d pvecs[2];
int sv, tv;
float ang, sinv, cosv;
float ns, nt;
int i;
SMapTexInfo *td;
td = &m_TexInfo;
//e = m_shader;
tVecx(0,0,0);
tVecy(0,0,0);
tShiftx = 0;
tShifty = 0;
if (!td->scale[0])
td->scale[0] = 0.5;
if (!td->scale[1])
td->scale[1] = 0.5;
m_Plane.CalcTextureAxis(pvecs[0], pvecs[1], 1);
// rotate axis
if (td->rotate == 0)
{
sinv = 0 ; cosv = 1;
}
else
if (td->rotate == 90)
{
sinv = 1 ; cosv = 0;
}
else
if (td->rotate == 180)
{
sinv = 0 ; cosv = -1;
}
else
if (td->rotate == 270)
{
sinv = -1 ; cosv = 0;
}
else
{
ang = td->rotate / 180 * gf_PI;
sinv = sin(ang);
cosv = cos(ang);
}
if (pvecs[0][0])
sv = 0;
else
if (pvecs[0][1])
sv = 1;
else
sv = 2;
if (pvecs[1][0])
tv = 0;
else
if (pvecs[1][1])
tv = 1;
else
tv = 2;
for (i=0 ; i<2 ; i++)
{
ns = cosv * pvecs[i][sv] - sinv * pvecs[i][tv];
nt = sinv * pvecs[i][sv] + cosv * pvecs[i][tv];
if (!i)
{
tVecx[sv] = ns;
tVecx[tv] = nt;
}
else
{
tVecy[sv] = ns;
tVecy[tv] = nt;
}
}
// scale
tVecx /= td->scale[0];
tVecy /= td->scale[1];
// defaults.
int texWidth = 32;
int texHeight = 32;
//@ASK Andrey.
if (m_mtl)
{
ITexPic *tex = m_mtl->GetEditorTexture();
if (tex)
{
texWidth = tex->GetWidth();
texHeight = tex->GetHeight();
}
}
// shift
tShiftx = td->shift[0] / texWidth;
tShifty = td->shift[1] / texHeight;
tVecx /= texWidth;
tVecy /= texHeight;
}
//////////////////////////////////////////////////////////////////////////
bool SBrushFace::ClipLine( Vec3d& p1,Vec3d& p2 )
{
float d1, d2;
d1 = p1.Dot(m_Plane.normal) - m_Plane.dist;
d2 = p2.Dot(m_Plane.normal) - m_Plane.dist;
if (d1 >= 0 && d2 >= 0)
return false;
if (d1 <= 0 && d2 <= 0)
return true;
float dt = d1 / (d1 - d2);
if (d1 > 0)
p1 = p1 + dt * (p2 - p1);
else
p2 = p1 + dt * (p2 - p1);
return true;
}
//////////////////////////////////////////////////////////////////////////
void SBrushFace::CalcTexCoords( SBrushVert &v )
{
Vec3d tVecx, tVecy;
float tShiftx, tShifty;
TextureVectors (tVecx, tVecy, tShiftx, tShifty);
v.st[0] = (v.xyz.Dot(tVecx)) + tShiftx;
v.st[1] = -((v.xyz.Dot(tVecy)) + tShifty);
}
//////////////////////////////////////////////////////////////////////////
void SBrushFace::DeletePrefabs(void)
{
/*
TPrefabItem *pi, *Next;
for (pi=m_Prefabs; pi; pi=Next)
{
Next = pi->Next;
delete pi;
}
*/
m_Prefabs = NULL;
}
///////////////////////////////////////////////////////////////////////////
float SBrushFace::CalcArea()
{
int nNumVertices=m_Poly->m_Pts.size();
Vec3d *vTempVecs=new Vec3d [nNumVertices];
for (int k=0;k<nNumVertices;k++)
{
SBrushVert vOrigVert=m_Poly->m_Pts[k];
vTempVecs[k]=vOrigVert.xyz;
} //k
m_fArea=::CalcArea(vTempVecs,nNumVertices,m_Plane.normal);
delete [] vTempVecs;
return (m_fArea);
}
///////////////////////////////////////////////////////////////////////////
void SBrushFace::CalcCenter()
{
m_vCenter(0,0,0);
int nNumVertices=m_Poly->m_Pts.size();
for (int k=0;k<nNumVertices;k++)
{
SBrushVert vOrigVert=m_Poly->m_Pts[k];
m_vCenter+=vOrigVert.xyz;
} //k
m_vCenter=m_vCenter/(float)nNumVertices;
}
//////////////////////////////////////////////////////////////////////////
void SBrushFace::BuildPrefabs_r(SBrushPoly *p, Vec3d& Area, Vec3d& Scale)
{
int i, i1, i2;
Vec3d mins, maxs;
Vec3d v, v1, v2;
Vec3d vup, vright, vpn, org;
SBrushPlane pl;
SBrushPoly *front, *back;
float size;
if (!p)
return;
p->CalcBounds(mins, maxs);
float a0 = Area[0];
float a1 = Area[1];
if (a0 < 2) a0 = 2;
if (a1 < 2) a1 = 2;
size = 99999.0f;
i = -1;
for (int n=0; n<p->m_Pts.size(); n++)
{
float s;
v = p->m_Pts[n].xyz - mins;
if ((s=v.Length()) < size)
{
i = n;
size = s;
}
}
if (!i)
i1 = p->m_Pts.size()-1;
else
i1 = i-1;
i2 = (i+1)%p->m_Pts.size();
v = p->m_Pts[i].xyz;
v1 = p->m_Pts[i1].xyz;
v2 = p->m_Pts[i2].xyz;
vup = v1 - v;
vright = v2 - v;
float si = vright.Length();
if (si-a0 > 0.1f)
{
Vec3d sp1, sp2;
sp1 = vright;
sp1.Normalize();
sp1 = v + sp1 * a0;
sp2 = vup;
sp2.Normalize();
sp2 = sp1 + sp2 * a1;
CreateBoundaryPlane(&m_Plane, sp1, sp2, &pl);
p->ClipByPlane(&pl, 0.1f, &front, &back);
BuildPrefabs_r(front, Area, Scale);
BuildPrefabs_r(back, Area, Scale);
if (front)
delete front;
if (back)
delete back;
return;
}
si = vup.Length();
if (si-a1 > 0.1f)
{
Vec3d sp1, sp2;
sp1 = vup;
sp1.Normalize();
sp1 = v + sp1 * a1;
sp2 = vright;
sp2.Normalize();
sp2 = sp1 + sp2 * a0;
CreateBoundaryPlane(&m_Plane, sp1, sp2, &pl);
p->ClipByPlane(&pl, 0.1f, &front, &back);
BuildPrefabs_r(front, Area, Scale);
BuildPrefabs_r(back, Area, Scale);
if (front)
delete front;
if (back)
delete back;
return;
}
SPrefabItem *pi = new SPrefabItem;
//Timur[9/16/2002]pi->Next = NULL;
//Timur[9/16/2002]pi->PrevLink =NULL;
//Timur[9/16/2002]pi->Link(m_Prefabs);
//Timur[7/3/2002]
//@ASK Andrey.
/*
pi->m_Geom = (CREPrefabGeom *)m_shader->m_REs[0];
CModelCgf *m = (CModelCgf *)pi->m_Geom->mModel;
*/
p->MakePlane(&pl);
vpn = pl.normal;
vup.Normalize();
vright.Normalize();
vright *= Scale[0];
vup *= Scale[1];
org = v;
Matrix44 mat;
mat.BuildFromVectors(vright, vup, vpn, org);
pi->m_Matrix = mat;
}
//////////////////////////////////////////////////////////////////////////
SBrushFace::~SBrushFace()
{
DeletePrefabs();
if (m_Poly)
delete m_Poly;
if (m_RE)
{
ReleaseRE();
}
}
//////////////////////////////////////////////////////////////////////////
void SBrushFace::BuildRE( const Matrix44 &worldTM )
{
if (!m_Prefabs)
{
// Delete previous render element.
if (m_RE)
ReleaseRE();
CREPolyMesh *re = (CREPolyMesh *)GetIEditor()->GetRenderer()->EF_CreateRE(eDATA_Poly);
m_RE = re;
//m_RE->m_DynMask = -1;
re->m_Plane.n = m_Plane.normal;
re->m_Plane.d = m_Plane.dist;
re->Srf = this;
//Timur[9/16/2002]
/*
SShader *eft = m_shader->mfGetTemplate(g_Globals.m_TemplateId);
if (m_shader && gNE[eft->m_Id].m_TessSize)
{
m_bTesselated = true;
TessSurf(re, this, gNE[eft->m_Id].m_TessSize);
}
else
*/
{
//m_bTesselated = false;
int numPts = m_Poly->m_Pts.size();
re->NumVerts = numPts;
re->TriVerts = new SMTriVert[numPts];
re->NumIndices = (numPts-2)*3;
re->Indices = new ushort[re->NumIndices];
SBrushVert *v = &m_Poly->m_Pts[0];
for (int i=re->NumVerts-1; i>=0; i--, v++)
{
re->TriVerts[i].vert = worldTM.TransformPointOLD(v->xyz);
re->TriVerts[i].dTC[0] = v->st[0];
re->TriVerts[i].dTC[1] = v->st[1];
re->TriVerts[i].lmTC[0] = v->st[0];
re->TriVerts[i].lmTC[1] = v->st[1];
}
ushort *vrtind = re->Indices;
for (i=0; i<numPts-2; i++, vrtind+=3)
{
vrtind[0] = 0;
vrtind[1] = i+1;
vrtind[2] = i+2;
}
}
}
//Timur[9/16/2002]
/*
if (m_shader && m_shader->m_REs.size()!=0)
m_shader->m_REs[0]->mfBuildGeometry(m_shader);
*/
}
void SBrushFace::ReleaseRE()
{
if (m_RE)
{
// Needed to delete pointers in same module.
CREPolyMesh *re = (CREPolyMesh*)m_RE;
if (re->TriVerts)
delete []re->TriVerts;
if (re->Indices)
delete []re->Indices;
re->TriVerts = 0;
re->Indices = 0;
re->NumVerts = 0;
re->NumIndices = 0;
}
}
//////////////////////////////////////////////////////////////////////////
void SBrushFace::BuildPrefabs(void)
{
//@ASK Andrey.
/*
DeletePrefabs();
if (!m_shader || m_shader->m_REs.size()==0 || m_shader->m_REs[0]->mfGetType() != eDATA_Prefab)
return;
CREPrefabGeom *pg = (CREPrefabGeom *)m_shader->m_REs[0];
CModelCgf *m = (CModelCgf *)pg->mModel;
Vec3d Area = m->m_BBox.max - m->m_BBox.min;
Vec3d Scale;
Scale[0] = m_TexInfo.scale[0];
Scale[1] = m_TexInfo.scale[1];
Scale[2] = 1.0f;
if (gcpCryIndEd->m_wndTextureBar.m_bAutoPrefab)
{
Vec3d v, v1, v2, vup, vright, mins, maxs;
int i, i1, i2;
SBrushPoly *p = m_Poly;
float size = 99999.0f;
p->CalcBounds(mins, maxs);
float a0 = Scale[0] * Area[0];
float a1 = Scale[1] * Area[1];
i = -1;
for (int n=0; n<p->m_Pts.size(); n++)
{
float s;
v = p->m_Pts[n].xyz - mins;
if ((s=v.Length()) < size)
{
i = n;
size = s;
}
}
if (!i)
i1 = p->m_Pts.size()-1;
else
i1 = i-1;
i2 = (i+1)%p->m_Pts.size();
v = p->m_Pts[i].xyz;
v1 = p->m_Pts[i1].xyz;
v2 = p->m_Pts[i2].xyz;
vup = v1 - v;
vright = v2 - v;
float s = vright.Length();
float t = s / a0;
int ti = (int)t;
float tf = t - ti;
if (tf > 0.5f)
ti++;
if (ti <= 0)
ti = 1;
Area[0] = s / ti;
Scale[0] = Area[0] / (m->m_BBox.max.x - m->m_BBox.min.x);
s = vup.Length();
t = s / a1;
ti = (int)t;
tf = t - ti;
if (tf > 0.5f)
ti++;
if (ti <= 0)
ti = 1;
Area[1] = s / ti;
Scale[1] = Area[1] / (m->m_BBox.max.y - m->m_BBox.min.y);
}
else
{
Area[0] *= Scale[0];
Area[1] *= Scale[1];
}
BuildPrefabs_r(m_Poly, Area, Scale);
*/
}
//////////////////////////////////////////////////////////////////////////
void SBrushFace::ClipPrefab(SPrefabItem *pi)
{
//@ASK Andrey.
/*
CComModel *fr, *md;
if (pi->m_Model)
md = pi->m_Model;
else
md = (CComModel *)pi->m_Geom->mModel;
fr = md->mfClip(&m_Plane, pi->m_Matrix);
if (fr)
{
if (pi->m_Model)
delete md;
pi->m_Model = fr;
}
*/
}
////////////////////////////////////////////////////////////////////
bool SBrushFace::IsIntersecting(const SBrushPlane &Plane)
{
if (!m_Poly)
return (false);
bool bFront=false;
bool bBack=false;
for (int k=0;k<m_Poly->m_Pts.size();k++)
{
Vec3d Vert=m_Poly->m_Pts[k].xyz;
float dist=(Plane.normal|Vert)-Plane.dist;
if (dist>=0)
{
if (bBack)
return (true);
bFront=true;
}
else
{
if (bFront)
return (true);
bBack=true;
}
} //k
return (false);
}
////////////////////////////////////////////////////////////////////
bool SBrushFace::IsIntersecting(SBrush *Vol)
{
for (int i=0; i<Vol->m_Faces.size(); i++)
{
SBrushFace *f = Vol->m_Faces[i];
//check if the face intersect the volume side's plane
if (IsIntersecting(f->m_Plane))
{
//if is it the case,check if the volume face intersect the face's plane
if (f->IsIntersecting(m_Plane))
return (true);
}
}//i
return (false);
}
//////////////////////////////////////////////////////////////////////////
void SBrushFace::FitTexture(int nX, int nY)
{
SBrushPoly *w;
Vec3d mins,maxs;
int i;
float width, height;
float rot_width, rot_height;
float cosv,sinv,ang;
float min_t, min_s, max_t, max_s;
float s,t;
Vec3d vecs[2];
Vec3d coords[4];
SMapTexInfo *td;
if (nY < 1)
nY = 1;
if (nX < 1)
nX = 1;
mins=SetMaxBB();
maxs=SetMinBB();
td = &m_TexInfo;
w = m_Poly;
if (!w)
return;
w->CalcBounds(mins, maxs);
ang = td->rotate / 180 * gf_PI;
sinv = sinf(ang);
cosv = cosf(ang);
m_Plane.CalcTextureAxis(vecs[0], vecs[1], 1);
min_s = mins | vecs[0];
min_t = mins | vecs[1];
max_s = maxs | vecs[0];
max_t = maxs | vecs[1];
width = max_s - min_s;
height = max_t - min_t;
coords[0][0] = min_s;
coords[0][1] = min_t;
coords[1][0] = max_s;
coords[1][1] = min_t;
coords[2][0] = min_s;
coords[2][1] = max_t;
coords[3][0] = max_s;
coords[3][1] = max_t;
min_s = min_t = 99999;
max_s = max_t = -99999;
for (i=0; i<4; i++)
{
s = cosv * coords[i][0] - sinv * coords[i][1];
t = sinv * coords[i][0] + cosv * coords[i][1];
if (i&1)
{
if (s > max_s)
max_s = s;
}
else
{
if (s < min_s)
min_s = s;
if (i<2)
{
if (t < min_t)
min_t = t;
}
else
{
if (t > max_t)
max_t = t;
}
}
}
rot_width = (max_s - min_s);
rot_height = (max_t - min_t);
//@ASK Andrey.
/*
float temp;
td->scale[0] = -(rot_width/((float)(gNE[m_shader->m_Id].m_Tex->m_Width*nX)));
td->scale[1] = -(rot_height/((float)(gNE[m_shader->m_Id].m_Tex->m_Height*nY)));
td->shift[0] = min_s/td->scale[0];
temp = (int)(td->shift[0] / (gNE[m_shader->m_Id].m_Tex->m_Width*nX));
temp = (temp+1)*gNE[m_shader->m_Id].m_Tex->m_Width*nX;
td->shift[0] = (int)(temp - td->shift[0])%(gNE[m_shader->m_Id].m_Tex->m_Width*nX);
td->shift[1] = min_t/td->scale[1];
temp = (int)(td->shift[1] / (gNE[m_shader->m_Id].m_Tex->m_Height*nY));
temp = (temp+1)*(gNE[m_shader->m_Id].m_Tex->m_Height*nY);
td->shift[1] = (int)(temp - td->shift[1])%(gNE[m_shader->m_Id].m_Tex->m_Height*nY);
*/
}

154
Editor/Brush/BrushFace.h Normal file
View File

@@ -0,0 +1,154 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: brushface.h
// Version: v1.00
// Created: 9/7/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History: Based on Andrey's Indoor editor.
//
////////////////////////////////////////////////////////////////////////////
#ifndef __brushface_h__
#define __brushface_h__
#if _MSC_VER > 1000
#pragma once
#endif
#include "BrushPlane.h"
// forward declarations.
class CREPrefabGeom;
class CRendElement;
struct SBrush;
struct SBrushPlane;
struct SBrushPoly;
struct SBrushVert;
class CBrushMtl;
//////////////////////////////////////////////////////////////////////////
/** Texture info of face.
*/
struct SMapTexInfo
{
char name[64];
float shift[2];
float rotate;
float scale[2];
int contents;
int flags;
int value;
SMapTexInfo()
{
name[0] = 0;
shift[0] = shift[1] = 0;
scale[0] = scale[1] = 0.5f;
rotate = 0;
contents = 0;
flags = 0;
value = 0;
}
void SetName(const char *p)
{
strcpy(name, p);
}
};
/** Prefab geometry used instead of texture.
*/
struct SPrefabItem
{
SPrefabItem()
{
m_Geom = NULL;
m_Model = NULL;
}
CREPrefabGeom *m_Geom;
Matrix44 m_Matrix;
//CComModel *m_Model;
IStatObj *m_Model;
};
/** Single Face of brush.
*/
struct SBrushFace
{
SBrushFace()
{
m_Poly = 0;
m_mtl = 0;
m_RE = 0;
m_Prefabs = 0;
m_color = 0xFFFFFFFF;
m_fArea = 0;
ZeroStruct(m_PlanePts);
m_vCenter(0,0,0);
}
~SBrushFace();
SBrushFace& operator = (const SBrushFace& f);
//check if the face intersect the brush
bool IsIntersecting(SBrush *Vol);
//check if the face intersect a plane
bool IsIntersecting(const SBrushPlane &Plane);
float CalcArea();
void CalcCenter();
void ClipPrefab(SPrefabItem *pi);
void DeletePrefabs();
void CalcTexCoords( SBrushVert &v );
void TextureVectors(Vec3d& tVecx, Vec3d& tVecy, float& tShiftx, float& tShifty);
void BuildPrefabs();
//! Build Render element for this face using specified world matrix.
void BuildRE( const Matrix44 &worldTM );
void BuildPrefabs_r(SBrushPoly *p, Vec3d& Area, Vec3d& Scale);
void FitTexture(int nX, int nY);
bool ClipLine(Vec3d& p1, Vec3d& p2);
void Draw();
//! Make plane of brush face.
void MakePlane();
private:
void ReleaseRE();
public:
SBrushPlane m_Plane;
SBrushPoly* m_Poly;
Vec3d m_PlanePts[3];
SMapTexInfo m_TexInfo;
//! Color of face.
COLORREF m_color;
//! Material used for this brush.
CBrushMtl* m_mtl;
//! Shader used for this face.
//IShader* m_shader;
//! Render element created for this face.
CRendElement* m_RE;
//! List of prefabs.
SPrefabItem *m_Prefabs;
//! Stores face center.
Vec3d m_vCenter;
//! Area of face.
float m_fArea;
//int m_dwFlags;
///bool m_bTesselated;
};
#endif // __brushface_h__

View File

@@ -0,0 +1,138 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: brushindoor.cpp
// Version: v1.00
// Created: 4/12/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "BrushIndoor.h"
#include "Brush.h"
#include "Objects\BrushObject.h"
#include <I3DEngine.h>
//////////////////////////////////////////////////////////////////////////
CBrushIndoor::CBrushIndoor()
{
m_buildingId = -1;
}
//////////////////////////////////////////////////////////////////////////
CBrushIndoor::~CBrushIndoor()
{
}
//////////////////////////////////////////////////////////////////////////
void CBrushIndoor::MakeIndoor()
{
ReleaseIndoor();
IndoorBaseInterface bi;
bi.m_pLog = GetIEditor()->GetSystem()->GetILog();
bi.m_pRenderer = GetIEditor()->GetSystem()->GetIRenderer();
bi.m_p3dEngine = GetIEditor()->GetSystem()->GetI3DEngine();
bi.m_pConsole = GetIEditor()->GetSystem()->GetIConsole();
bi.m_pSystem = GetIEditor()->GetSystem();
m_buildingId = GetBuildMgr()->CreateBuilding(bi);
GetBuildMgr()->SetBuildingPos( Vec3(0,0,0),m_buildingId );
}
//////////////////////////////////////////////////////////////////////////
void CBrushIndoor::ReleaseIndoor()
{
if (m_buildingId)
{
GetBuildMgr()->DeleteBuilding(m_buildingId);
m_buildingId = -1;
}
}
//////////////////////////////////////////////////////////////////////////
IIndoorBase* CBrushIndoor::GetBuildMgr()
{
return GetIEditor()->Get3DEngine()->GetBuildingManager();
}
//////////////////////////////////////////////////////////////////////////
void CBrushIndoor::AddObject( IStatObj *object )
{
if (m_buildingId >= 0)
{
GetBuildMgr()->SetOutsideStatObj( m_buildingId,object,false );
GetBuildMgr()->SetBuildingBBox( object->GetBoxMin(),object->GetBoxMax(),m_buildingId );
}
}
//////////////////////////////////////////////////////////////////////////
void CBrushIndoor::RemoveObject( IStatObj *object )
{
if (m_buildingId >= 0)
{
GetBuildMgr()->SetOutsideStatObj( m_buildingId,object,true );
}
}
//////////////////////////////////////////////////////////////////////////
void CBrushIndoor::UpdateObject( IStatObj *object )
{
if (m_buildingId >= 0)
{
//GetBuildMgr()->SetOutsideStatObj( m_buildingId,object,true );
}
}
//////////////////////////////////////////////////////////////////////////
void CBrushIndoor::SetBounds( const BBox &bbox )
{
if (m_buildingId >= 0)
{
GetBuildMgr()->SetBuildingBBox( bbox.min,bbox.max,m_buildingId );
}
}
//////////////////////////////////////////////////////////////////////////
void CBrushIndoor::AddBrush( CBrushObject *brushObj )
{
m_brushes.insert( brushObj );
}
//////////////////////////////////////////////////////////////////////////
void CBrushIndoor::RemoveBrush( CBrushObject *brushObj )
{
m_brushes.erase( brushObj );
}
//////////////////////////////////////////////////////////////////////////
void CBrushIndoor::RecalcBounds()
{
BBox bounds,box;
bounds.Reset();
for (Brushes::iterator it = m_brushes.begin(); it != m_brushes.end(); ++it)
{
CBrushObject *brushObj = *it;
brushObj->GetBoundBox( box );
bounds.Add( box.min );
bounds.Add( box.max );
}
if (m_buildingId >= 0)
{
GetBuildMgr()->SetBuildingBBox( bounds.min,bounds.max,m_buildingId );
}
}
//////////////////////////////////////////////////////////////////////////
void CBrushIndoor::GetObjects( std::vector<CBrushObject*> &objects )
{
objects.clear();
objects.insert( objects.end(),m_brushes.begin(),m_brushes.end() );
}

View File

@@ -0,0 +1,61 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: brushindoor.h
// Version: v1.00
// Created: 4/12/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __brushindoor_h__
#define __brushindoor_h__
#pragma once
class CBrushObject;
/** Holds reference to indoor building to which brushes are added.
*/
class CBrushIndoor
{
public:
CBrushIndoor();
~CBrushIndoor();
struct IIndoorBase* GetBuildMgr();
//! Add new brush object to indoor.
void AddBrush( CBrushObject *brushObj );
//! Remove brush object from indoor.
void RemoveBrush( CBrushObject *brushObj );
void MakeIndoor();
void ReleaseIndoor();
void AddObject( IStatObj *object );
void RemoveObject( IStatObj *object );
void UpdateObject( IStatObj *object );
//! Sound indoor bounding box in world space.
void SetBounds( const BBox &bbox );
//! Recalculate bounding box.
void RecalcBounds();
void GetObjects( std::vector<CBrushObject*> &objects );
private:
// Id of building.
int m_buildingId;
typedef std::set<CBrushObject*> Brushes;
Brushes m_brushes;
};
#endif // __brushindoor_h__

38
Editor/Brush/BrushMtl.cpp Normal file
View File

@@ -0,0 +1,38 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: brushmtl.cpp
// Version: v1.00
// Created: 2/12/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "BrushMtl.h"
#define BASE_SHADER_NAME "$Editor"
#define DEFAULT_SHADER "TemplDecal"
#define DEFAULT_TEXTURE "Checker.tga"
//////////////////////////////////////////////////////////////////////////
CBrushMtl::CBrushMtl()
{
m_shaderItem.m_pShader = 0;
m_shaderItem.m_pShaderResources = 0;
// Default shader.
m_shaderName = DEFAULT_SHADER;
m_sr.m_Textures[EFTT_DIFFUSE].m_Name = DEFAULT_TEXTURE;
}
//////////////////////////////////////////////////////////////////////////
void CBrushMtl::ReloadShader()
{
m_shaderItem = GetIEditor()->GetRenderer()->EF_LoadShaderItem( BASE_SHADER_NAME,eSH_Misc,true,m_shaderName,0,&m_sr );
}

48
Editor/Brush/BrushMtl.h Normal file
View File

@@ -0,0 +1,48 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: brushmtl.h
// Version: v1.00
// Created: 2/12/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __brushmtl_h__
#define __brushmtl_h__
#pragma once
/** Material used by brush.
*/
class CBrushMtl : public CRefCountBase
{
public:
CBrushMtl();
IShader* GetShader() const { return m_shaderItem.m_pShader; };
SRenderShaderResources* GetShaderResources() const { return m_shaderItem.m_pShaderResources; };
ITexPic* GetEditorTexture() const
{
if (m_shaderItem.m_pShaderResources->m_Textures[EFTT_DIFFUSE])
return m_shaderItem.m_pShaderResources->m_Textures[EFTT_DIFFUSE]->m_TU.m_ITexPic;
return NULL;
}
//! Reload shader description inside renderer.
void ReloadShader();
private:
SShaderItem m_shaderItem;
SInputShaderResources m_sr;
CString m_shaderName;
};
// Typedef smart pointer to brush material.
typedef TSmartPtr<CBrushMtl> CBrushMtlPtr;
#endif // __brushmtl_h__

View File

@@ -0,0 +1 @@
#include "StdAfx.h"

View File

@@ -0,0 +1,30 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: brushmtllib.h
// Version: v1.00
// Created: 2/12/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __brushmtllib_h__
#define __brushmtllib_h__
#pragma once
/** Library of materials used for brush creation.
*/
class CBrushMtlLib
{
public:
private:
// Array of all available materials.
std::vector<CBrushMtlPtr> m_materials;
};
#endif // __brushmtllib_h__

120
Editor/Brush/BrushPanel.cpp Normal file
View File

@@ -0,0 +1,120 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: brushpanel.cpp
// Version: v1.00
// Created: 2/12/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "BrushPanel.h"
#include "..\Objects\ObjectManager.h"
#include "..\Objects\BrushObject.h"
// CBrushPanel dialog
IMPLEMENT_DYNAMIC(CBrushPanel, CXTResizeDialog)
CBrushPanel::CBrushPanel(CWnd* pParent /*=NULL*/)
: CXTResizeDialog(CBrushPanel::IDD, pParent)
{
m_brushObj = 0;
Create( IDD,pParent );
}
//////////////////////////////////////////////////////////////////////////
CBrushPanel::~CBrushPanel()
{
}
//////////////////////////////////////////////////////////////////////////
void CBrushPanel::DoDataExchange(CDataExchange* pDX)
{
CXTResizeDialog::DoDataExchange(pDX);
//DDX_Control(pDX, IDC_SIDES, m_sides);
DDX_Control(pDX, IDC_RESETSIZE, m_resetSizeBtn);
DDX_Control(pDX, IDC_REFRESH, m_reloadBtn);
}
//////////////////////////////////////////////////////////////////////////
void CBrushPanel::SetBrush( CBrushObject *obj )
{
m_brushObj = obj;
}
BEGIN_MESSAGE_MAP(CBrushPanel, CXTResizeDialog)
//ON_CBN_SELENDOK(IDC_SIDES, OnCbnSelendokSides)
ON_BN_CLICKED(IDC_RESETSIZE, OnBnClickedResetsize)
ON_BN_CLICKED(IDC_REFRESH, OnBnClickedReload)
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////////
BOOL CBrushPanel::OnInitDialog()
{
CXTResizeDialog::OnInitDialog();
/*
CString str;
for (int i = 0; i < 10; i++)
{
str.Format( "%d",i );
m_sides.AddString( str );
}
*/
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
//////////////////////////////////////////////////////////////////////////
void CBrushPanel::OnCbnSelendokSides()
{
}
//////////////////////////////////////////////////////////////////////////
void CBrushPanel::OnBnClickedResetsize()
{
if (m_brushObj)
{
m_brushObj->ResetToPrefabSize();
}
else
{
// Reset all selected brushes.
CSelectionGroup *selection = GetIEditor()->GetSelection();
for (int i = 0; i < selection->GetCount(); i++)
{
CBaseObject *pBaseObj = selection->GetObject(i);
if (pBaseObj->IsKindOf(RUNTIME_CLASS(CBrushObject)))
((CBrushObject*)pBaseObj)->ResetToPrefabSize();
}
}
}
//////////////////////////////////////////////////////////////////////////
void CBrushPanel::OnBnClickedReload()
{
if (m_brushObj)
{
m_brushObj->ReloadPrefabGeometry();
}
else
{
// Reset all selected brushes.
CSelectionGroup *selection = GetIEditor()->GetSelection();
for (int i = 0; i < selection->GetCount(); i++)
{
CBaseObject *pBaseObj = selection->GetObject(i);
if (pBaseObj->IsKindOf(RUNTIME_CLASS(CBrushObject)))
((CBrushObject*)pBaseObj)->ReloadPrefabGeometry();
}
}
}

60
Editor/Brush/BrushPanel.h Normal file
View File

@@ -0,0 +1,60 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: brushpanel.h
// Version: v1.00
// Created: 2/12/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __BrushPanel_h__
#define __BrushPanel_h__
#include "afxwin.h"
#pragma once
#include "XTToolkit.h"
class CBrushObject;
// CBrushPanel dialog
class CBrushPanel : public CXTResizeDialog
{
DECLARE_DYNAMIC(CBrushPanel)
public:
CBrushPanel(CWnd* pParent = NULL); // standard constructor
virtual ~CBrushPanel();
void SetBrush( CBrushObject *obj );
// Dialog Data
enum { IDD = IDD_PANEL_BRUSH };
protected:
virtual void OnOK() {};
virtual void OnCancel() {};
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnInitDialog();
afx_msg void OnCbnSelendokSides();
afx_msg void OnBnClickedReload();
DECLARE_MESSAGE_MAP()
CBrushObject *m_brushObj;
// Controls.
//CComboBox m_sides;
CCustomButton m_resetSizeBtn;
CCustomButton m_reloadBtn;
afx_msg void OnBnClickedResetsize();
};
#endif // __BrushPanel_h__

160
Editor/Brush/BrushPlane.cpp Normal file
View File

@@ -0,0 +1,160 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: brushplane.cpp
// Version: v1.00
// Created: 9/7/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "BrushPlane.h"
#include "BrushPoly.h"
// Local variables.
namespace
{
Vec3d s_baseAxis[] =
{
Vec3d(0,0,1), Vec3d(1,0,0), Vec3d(0,-1,0), Vec3d(1,0,0), Vec3d(0,-1,0), // floor
Vec3d(0,0,-1), Vec3d(1,0,0), Vec3d(0,-1,0), Vec3d(1,0,0), Vec3d(0,-1,0), // ceiling
Vec3d(1,0,0), Vec3d(0,1,0), Vec3d(0,0,-1), Vec3d(0,1,0), Vec3d(0,0,-1), // west wall
Vec3d(-1,0,0), Vec3d(0,1,0), Vec3d(0,0,-1), Vec3d(0,1,0), Vec3d(0,0,-1), // east wall
Vec3d(0,1,0), Vec3d(1,0,0), Vec3d(0,0,-1), Vec3d(1,0,0), Vec3d(0,0,-1), // south wall
Vec3d(0,-1,0), Vec3d(1,0,0), Vec3d(0,0,-1), Vec3d(1,0,0), Vec3d(0,0,-1) // north wall
};
}
#define PLANE_NORMAL_EPSILON 0.0001f
#define PLANE_DIST_EPSILON 0.001f
//////////////////////////////////////////////////////////////////////////
//
// SBrushPlane implementation
//
//////////////////////////////////////////////////////////////////////////
int SBrushPlane::Equal(SBrushPlane *b, int flip)
{
Vec3d norm;
float dst;
if (flip)
{
norm[0] = -b->normal[0];
norm[1] = -b->normal[1];
norm[2] = -b->normal[2];
dst = -b->dist;
}
else
{
norm[0] = b->normal[0];
norm[1] = b->normal[1];
norm[2] = b->normal[2];
dst = b->dist;
}
if (fabs(norm[0]-normal[0]) < PLANE_NORMAL_EPSILON &&
fabs(norm[1]-normal[1]) < PLANE_NORMAL_EPSILON &&
fabs(norm[2]-normal[2]) < PLANE_NORMAL_EPSILON &&
fabs(dst-dist) < PLANE_DIST_EPSILON)
return true;
return false;
}
//////////////////////////////////////////////////////////////////////////
void SBrushPlane::CalcTextureAxis(Vec3d& xv, Vec3d& yv, bool bTex)
{
int bestaxis;
float dot,best;
int i;
best = 0;
bestaxis = 0;
for (i=0 ; i<6 ; i++)
{
dot = normal | s_baseAxis[i*5];
if (dot > best)
{
best = dot;
bestaxis = i;
}
}
if (bTex)
{
xv = s_baseAxis[bestaxis*5+1];
yv = s_baseAxis[bestaxis*5+2];
}
else
{
xv = s_baseAxis[bestaxis*5+3];
yv = s_baseAxis[bestaxis*5+4];
}
}
//////////////////////////////////////////////////////////////////////////
SBrushPoly *SBrushPlane::CreatePoly()
{
int i, x;
float max, v;
Vec3d org, vright, vup;
SBrushPoly *p;
max = -99999;
x = -1;
for (i=0 ; i<3; i++)
{
v = (float)fabs(normal[i]);
if (v > max)
{
x = i;
max = v;
}
}
if (x==-1)
{
CLogFile::WriteLine("Error: SBrushPlane::CreatePoly: no axis found");
return NULL;
}
vup(0,0,0);
if (x != 2)
vup = Vec3d(0,0,1);
else
vup = Vec3d(1,0,0);
v = vup | normal;
vup += normal * -v;
vup.Normalize();
org = normal * dist;
vright = vup ^ normal;
vup *= 32768.0f;
vright *= 32768.0f;
// project a really big axis aligned box onto the plane
p = new SBrushPoly(4);
p->m_Pts[0].xyz = org - vright;
p->m_Pts[0].xyz += vup;
p->m_Pts[1].xyz = org + vright;
p->m_Pts[1].xyz += vup;
p->m_Pts[2].xyz = org + vright;
p->m_Pts[2].xyz -= vup;
p->m_Pts[3].xyz = org - vright;
p->m_Pts[3].xyz -= vup;
return p;
}

67
Editor/Brush/BrushPlane.h Normal file
View File

@@ -0,0 +1,67 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: brushplane.h
// Version: v1.00
// Created: 9/7/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History: Based on Andrey's Indoor editor.
//
////////////////////////////////////////////////////////////////////////////
#ifndef __brushplane_h__
#define __brushplane_h__
#if _MSC_VER > 1000
#pragma once
#endif
struct SBrushPoly;
struct SBrushPlane
{
SBrushPlane()
{
type = 0;
dist = 0;
normal(0,0,0);
}
// Makes the palne given 3 points
void Make( const Vec3d &p1, const Vec3d &p2, const Vec3d &p3)
{
normal = (p1 - p2)^(p3 - p2);
normal.Normalize();
dist = normal.Dot(p2);
}
void CalcTextureAxis(Vec3d& xv, Vec3d& yv, bool bTex);
SBrushPoly *CreatePoly();
int Equal(SBrushPlane *b, int flip);
void Invert(SBrushPlane *p)
{
normal = Vec3d(0,0,0) - p->normal;
dist = -p->dist;
}
_inline bool operator==(const SBrushPlane& p) const
{
if ( p.normal.x==normal.x && p.normal.y==normal.y && p.normal.z==normal.z && p.dist==dist)
return true;
return false;
}
_inline bool operator!=(const SBrushPlane& p) const
{
if ( p.normal.x==normal.x && p.normal.y==normal.y && p.normal.z==normal.z && p.dist==dist)
return false;
return true;
}
Vec3d normal;
float dist;
int type;
};
#endif // __brushplane_h__

252
Editor/Brush/BrushPoly.cpp Normal file
View File

@@ -0,0 +1,252 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: BrushPoly.cpp
// Version: v1.00
// Created: 8/7/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History: Based on Andrey's Indoor editor.
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "BrushPoly.h"
#include "BrushPlane.h"
//////////////////////////////////////////////////////////////////////////
// SBrushPoly implementation.
//////////////////////////////////////////////////////////////////////////
#define POLY_DOT_EPSILON 0.001f
void SBrushPoly::ClipByPlane(SBrushPlane *p, float eps, SBrushPoly **front, SBrushPoly **back)
{
float dists[64];
int sides[64];
int counts[3];
float dot;
int i, j;
SBrushVert *p1, *p2;
Vec3d mid;
SBrushPoly *f, *b;
counts[0] = counts[1] = counts[2] = 0;
for (i=0; i<m_Pts.size(); i++)
{
dot = (m_Pts[i].xyz | p->normal) - p->dist;
dists[i] = dot;
if (dot > eps)
sides[i] = 0;
else
if (dot < -eps)
sides[i] = 1;
else
sides[i] = 2;
counts[sides[i]]++;
}
sides[i] = sides[0];
dists[i] = dists[0];
*front = *back = NULL;
if (!counts[0])
{
*back = this;
return;
}
if (!counts[1])
{
*front = this;
return;
}
*front = f = new SBrushPoly;
*back = b = new SBrushPoly;
// Reserve space for at least 4 points.
f->m_Pts.reserve(4);
b->m_Pts.reserve(4);
SBrushVert v;
for (i=0; i<m_Pts.size(); i++)
{
p1 = &m_Pts[i];
if (sides[i] == 2)
{
f->m_Pts.push_back(*p1);
b->m_Pts.push_back(*p1);
continue;
}
if (sides[i] == 0)
f->m_Pts.push_back(*p1);
if (sides[i] == 1)
b->m_Pts.push_back(*p1);
if (sides[i+1] == 2 || sides[i+1] == sides[i])
continue;
p2 = &m_Pts[(i+1)%m_Pts.size()];
dot = dists[i] / (dists[i]-dists[i+1]);
for (j=0; j<3; j++)
{
if (p->normal[j] == 1)
mid[j] = p->dist;
else
if (p->normal[j] == -1)
mid[j] = -p->dist;
else
mid[j] = p1->xyz[j] + dot*(p2->xyz[j]-p1->xyz[j]);
}
v.xyz = mid;
f->m_Pts.push_back(v);
b->m_Pts.push_back(v);
}
}
//////////////////////////////////////////////////////////////////////////
SBrushPoly *SBrushPoly::ClipByPlane(SBrushPlane *split, bool keep)
{
float dists[64];
int sides[64];
int counts[3];
float dot;
int i, j;
SBrushVert *p1, *p2;
//SBrushPoly *newp;
counts[0] = counts[1] = counts[2] = 0;
for (i=0; i<m_Pts.size(); i++)
{
dot = (m_Pts[i].xyz | split->normal) - split->dist;
dists[i] = dot;
if (dot > POLY_DOT_EPSILON)
sides[i] = 0;
else
if (dot < -POLY_DOT_EPSILON)
sides[i] = 1;
else
sides[i] = 2;
counts[sides[i]]++;
}
sides[i] = sides[0];
dists[i] = dists[0];
if (keep && !counts[0] && !counts[1])
return this;
if (!counts[0])
{
delete this;
return NULL;
}
if (!counts[1])
return this;
//newp = new SBrushPoly;
SBrushVert v;
static std::vector<SBrushVert> newpoints;
newpoints.clear();
newpoints.reserve(16);
for (i=0; i<m_Pts.size(); i++)
{
p1 = &m_Pts[i];
if (sides[i] == 2)
{
//newp->m_Pts.push_back(*p1);
newpoints.push_back(*p1);
continue;
}
if (sides[i] == 0)
//newp->m_Pts.push_back(*p1);
newpoints.push_back(*p1);
if (sides[i+1] == 2 || sides[i+1] == sides[i])
continue;
p2 = &m_Pts[(i+1)%m_Pts.size()];
dot = dists[i] / (dists[i]-dists[i+1]);
for (j=0; j<3 ; j++)
{
if (split->normal[j] == 1)
v.xyz[j] = (float)split->dist;
else
if (split->normal[j] == -1)
v.xyz[j] = -(float)split->dist;
else
v.xyz[j] = p1->xyz[j] + dot*(p2->xyz[j]-p1->xyz[j]);
}
for (j=0; j<2; j++)
{
if (split->normal[j] == 1)
v.st[j] = (float)split->dist;
else
if (split->normal[j] == -1)
v.st[j] = -(float)split->dist;
else
v.st[j] = p1->st[j] + dot*(p2->st[j]-p1->st[j]);
}
//newp->m_Pts.push_back(v);
newpoints.push_back(v);
}
m_Pts = newpoints;
//delete this;
//return newp;
return this;
}
//////////////////////////////////////////////////////////////////////////
void SBrushPoly::CalcBounds(Vec3d& mins, Vec3d& maxs)
{
mins=SetMaxBB();
maxs=SetMinBB();
for (int i=0; i<m_Pts.size(); i++)
{
AddToBounds(m_Pts[i].xyz, mins, maxs);
}
}
//////////////////////////////////////////////////////////////////////////
void SBrushPoly::MakePlane(SBrushPlane *pl)
{
Vec3d v1 = m_Pts[1].xyz - m_Pts[0].xyz;
Vec3d v2 = m_Pts[2].xyz - m_Pts[0].xyz;
pl->normal = v2 ^ v1;
pl->normal.Normalize();
pl->dist = m_Pts[0].xyz | pl->normal;
}
//////////////////////////////////////////////////////////////////////////
float SBrushPoly::Area()
{
int i;
Vec3d d1, d2, cross;
float total;
total = 0;
for (i=2; i<m_Pts.size(); i++)
{
d1 = m_Pts[i-1].xyz - m_Pts[0].xyz;
d2 = m_Pts[i].xyz - m_Pts[0].xyz;
cross = d1 ^ d2;
total += 0.5 * cross.Length();
}
return total;
}

50
Editor/Brush/BrushPoly.h Normal file
View File

@@ -0,0 +1,50 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: brushpoly.h
// Version: v1.00
// Created: 9/7/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History: Based on Andrey's Indoor editor.
//
////////////////////////////////////////////////////////////////////////////
#ifndef __brushpoly_h__
#define __brushpoly_h__
#if _MSC_VER > 1000
#pragma once
#endif
struct SBrushPlane;
/** Brush vertex used in SBrushPoly structure.
*/
struct SBrushVert
{
Vec3d xyz;
float st[2];
};
/** Brush polygon.
*/
struct SBrushPoly
{
SBrushPoly(int nv) { m_Pts.resize(nv); }
SBrushPoly() {}
SBrushPoly& operator = (const SBrushPoly& src) { m_Pts = src.m_Pts; return *this; }
SBrushPoly *ClipByPlane(SBrushPlane *p, bool keep);
void ClipByPlane(SBrushPlane *p, float eps, SBrushPoly **front, SBrushPoly **back);
void CalcBounds(Vec3d& mins, Vec3d& maxs);
void MakePlane(SBrushPlane *pl);
float Area();
std::vector<SBrushVert> m_Pts;
};
#endif // __brushpoly_h__

360
Editor/Brush/BrushTool.cpp Normal file
View File

@@ -0,0 +1,360 @@
`////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
// File name: BrushTool.cpp
// Version: v1.00
// Created: 11/1/2002 by Timur.
// Compilers: Visual C++ 6.0
// Description: Terrain Modification Tool implementation.
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "BrushTool.h"
#include "..\Viewport.h"
#include "Brush.h"
#include "..\Objects\ObjectManager.h"
#include "..\Objects\BrushObject.h"
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CBrushTool,CEditTool)
//////////////////////////////////////////////////////////////////////////
CBrushTool::CBrushTool()
{
m_IEditor = 0;
m_mode = BrushNoMode;
m_bMouseCaptured = false;
m_lastBrushBounds = BBox( Vec3(-32,-32,-32),Vec3(32,32,32) );
}
//////////////////////////////////////////////////////////////////////////
CBrushTool::~CBrushTool()
{
}
//////////////////////////////////////////////////////////////////////////
void CBrushTool::BeginEditParams( IEditor *ie,int flags )
{
m_IEditor = ie;
}
//////////////////////////////////////////////////////////////////////////
void CBrushTool::EndEditParams()
{
}
void::CBrushTool::Display( DisplayContext &dc )
{
CalcLastBrushSize();
}
bool CBrushTool::OnLButtonDown( CViewport *view,UINT nFlags,CPoint point )
{
m_mode = BrushNoMode;
m_mouseDownPos = point;
if (nFlags & MK_SHIFT)
{
// Enable Create or sheer mode.
if (GetIEditor()->GetSelection()->IsEmpty())
{
// Create new brush.
m_mode = BrushCreateMode;
view->BeginUndo();
view->CaptureMouse();
m_bMouseCaptured = true;
return true;
}
}
bool bMouseClickedSelected = false;
// If clicked within selected brush. move this brush.
ObjectHitInfo hitInfo(view,point);
if (view->HitTest( point,hitInfo ))
{
if (hitInfo.object->GetType() == OBJTYPE_BRUSH && hitInfo.object->IsSelected())
{
bMouseClickedSelected = true;
// Only Left buttons should be pressed (no combinations)
if (nFlags == MK_LBUTTON)
{
m_mode = BrushMoveMode;
view->BeginUndo();
view->CaptureMouse();
m_bMouseCaptured = true;
return true;
}
}
}
if (nFlags & MK_SHIFT)
{
if (!bMouseClickedSelected)
{
// Clicked outside of selected objects.
// So start streching brushes.
//GetIEditor()->ClearSelection();
bool bShear = (nFlags & MK_CONTROL) != 0;
m_mode = BrushStretchMode;
view->BeginUndo();
view->CaptureMouse();
m_bMouseCaptured = true;
// Select brush drag sides.
CSelectionGroup *selection = GetIEditor()->GetSelection();
for (int i = 0; i < selection->GetCount(); i++)
{
if (!selection->GetObject(i)->IsKindOf(RUNTIME_CLASS(CBrushObject)))
continue;
CBrushObject *brushObj = (CBrushObject*)selection->GetObject(i);
Vec3 raySrc,rayDir;
view->ViewToWorldRay( point,raySrc,rayDir );
brushObj->SelectBrushSide( raySrc,rayDir,bShear );
}
m_IEditor->UpdateViews(eUpdateObjects);
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CBrushTool::OnLButtonUp( CViewport *view,UINT nFlags,CPoint point )
{
bool bResult = false;
if (m_mode == BrushMoveMode)
{
view->AcceptUndo( "Move Brush" );
bResult = true;
}
else if (m_mode == BrushCreateMode)
{
view->AcceptUndo( "Create Brush" );
bResult = true;
}
else if (m_mode == BrushStretchMode)
{
view->AcceptUndo( "Sheer Brush(s)" );
bResult = true;
}
if (m_bMouseCaptured)
{
view->ReleaseMouse();
}
m_mode = BrushNoMode;
return bResult;
}
//////////////////////////////////////////////////////////////////////////
bool CBrushTool::OnMouseMove( CViewport *view,UINT nFlags, CPoint point )
{
if (m_mode == BrushMoveMode)
{
// Move brush.
GetIEditor()->RestoreUndo();
Vec3 p1 = view->MapViewToCP(m_mouseDownPos);
Vec3 p2 = view->MapViewToCP(point);
Vec3 v = view->GetCPVector(p1,p2);
int coordSys = GetIEditor()->GetReferenceCoordSys();
GetIEditor()->GetSelection()->Move( v,false, coordSys==COORDS_WORLD );
return true;
}
if (m_mode == BrushCreateMode)
{
NewBrush( view,point );
return true;
}
else if (m_mode == BrushStretchMode)
{
StretchBrush( view,point );
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CBrushTool::MouseCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags )
{
bool bProcessed = false;
if (event == eMouseLDown)
{
bProcessed = OnLButtonDown( view,flags,point );
}
else if (event == eMouseLUp)
{
bProcessed = OnLButtonUp( view,flags,point );
}
else if (event == eMouseMove)
{
bProcessed = OnMouseMove( view,flags,point );
}
// Not processed.
return bProcessed;
}
//////////////////////////////////////////////////////////////////////////
bool CBrushTool::OnKeyDown( CViewport *view,uint nChar,uint nRepCnt,uint nFlags )
{
if (nChar == VK_ESCAPE)
{
// Escape clears selection.
GetIEditor()->ClearSelection();
return true;
}
// Not processed.
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CBrushTool::OnKeyUp( CViewport *view,uint nChar,uint nRepCnt,uint nFlags )
{
// Not processed.
return false;
}
//////////////////////////////////////////////////////////////////////////
void CBrushTool::NewBrush( CViewport *view,CPoint point )
{
CRect rc( m_mouseDownPos,point );
rc.NormalizeRect();
BBox brushBox;
brushBox.Reset();
brushBox.Add( view->MapViewToCP( CPoint(rc.left,rc.top) ) );
brushBox.Add( view->MapViewToCP( CPoint(rc.right,rc.bottom) ) );
switch (view->GetType())
{
case ET_ViewportXY:
brushBox.min.z = m_lastBrushBounds.min.z;
brushBox.max.z = m_lastBrushBounds.max.z;
break;
case ET_ViewportXZ:
brushBox.min.y = m_lastBrushBounds.min.y;
brushBox.max.y = m_lastBrushBounds.max.y;
break;
case ET_ViewportYZ:
brushBox.min.x = m_lastBrushBounds.min.x;
brushBox.max.x = m_lastBrushBounds.max.x;
break;
default:
brushBox.min.z = m_lastBrushBounds.min.z;
brushBox.max.z = m_lastBrushBounds.max.z;
}
if (IsVectorsEqual(brushBox.min,brushBox.max))
return;
// If width or height or depth are zero.
if (fabs(brushBox.min.x-brushBox.max.x) < 0.01 ||
fabs(brushBox.min.y-brushBox.max.y) < 0.01 ||
fabs(brushBox.min.z-brushBox.max.z) < 0.01)
return;
if (IsEquivalent(m_lastBrushBounds.min,brushBox.min,0) && IsEquivalent(m_lastBrushBounds.max,brushBox.max,0))
return;
m_lastBrushBounds = brushBox;
Vec3 center = (brushBox.min + brushBox.max)/2.0f;
brushBox.min -= center;
brushBox.max -= center;
SBrush *brush = new SBrush;
SMapTexInfo ti;
brush->Create( brushBox.min,brushBox.max,&ti );
bool bSolidValid = brush->BuildSolid();
CBrushObject *brushObj;
CBaseObject *obj = m_IEditor->GetSelectedObject();
if (obj && obj->IsKindOf(RUNTIME_CLASS(CBrushObject)))
{
brushObj = (CBrushObject*)obj;
}
else
{
m_IEditor->ClearSelection();
brushObj = (CBrushObject*)m_IEditor->NewObject( "Brush" );
m_IEditor->SelectObject( brushObj );
}
brushObj->SetPos( center );
brushObj->SetBrush( brush );
}
//////////////////////////////////////////////////////////////////////////
void CBrushTool::StretchBrush( CViewport* view,CPoint point )
{
Vec3 src = view->MapViewToCP(m_mouseDownPos);
Vec3 trg = view->MapViewToCP(point);
Vec3 delta = trg - src;
if (IsEquivalent(delta,Vec3(0,0,0),0))
return;
m_mouseDownPos = point;
Vec3 raySrc,rayDir;
view->ViewToWorldRay( point,raySrc,rayDir );
CSelectionGroup *selection = GetIEditor()->GetSelection();
for (int i = 0; i < selection->GetCount(); i++)
{
if (!selection->GetObject(i)->IsKindOf(RUNTIME_CLASS(CBrushObject)))
continue;
CBrushObject *brushObj = (CBrushObject*)selection->GetObject(i);
brushObj->MoveSelectedPoints( delta );
//SBrush *brush = brushObj->GetBrush();
//brush->SideSelect(
}
view->Invalidate(FALSE);
}
//////////////////////////////////////////////////////////////////////////
void CBrushTool::CalcLastBrushSize()
{
bool bSelected = false;
BBox box;
box.Reset();
CSelectionGroup *sel = m_IEditor->GetSelection();
for (int i = 0; i < sel->GetCount(); i++)
{
if (sel->GetObject(i)->GetType() == OBJTYPE_BRUSH)
{
BBox local;
sel->GetObject(i)->GetBoundBox(local);
box.Add( local.min );
box.Add( local.max );
bSelected = true;
}
}
BBox empty;
empty.Reset();
if (bSelected)
{
if (!IsEquivalent(box.min,empty.min,0) && !IsEquivalent(box.max,empty.max,0))
{
m_lastBrushBounds = box;
}
}
}

83
Editor/Brush/BrushTool.h Normal file
View File

@@ -0,0 +1,83 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
// File name: BrushTool.h
// Version: v1.00
// Created: 11/1/2002 by Timur.
// Compilers: Visual C++ 6.0
// Description: Terrain modification tool.
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __BrushTool_h__
#define __BrushTool_h__
#if _MSC_VER > 1000
#pragma once
#endif
#include "..\EditTool.h"
//////////////////////////////////////////////////////////////////////////
class CBrushTool : public CEditTool
{
DECLARE_DYNCREATE(CBrushTool)
public:
CBrushTool();
virtual ~CBrushTool();
//////////////////////////////////////////////////////////////////////////
// CEditTool overrides.
//////////////////////////////////////////////////////////////////////////
virtual void BeginEditParams( IEditor *ie,int flags );
virtual void EndEditParams();
virtual void Display( DisplayContext &dc );
virtual bool MouseCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags );
// Key down.
virtual bool OnKeyDown( CViewport *view,uint nChar,uint nRepCnt,uint nFlags );
virtual bool OnKeyUp( CViewport *view,uint nChar,uint nRepCnt,uint nFlags );
// Delete itself.
virtual void Release() { delete this; };
//////////////////////////////////////////////////////////////////////////
private:
void NewBrush( CViewport *view,CPoint point );
void StretchBrush( CViewport* view,CPoint point );
void CalcLastBrushSize();
// Specific mouse events handlers.
bool OnLButtonDown( CViewport *view,UINT nFlags,CPoint point );
bool OnLButtonUp( CViewport *view,UINT nFlags,CPoint point );
bool OnMouseMove( CViewport *view,UINT nFlags,CPoint point );
//! Operation modes of this viewport.
enum BrushOpMode
{
BrushNoMode = 0,
BrushMoveMode,
BrushCreateMode,
BrushStretchMode,
};
IEditor *m_IEditor;
//////////////////////////////////////////////////////////////////////////
//! Bounds of last selected brush or selection.
BBox m_lastBrushBounds;
//! Current brush tool operation mode.
BrushOpMode m_mode;
bool m_bMouseCaptured;
CPoint m_mouseDownPos;
};
#endif // __BrushTool_h__

385
Editor/BuildingPanel.cpp Normal file
View File

@@ -0,0 +1,385 @@
// BuildingPanel.cpp : implementation file
//
#include "stdafx.h"
#include "BuildingPanel.h"
#include "Objects\ObjectManager.h"
#include "Objects\Building.h"
#include "ObjectCreateTool.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CBuildingPanel dialog
CBuildingPanel::CBuildingPanel(CWnd* pParent /*=NULL*/)
: CDialog( CBuildingPanel::IDD,pParent)
{
//{{AFX_DATA_INIT(CBuildingPanel)
//}}AFX_DATA_INIT
m_building = 0;
m_picking = false;
m_currHelper = 0;
}
CBuildingPanel::~CBuildingPanel()
{
if (GetIEditor()->GetEditTool() == m_createTool)
{
GetIEditor()->SetEditTool(0);
}
}
void CBuildingPanel::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CBuildingPanel)
DDX_Control(pDX, IDC_UNBIND, m_unbindBuilding);
DDX_Control(pDX, IDC_BIND, m_bindButton);
DDX_Control(pDX, IDC_WIREFRAME, m_wireframe);
DDX_Control(pDX, IDC_PORTALS, m_portals);
DDX_Control(pDX, IDC_HIDE_NONE, m_hideNone);
DDX_Control(pDX, IDC_HIDE_INVERT, m_hideInvert);
DDX_Control(pDX, IDC_HIDE_ALL, m_hideAll);
DDX_Control(pDX, IDC_HIDDEN_SECTORS, m_hiddenSectors);
DDX_Control(pDX, IDC_HELPERS, m_helpers);
DDX_Control(pDX, IDC_CHANGE, m_browseButton);
DDX_Control(pDX, IDC_SPAWN, m_spawnButton);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CBuildingPanel, CDialog)
//{{AFX_MSG_MAP(CBuildingPanel)
ON_BN_CLICKED(IDC_ADD, OnAdd)
ON_BN_CLICKED(IDC_REMOVE, OnRemove)
ON_BN_CLICKED(IDC_CHANGE, OnChange)
ON_BN_CLICKED(IDC_SPAWN, OnSpawn)
ON_LBN_SELCHANGE(IDC_HIDDEN_SECTORS, OnSelchangeHiddenSectors)
ON_BN_CLICKED(IDC_HIDE_ALL, OnHideAll)
ON_BN_CLICKED(IDC_HIDE_NONE, OnHideNone)
ON_BN_CLICKED(IDC_HIDE_INVERT, OnHideInvert)
ON_BN_CLICKED(IDC_BIND, OnBind)
ON_BN_CLICKED(IDC_UNBIND, OnUnbind)
ON_BN_CLICKED(IDC_WIREFRAME, OnWireframe)
ON_BN_CLICKED(IDC_PORTALS, OnBnClickedPortals)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CBuildingPanel message handlers
BOOL CBuildingPanel::OnInitDialog()
{
CDialog::OnInitDialog();
CRect rc;
m_helpers.GetClientRect( rc );
int w1 = rc.right/2;
int w2 = rc.right/2-2;
m_helpers.SetBkColor( RGB(0xE0,0xE0,0xE0) );
m_helpers.SetTextBkColor( RGB(0xE0,0xE0,0xE0) );
m_hiddenSectors.SetBkColor( RGB(0xE0,0xE0,0xE0) );
// Init helpers.
//m_helpers.SetExtendedStyle( LVS_EX_FLATSB|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP );
m_helpers.SetExtendedStyle( LVS_EX_FLATSB|LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_GRIDLINES );
m_helpers.InsertColumn( 1,"Helper",LVCFMT_LEFT,w1,0 );
m_helpers.InsertColumn( 2,"Object",LVCFMT_LEFT,w2,1 );
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CBuildingPanel::OnAdd()
{
assert( m_building != 0 );
// TODO: Add your control notification handler code here
// Select Cgf file.
/*
CString file,relFile;
if (GetIEditor()->SelectFile( "*.cgf","Objects\\Buildings",file,relFile ))
{
m_building->AddObject( relFile );
RefreshList();
}
*/
/*
CString filter = "Building Files (*.bld)|*.bld||";
char files[4096];
memset( files,0,sizeof(files) );
CFileDialog dlg(TRUE, NULL,NULL, OFN_ALLOWMULTISELECT|OFN_ENABLESIZING|OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_NOCHANGEDIR, filter );
dlg.m_ofn.lpstrInitialDir = "Objects\\Buildings";
dlg.m_ofn.lpstrFile = files;
dlg.m_ofn.nMaxFile = sizeof(files);
if (dlg.DoModal() == IDOK)
{
POSITION pos = dlg.GetStartPosition();
while (pos != NULL)
{
CString fileName = dlg.GetNextPathName(pos);
CString relativeFileName = GetIEditor()->GetRelativePath( fileName );
m_building->AddObject( relativeFileName );
}
RefreshList();
}
*/
}
void CBuildingPanel::OnRemove()
{
assert( m_building != 0 );
/*
std::vector<int> items;
items.resize( m_objects.GetSelCount() );
if (items.size() > 0)
{
std::vector<CString> names;
names.resize( items.size() );
m_objects.GetSelItems( items.size(),&items[0] );
for (int i = 0; i < items.size(); i++)
{
names[i] = m_building->GetObjectName(items[i]);
}
for (i = 0; i < names.size(); i++)
{
m_building->RemoveObject( names[i] );
}
RefreshList();
}
*/
}
//////////////////////////////////////////////////////////////////////////
void CBuildingPanel::SetBuilding( CBuilding *obj )
{
m_building = obj;
assert( m_building != 0 );
m_wireframe.SetCheck( (m_building->IsWireframe())?BST_CHECKED:BST_UNCHECKED );
m_portals.SetCheck( (m_building->IsPortals())?BST_CHECKED:BST_UNCHECKED );
RefreshList();
};
//////////////////////////////////////////////////////////////////////////
void CBuildingPanel::RefreshList()
{
if (!m_building)
return;
CString str = m_building->GetObjectName();
str.MakeLower();
str.Replace( "objects\\buildings\\","" );
SetDlgItemText( IDC_BUILDING,str );
/*
assert( m_building != 0 );
m_objects.ResetContent();
for (int i = 0; i < m_building->GetObjectCount(); i++)
{
CString name = m_building->GetObjectName(i);
char file[_MAX_FNAME];
char ext[_MAX_EXT];
_splitpath(name,NULL,NULL,file,ext );
m_objects.InsertString(i,CString(file) );
}
*/
/*
m_helpers.DeleteAllItems();
for (int i = 0; i < m_building->GetChildCount(); i++)
{
CBaseObject *obj = m_building->GetChild(i);
int id = m_helpers.InsertItem( i,obj->GetName() );
m_helpers.SetItem( id,1,LVIF_TEXT|LVIF_STATE,obj->GetTypeDescription(),0,0,0,0 );
}
*/
int i;
m_helpers.DeleteAllItems();
std::vector<CBuilding::ObjectHelper> &helpers = m_building->GetHelpers();
for (i = 0; i < helpers.size(); i++)
{
CBaseObject *obj = helpers[i].object;
int id = m_helpers.InsertItem( i,helpers[i].name );
if (obj)
m_helpers.SetItem( id,1,LVIF_TEXT|LVIF_STATE,obj->GetName(),0,0,0,0 );
}
m_hiddenSectors.ResetContent();
for (i = 0; i < m_building->GetNumSectors(); i++)
{
CString str;
str.Format( "Sector %d",i );
m_hiddenSectors.AddString( str );
if (m_building->IsSectorHidden(i))
m_hiddenSectors.SetSel(i);
}
}
void CBuildingPanel::OnChange()
{
CString filter = "Building Files (*.bld)|*.bld||";
CFileDialog dlg(TRUE, NULL,NULL, OFN_ENABLESIZING|OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_NOCHANGEDIR, filter );
dlg.m_ofn.lpstrInitialDir = "Objects\\Buildings";
if (dlg.DoModal() == IDOK)
{
CString relativeFileName = GetIEditor()->GetRelativePath( dlg.GetPathName() );
m_building->LoadBuilding( relativeFileName );
RefreshList();
}
}
void CBuildingPanel::OnSpawn()
{
int sel = m_helpers.GetNextItem(-1,LVNI_SELECTED);
if (sel < 0)
return;
m_currHelper = sel;
assert( m_building );
//m_building->SpawnEntities();
//RefreshList();
m_createTool = new CObjectCreateTool( functor(*this,OnCreateCallback) );
GetIEditor()->SetEditTool( m_createTool );
m_createTool->StartCreation( "StdEntity" );
}
void CBuildingPanel::OnCreateCallback( class CObjectCreateTool *tool,class CBaseObject *object )
{
assert( m_building );
tool->AcceptCreation();
if (m_currHelper >= 0 && m_currHelper < m_building->GetHelpers().size())
{
m_building->BindToHelper( m_currHelper,object );
RefreshList();
}
}
void CBuildingPanel::OnSelchangeHiddenSectors()
{
for (int i = 0; i < m_hiddenSectors.GetCount(); i++)
{
if (m_hiddenSectors.GetSel(i))
m_building->HideSector(i,true);
else
m_building->HideSector(i,false);
}
}
void CBuildingPanel::OnHideAll()
{
for (int i = 0; i < m_building->GetNumSectors(); i++)
m_building->HideSector(i,true);
RefreshList();
}
void CBuildingPanel::OnHideNone()
{
for (int i = 0; i < m_building->GetNumSectors(); i++)
m_building->HideSector(i,false);
RefreshList();
}
void CBuildingPanel::OnHideInvert()
{
for (int i = 0; i < m_building->GetNumSectors(); i++)
m_building->HideSector(i,m_building->IsSectorHidden(i));
RefreshList();
}
void CBuildingPanel::OnBind()
{
if (m_picking)
{
GetIEditor()->SetEditTool(0);
m_picking = false;
return;
}
int sel = m_helpers.GetNextItem(-1,LVNI_SELECTED);
if (sel < 0)
return;
m_currHelper = sel;
// Bind picked object to helper.
GetIEditor()->PickObject( this,0,"Pick object to bind" );
m_bindButton.SetCheck( BST_CHECKED );
m_picking = true;
}
void CBuildingPanel::OnUnbind()
{
int sel = m_helpers.GetNextItem(-1,LVNI_SELECTED);
if (sel < 0)
return;
if (m_picking)
return;
// Unbind picked object from helper.
std::vector<CBuilding::ObjectHelper> &helpers = m_building->GetHelpers();
if (sel < helpers.size())
{
m_building->UnbindHelper( sel );
RefreshList();
}
}
//////////////////////////////////////////////////////////////////////////
void CBuildingPanel::OnPick( CBaseObject *picked )
{
m_bindButton.SetCheck( BST_UNCHECKED );
m_picking = false;
assert( m_building != 0 );
if (!picked)
return;
std::vector<CBuilding::ObjectHelper> &helpers = m_building->GetHelpers();
if (m_currHelper >= 0 && m_currHelper < helpers.size())
{
m_building->BindToHelper( m_currHelper,picked );
RefreshList();
}
}
void CBuildingPanel::OnCancelPick()
{
m_picking = false;
m_bindButton.SetCheck( BST_UNCHECKED );
m_currHelper = -1;
}
void CBuildingPanel::OnWireframe()
{
if (m_wireframe.GetCheck() == BST_CHECKED)
m_building->SetWireframe(true);
else
m_building->SetWireframe(false);
}
void CBuildingPanel::OnBnClickedPortals()
{
if (m_portals.GetCheck() == BST_CHECKED)
m_building->SetPortals(true);
else
m_building->SetPortals(false);
}

88
Editor/BuildingPanel.h Normal file
View File

@@ -0,0 +1,88 @@
#if !defined(AFX_BUILDINGPANEL_H__96E64797_3913_440B_93E3_E4ACB5934454__INCLUDED_)
#define AFX_BUILDINGPANEL_H__96E64797_3913_440B_93E3_E4ACB5934454__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// BuildingPanel.h : header file
//
#include "ObjectPanel.h"
/////////////////////////////////////////////////////////////////////////////
// CBuildingPanel dialog
class CBuildingPanel : public CDialog, public IPickObjectCallback
{
// Construction
public:
CBuildingPanel(CWnd* pParent = NULL); // standard constructor
~CBuildingPanel();
// Dialog Data
//{{AFX_DATA(CBuildingPanel)
enum { IDD = IDD_PANEL_BUILDING };
CCustomButton m_unbindBuilding;
CColorCheckBox m_bindButton;
CButton m_wireframe;
CButton m_portals;
CCustomButton m_hideNone;
CCustomButton m_hideInvert;
CCustomButton m_hideAll;
CColoredListBox m_hiddenSectors;
CListCtrl m_helpers;
CCustomButton m_browseButton;
CCustomButton m_spawnButton;
//}}AFX_DATA
void SetBuilding( class CBuilding *obj );
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CBuildingPanel)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
virtual void OnUpdate() {};
// Implementation
protected:
virtual void OnOK() {};
virtual void OnCancel() {};
// Ovverriden from IPickObjectCallback
virtual void OnPick( CBaseObject *picked );
virtual void OnCancelPick();
void OnCreateCallback( class CObjectCreateTool *tool,class CBaseObject *object );
void RefreshList();
// Generated message map functions
//{{AFX_MSG(CBuildingPanel)
virtual BOOL OnInitDialog();
afx_msg void OnAdd();
afx_msg void OnRemove();
afx_msg void OnChange();
afx_msg void OnSpawn();
afx_msg void OnSelchangeHiddenSectors();
afx_msg void OnHideAll();
afx_msg void OnHideNone();
afx_msg void OnHideInvert();
afx_msg void OnBind();
afx_msg void OnUnbind();
afx_msg void OnWireframe();
afx_msg void OnBnClickedPortals();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
CBuilding *m_building;
CObjectCreateTool *m_createTool;
int m_currHelper;
bool m_picking;
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_BUILDINGPANEL_H__96E64797_3913_440B_93E3_E4ACB5934454__INCLUDED_)

71
Editor/CheckOutDialog.cpp Normal file
View File

@@ -0,0 +1,71 @@
// CheckOutDialog.cpp : implementation file
//
#include "stdafx.h"
#include "CheckOutDialog.h"
// CCheckOutDialog dialog
IMPLEMENT_DYNAMIC(CCheckOutDialog, CDialog)
CCheckOutDialog::CCheckOutDialog( const CString &file,CWnd* pParent /*=NULL*/)
: CDialog(CCheckOutDialog::IDD, pParent)
, m_text(_T(""))
{
m_file = file;
m_result = CANCEL;
}
CCheckOutDialog::~CCheckOutDialog()
{
}
void CCheckOutDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_TEXT, m_text);
}
BEGIN_MESSAGE_MAP(CCheckOutDialog, CDialog)
ON_BN_CLICKED(IDC_CHECKOUT, OnBnClickedCheckout)
ON_BN_CLICKED(IDOK, OnBnClickedOk)
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////////
// CCheckOutDialog message handlers
void CCheckOutDialog::OnBnClickedCheckout()
{
// Check out this file.
m_result = CHECKOUT;
OnOK();
}
//////////////////////////////////////////////////////////////////////////
void CCheckOutDialog::OnBnClickedOk()
{
// Overwrite this file.
m_result = OVERWRITE;
OnOK();
}
BOOL CCheckOutDialog::OnInitDialog()
{
CDialog::OnInitDialog();
CString title;
GetWindowText( title );
title += " (";
title += m_file;
title += ")";
SetWindowText( title );
m_text.Format( _T("%s is read-only file, can be under Source Control."),(const char*)m_file );
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}

60
Editor/CheckOutDialog.h Normal file
View File

@@ -0,0 +1,60 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: checkoutdialog.h
// Version: v1.00
// Created: 22/5/2003 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __checkoutdialog_h__
#define __checkoutdialog_h__
#pragma once
//////////////////////////////////////////////////////////////////////////
// CCheckOutDialog dialog
class CCheckOutDialog : public CDialog
{
DECLARE_DYNAMIC(CCheckOutDialog)
// Checkout dialog result.
enum EResult
{
CHECKOUT,
OVERWRITE,
CANCEL,
};
public:
CCheckOutDialog( const CString &file,CWnd* pParent = NULL); // standard constructor
virtual ~CCheckOutDialog();
// Dialog Data
enum { IDD = IDD_CHECKOUT };
EResult GetResult() const { return m_result; };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
afx_msg void OnBnClickedCheckout();
afx_msg void OnBnClickedOk();
CString m_file;
CString m_text;
EResult m_result;
public:
virtual BOOL OnInitDialog();
};
#endif // __checkoutdialog_h__

159
Editor/Clipboard.cpp Normal file
View File

@@ -0,0 +1,159 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: clipboard.cpp
// Version: v1.00
// Created: 15/8/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "Clipboard.h"
#include <afxole.h>
#include <afxadv.h>
XmlNodeRef CClipboard::m_node;
CString CClipboard::m_title;
//////////////////////////////////////////////////////////////////////////
// Clipboard implementation.
//////////////////////////////////////////////////////////////////////////
void CClipboard::Put(XmlNodeRef &node,const CString &title )
{
m_title = title;
if (m_title.IsEmpty())
{
m_title = node->getTag();
}
m_node = node;
PutString( m_node->getXML().c_str(),title );
/*
COleDataSource Source;
CSharedFile sf(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT);
CString text = node->getXML();
sf.Write(text, text.GetLength());
HGLOBAL hMem = sf.Detach();
if (!hMem)
return;
Source.CacheGlobalData(CF_TEXT, hMem);
Source.SetClipboard();
*/
}
//////////////////////////////////////////////////////////////////////////
XmlNodeRef CClipboard::Get()
{
/*
COleDataObject obj;
if (obj.AttachClipboard()) {
if (obj.IsDataAvailable(CF_TEXT)) {
HGLOBAL hmem = obj.GetGlobalData(CF_TEXT);
CMemFile sf((BYTE*) ::GlobalLock(hmem), ::GlobalSize(hmem));
CString buffer;
LPSTR str = buffer.GetBufferSetLength(::GlobalSize(hmem));
sf.Read(str, ::GlobalSize(hmem));
::GlobalUnlock(hmem);
XmlParser parser;
XmlNodeRef node = parser.parseBuffer( buffer );
return node;
}
}
return 0;
*/
XmlNodeRef node = m_node;
//m_node = 0;
return node;
}
//////////////////////////////////////////////////////////////////////////
void CClipboard::PutString( const CString &text,const CString &title /* = "" */)
{
if (!OpenClipboard(NULL))
{
AfxMessageBox( "Cannot open the Clipboard" );
return;
}
// Remove the current Clipboard contents
if( !EmptyClipboard() )
{
AfxMessageBox( "Cannot empty the Clipboard" );
return;
}
CSharedFile sf(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT);
sf.Write(text, text.GetLength());
HGLOBAL hMem = sf.Detach();
if (!hMem)
return;
// For the appropriate data formats...
if ( ::SetClipboardData( CF_TEXT,hMem ) == NULL )
{
AfxMessageBox( "Unable to set Clipboard data" );
CloseClipboard();
return;
}
CloseClipboard();
/*
COleDataSource Source;
Source.CacheGlobalData(CF_TEXT, hMem);
Source.SetClipboard();
*/
}
//////////////////////////////////////////////////////////////////////////
CString CClipboard::GetString()
{
COleDataObject obj;
if (obj.AttachClipboard()) {
if (obj.IsDataAvailable(CF_TEXT)) {
HGLOBAL hmem = obj.GetGlobalData(CF_TEXT);
CMemFile sf((BYTE*) ::GlobalLock(hmem), ::GlobalSize(hmem));
CString buffer;
LPSTR str = buffer.GetBufferSetLength(::GlobalSize(hmem));
sf.Read(str, ::GlobalSize(hmem));
::GlobalUnlock(hmem);
return buffer;
}
}
return "";
}
//////////////////////////////////////////////////////////////////////////
bool CClipboard::IsEmpty() const
{
if (m_node)
return false;
/*
COleDataObject obj;
if (obj.AttachClipboard())
{
if (obj.IsDataAvailable(CF_TEXT))
{
return true;
}
}
*/
return true;
}

49
Editor/Clipboard.h Normal file
View File

@@ -0,0 +1,49 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: clipboard.h
// Version: v1.00
// Created: 15/8/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __clipboard_h__
#define __clipboard_h__
#if _MSC_VER > 1000
#pragma once
#endif
/** Use this class to put and get stuff from windows clipboard.
*/
class CRYEDIT_API CClipboard
{
public:
//! Put xml node into clipboard
void Put( XmlNodeRef &node,const CString &title = "" );
//! Get xml node to clipboard.
XmlNodeRef Get();
//! Put string into wibndows clipboard.
void PutString( const CString &text,const CString &title = "" );
//! Get string from Windows clipboard.
CString GetString();
//! Return name of what is in clipboard now.
CString GetTitle() const { return m_title; };
//! Return true if clipboard is empty.
bool IsEmpty() const;
private:
static XmlNodeRef m_node;
static CString m_title;
};
#endif // __clipboard_h__

656
Editor/Clouds.cpp Normal file
View File

@@ -0,0 +1,656 @@
// Clouds.cpp: Implementaion of the class CClouds.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Clouds.h"
#include "Util\DynamicArray2D.h"
//////////////////////////////////////////////////////////////////////
// Construction / destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_SERIAL (CClouds, CObject, 1)
CClouds::CClouds()
{
// Init member variables
m_iWidth = 0;
m_iHeight = 0;
m_sLastParam.bValid = false;
}
CClouds::~CClouds()
{
}
bool CClouds::GenerateClouds(SNoiseParams *sParam, CWnd *pWndStatus)
{
//////////////////////////////////////////////////////////////////////
// Generate the clouds
//////////////////////////////////////////////////////////////////////
assert(sParam);
// Free all old data
CleanUp();
// Save the width & height
m_iWidth = sParam->iWidth;
m_iHeight = sParam->iHeight;
// Create a new DC
m_dcClouds.CreateCompatibleDC(NULL);
// Create a new bitmap
VERIFY(m_bmpClouds.CreateBitmap(512, 512, 1, 32, NULL));
m_dcClouds.SelectObject(m_bmpClouds);
// Hold the last used parameters
memcpy(&m_sLastParam, sParam, sizeof(SNoiseParams));
m_sLastParam.bValid = true;
// Call the generation function function with the supplied parameters
CalcCloudsPerlin(sParam, pWndStatus);
return true;
}
void CClouds::DrawClouds(CDC *pDC, LPRECT prcPosition)
{
//////////////////////////////////////////////////////////////////////
// Draw the generated cloud texture
//////////////////////////////////////////////////////////////////////
assert(pDC);
assert(prcPosition);
// Prevents that the overall apperance of the image changes when it
// is stretched
pDC->SetStretchBltMode(HALFTONE);
if (m_dcClouds.m_hDC)
{
// Blit it to the destination rectangle
pDC->StretchBlt(prcPosition->left, prcPosition->top, prcPosition->right,
prcPosition->bottom, &m_dcClouds, 0, 0, m_iWidth, m_iHeight, SRCCOPY);
}
else
{
// Just draw a black rectangle
pDC->StretchBlt(prcPosition->left, prcPosition->top, prcPosition->right,
prcPosition->bottom, &m_dcClouds, 0, 0, m_iWidth, m_iHeight, BLACKNESS);
}
}
void CClouds::CalcCloudsPerlin(SNoiseParams *sParam, CWnd *pWndStatus)
{
//////////////////////////////////////////////////////////////////////
// Generate perlin noise based clouds
//////////////////////////////////////////////////////////////////////
unsigned int i, j, h;
COLORREF clrfColor;
float fValueRange;
CDynamicArray2D cCloud(sParam->iWidth, sParam->iHeight);
float fLowestPoint = 256000.0f, fHighestPoint = -256000.0f;
float fScaledCol;
CNoise cNoise;
float fYScale = 255;
char szStatus[128];
assert(!IsBadReadPtr(sParam, sizeof(SNoiseParams)));
assert(sParam->fFrequency);
assert(sParam->iWidth && sParam->iHeight);
assert(pWndStatus);
assert(::IsWindow(pWndStatus->m_hWnd));
assert(m_dcClouds.m_hDC);
assert(m_bmpClouds.m_hObject);
//////////////////////////////////////////////////////////////////////
// Generate the noise array
//////////////////////////////////////////////////////////////////////
// Set the random value
srand(sParam->iRandom);
// Process layers
for (i=0; i<sParam->iPasses; i++)
{
// Show status
sprintf(szStatus, "Calculating pass %i of %i...", i + 1, sParam->iPasses);
pWndStatus->SetWindowText(szStatus);
// Apply the fractal noise function to the array
cNoise.FracSynthPass(&cCloud, sParam->fFrequency, fYScale,
sParam->iWidth, sParam->iHeight, FALSE);
// Modify noise generation parameters
sParam->fFrequency *= sParam->fFrequencyStep;
fYScale *= sParam->fFade;
}
//////////////////////////////////////////////////////////////////////
// Paint the clouds into the bitmap
//////////////////////////////////////////////////////////////////////
// Apply the exponential function and find the value range
for (i=0; i<sParam->iWidth; i++)
for (j=0; j<sParam->iHeight; j++)
{
// Apply an exponential function to get separated clouds
cCloud.m_Array[i][j] = CloudExpCurve(cCloud.m_Array[i][j],
sParam->iCover, sParam->iSharpness);
fHighestPoint = __max(fHighestPoint, cCloud.m_Array[i][j]);
fLowestPoint = __min(fLowestPoint, cCloud.m_Array[i][j]);
}
// Prepare some renormalisation values
fValueRange = fHighestPoint - fLowestPoint;
// Smooth the clouds
for (h=0; h<sParam->iSmoothness; h++)
for (i=1; i<sParam->iWidth-1; i++)
for (j=1; j<sParam->iHeight-1; j++)
{
cCloud.m_Array[i][j] =
(cCloud.m_Array[i][j] + cCloud.m_Array[i+1][j] + cCloud.m_Array[i][j+1] +
cCloud.m_Array[i+1][j+1] + cCloud.m_Array[i-1][j] + cCloud.m_Array[i][j-1] +
cCloud.m_Array[i-1][j-1] + cCloud.m_Array[i+1][j-1] + cCloud.m_Array[i-1][j+1])
/ 9.0f;
}
for (i=0; i<sParam->iWidth; i++)
for (j=0; j<sParam->iHeight; j++)
{
// Normalize it first
cCloud.m_Array[i][j] += fLowestPoint;
cCloud.m_Array[i][j] = cCloud.m_Array[i][j] / fValueRange * 255.0f;
if (cCloud.m_Array[i][j] > 255)
cCloud.m_Array[i][j] = 255;
// Get the 0-255 index from the array, convert it into 0x00BBGGRR format, (add the
// blue sky) and draw the pixel it into the bitmap
if (sParam->bBlueSky)
{
fScaledCol = cCloud.m_Array[i][j] / 255.0f;
clrfColor = ((int) (fScaledCol * 255 + (1 - fScaledCol) * 40)) |
((int) (fScaledCol * 255 + (1 - fScaledCol) * 90)) << 8 |
((int) (fScaledCol * 255 + (1 - fScaledCol) * 180)) << 16;
}
else
{
fScaledCol = cCloud.m_Array[i][j] / 255.0f;
clrfColor = ((int) (fScaledCol * 255 + (1 - fScaledCol))) |
((int) (fScaledCol * 255 + (1 - fScaledCol))) << 8 |
((int) (fScaledCol * 255 + (1 - fScaledCol))) << 16;
}
// Set the pixel
m_dcClouds.SetPixelV(i, j, clrfColor);
}
}
void CClouds::CleanUp()
{
//////////////////////////////////////////////////////////////////////
// Free all data
//////////////////////////////////////////////////////////////////////
// The cloud DC
if (m_dcClouds.m_hDC)
m_dcClouds.DeleteDC();
// Bitmap
if (m_bmpClouds.m_hObject)
m_bmpClouds.DeleteObject();
}
float CClouds::CloudExpCurve(float v, unsigned int iCover, float fSharpness)
{
//////////////////////////////////////////////////////////////////////
// Exponential function to generate separated clouds
//////////////////////////////////////////////////////////////////////
float CloudDensity;
float c;
c = v - iCover;
if (c < 0)
c = 0;
CloudDensity = 255.f - (float) ((pow(fSharpness, c)) * 255.0f);
return CloudDensity;
}
void CClouds::Serialize(CArchive& ar)
{
////////////////////////////////////////////////////////////////////////
// Save or restore the class
////////////////////////////////////////////////////////////////////////
CObject::Serialize (ar);
if (ar.IsStoring())
{
// Storing
ar << m_iWidth << m_iHeight;
ar.Write(&m_sLastParam, sizeof(m_sLastParam));
}
else
{
// Loading
ar >> m_iWidth >> m_iHeight;
ar.Read(&m_sLastParam, sizeof(m_sLastParam));
}
}
void CClouds::Serialize( CXmlArchive &xmlAr )
{
if (xmlAr.bLoading)
{
//Load
XmlNodeRef clouds = xmlAr.root->findChild( "Clouds" );
if (clouds)
{
clouds->getAttr( "Width",m_iWidth );
clouds->getAttr( "Height",m_iHeight );
}
}
else
{
//Save
XmlNodeRef clouds = xmlAr.root->newChild( "Clouds" );
clouds->setAttr( "Width",(int)m_iWidth );
clouds->setAttr( "Height",(int)m_iHeight );
}
}
/*
void CClouds::CalcCloudsBezierFault(CLOUDPARAM *sParam, CWnd *pWndStatus)
{
//////////////////////////////////////////////////////////////////////
// Generate new clouds. We are using quadric Bezier curves
// instead of simple lines to smooth out the image. The point in front
// of line test is done by using a simple Bresenham algorithm to find
// the intersection points with each scanline. Use the titel of
// the supplied window to provide status informations
//////////////////////////////////////////////////////////////////////
unsigned int i, j, h, iScanline, iScanlineCurX;
uint8 iColor;
COLORREF clrfColor;
POINT p1, p2, p3;
float fValueRange;
CDynamicArray2D cCloud(sParam->iWidth, sParam->iHeight);
unsigned int *pScanlineIntersection = new unsigned int [m_iHeight];
float fLowestPoint = 65536.0f, fHighestPoint = -65536.0f;
float fIncreasement = 1.0f;
KeyPoint sKeyPoints[MAX_KEY_POINTS];
unsigned int iKeyPointCount;
int iDeltaX, iDeltaY;
int iUDeltaX, iUDeltaY;
char szWindowTitel[32];
unsigned int iStatus, iLastStatus = 0;
assert(sParam);
assert(sParam->iIterations);
// Paint it black first
m_dcClouds.BitBlt(0, 0, m_iWidth, m_iHeight, &m_dcClouds, 0, 0, BLACKNESS);
// Do the iterations
for (i=0; i<sParam->iIterations; i++)
{
// Update status (if necessary)
iStatus = (int) (i / (float) sParam->iIterations * 100);
if (iStatus != iLastStatus)
{
sprintf(szWindowTitel, "%i%% Done", iStatus);
pWndStatus->SetWindowText(szWindowTitel);
iLastStatus = iStatus;
}
//////////////////////////////////////////////////////////////////////
// Generate the curve
//////////////////////////////////////////////////////////////////////
// Pick two random points on the border
RandomPoints(&p1, &p2);
iDeltaX = p2.x - p1.x; // Work out X delta
iDeltaY = p2.y - p1.y; // Work out Y delta
iUDeltaX = abs(iDeltaX); // iUDeltaX is the unsigned X delta
iUDeltaY = abs(iDeltaY); // iUDeltaY is the unsigned Y delta
// Subdivide the line, use a random point in the heightmap as third control point
p3.x = (long) (rand() / (float) RAND_MAX * m_iWidth);
p3.y = (long) (rand() / (float) RAND_MAX * m_iHeight);
// Get the keypoints of the Bezier curve
iKeyPointCount = QuadricSubdivide(&p1, &p3, &p2,
BEZIER_SUBDIVISON_LEVEL, sKeyPoints, true);
//////////////////////////////////////////////////////////////////////
// Trace each curve segment into the scanline intersection array
//////////////////////////////////////////////////////////////////////
for (j=0; j<iKeyPointCount - 1; j++)
{
// Get the start / endpoints of the segment
p1.x = (long) sKeyPoints[j].fX;
p1.y = (long) sKeyPoints[j].fY;
p2.x = (long) sKeyPoints[j + 1].fX;
p2.y = (long) sKeyPoints[j + 1].fY;
TraceCurveSegment(&p1, &p2, iUDeltaX, iUDeltaY, pScanlineIntersection);
}
//////////////////////////////////////////////////////////////////////
// Process all scanlines and raise / lower the terrain
//////////////////////////////////////////////////////////////////////
// This ensures a good distribution of vallies and mountains
if (rand() % 2)
{
if (iDeltaX > 0)
iDeltaX = -iDeltaX;
else
iDeltaX = abs(iDeltaX);
}
// We have to approach the two delta cases different to make sure we are
// processing all pixels
if (iUDeltaX < iUDeltaY)
{
// This is necessary because the direction of the line is important for the
// raising / lowering. Doing it here safes us from using a branch in the
// inner loop
if (iDeltaX > 0)
fIncreasement = (float) fabs(fIncreasement);
else
fIncreasement = (float) -fabs(fIncreasement);
for (iScanline=0; iScanline<m_iHeight; iScanline++)
{
// Loop trough each pixel in the scanline
for (iScanlineCurX=0; iScanlineCurX<m_iWidth; iScanlineCurX++)
{
// Raise / lower the terrain on each side of the line
if (iScanlineCurX > pScanlineIntersection[iScanline])
cCloud.m_Array[iScanlineCurX][iScanline] += fIncreasement;
else
cCloud.m_Array[iScanlineCurX][iScanline] -= fIncreasement;
// Do we have a new highest / lowest value ?
fLowestPoint = __min(fLowestPoint, cCloud.m_Array[iScanlineCurX][iScanline]);
fHighestPoint = __max(fHighestPoint, cCloud.m_Array[iScanlineCurX][iScanline]);
}
}
}
else
{
// This is necessary because the direction of the line is important for the
// raising / lowering. Doing it here safes us from using a branch in the
// inner loop
if (iDeltaY > 0)
fIncreasement = (float) fabs(fIncreasement);
else
fIncreasement = (float) -fabs(fIncreasement);
// Loop trough each pixel in the scanline
for (iScanlineCurX=0; iScanlineCurX<m_iWidth; iScanlineCurX++)
{
for (iScanline=0; iScanline<m_iHeight; iScanline++)
{
// Raise / lower the terrain on each side of the line
if (iScanline > pScanlineIntersection[iScanlineCurX])
cCloud.m_Array[iScanlineCurX][iScanline] += fIncreasement;
else
cCloud.m_Array[iScanlineCurX][iScanline] -= fIncreasement;
// Do we have a new highest / lowest value ?
fLowestPoint = __min(fLowestPoint, cCloud.m_Array[iScanlineCurX][iScanline]);
fHighestPoint = __max(fHighestPoint, cCloud.m_Array[iScanlineCurX][iScanline]);
}
}
}
}
//////////////////////////////////////////////////////////////////////
// Paint the clouds into the bitmap
//////////////////////////////////////////////////////////////////////
// Prepare some renormalisation values. Shorten the value range to get
// higher contrast clouds
fValueRange = (fHighestPoint - fLowestPoint) / 1.3f;
if (fLowestPoint < 0)
{
fLowestPoint = (float) fabs(fLowestPoint);
fHighestPoint += (float) fabs(fLowestPoint);
}
// Smooth the clouds
for (h=0; h<sParam->iSmoothness; h++)
for (i=1; i<m_iWidth-1; i++)
for (j=1; j<m_iHeight-1; j++)
{
cCloud.m_Array[i][j] =
(cCloud.m_Array[i][j] + cCloud.m_Array[i+1][j] + cCloud.m_Array[i][j+1] +
cCloud.m_Array[i+1][j+1] + cCloud.m_Array[i-1][j] + cCloud.m_Array[i][j-1] +
cCloud.m_Array[i-1][j-1] + cCloud.m_Array[i+1][j-1] + cCloud.m_Array[i-1][j+1])
/ 9.0f;
}
for (i=0; i<m_iWidth; i++)
for (j=0; j<m_iHeight; j++)
{
// Normalize it first
cCloud.m_Array[i][j] += fLowestPoint;
cCloud.m_Array[i][j] = cCloud.m_Array[i][j] / fValueRange * 255.0f;
if (cCloud.m_Array[i][j] > 255)
cCloud.m_Array[i][j] = 255;
// Apply an exponetial function to get separated clouds
cCloud.m_Array[i][j] = CloudExpCurve(cCloud.m_Array[i][j]);
// Get the 0-255 index from the array, convert it into 0x00BBGGRR grayscale
// and draw it into the bitmap
iColor = (int8) cCloud.m_Array[i][j];
clrfColor = iColor | iColor << 8 | iColor << 16;
m_dcClouds.SetPixelV(i, j, clrfColor);
}
// Free the scanline intersection data
delete [] pScanlineIntersection;
pScanlineIntersection = 0;
}
unsigned int CClouds::QuadricSubdivide(LPPOINT p1, LPPOINT p2, LPPOINT p3, unsigned int iLevel,
KeyPoint *pKeyPointArray, bool bFirstSubdivision)
{
//////////////////////////////////////////////////////////////////////
// Add a line (one key point). If level is 0 use the end points. If
// this is the first subdivision, you have to pass true for
// bFirstSubdivision. The number of keypoints is returned
//////////////////////////////////////////////////////////////////////
POINT pGl[3];
POINT pGr[3];
static int iCurKeyPoint = 0;
// Start with the first keypoint when doing the first subdivision
if (bFirstSubdivision)
iCurKeyPoint = 0;
if (iLevel == 0)
{
// Add it to the list
pKeyPointArray[iCurKeyPoint].fX = (float) p1->x;
pKeyPointArray[iCurKeyPoint].fY = (float) p1->y;
// Advance to the next
iCurKeyPoint++;
return iCurKeyPoint;
}
// New geometry vectors for the left and right halves of the curve
// Subdivide
memcpy(&pGl[0], p1, sizeof(POINT));
pGl[1].x = (p1->x + p2->x) >> 1;
pGl[1].y = (p1->y + p2->y) >> 1;
pGr[1].x = (p2->x + p3->x) >> 1;
pGr[1].y = (p2->y + p3->y) >> 1;
pGl[2].x = pGr[0].x = (pGl[1].x + pGr[1].x) >> 1;
pGl[2].y = pGr[0].y = (pGl[1].y + pGr[1].y) >> 1;
memcpy(&pGr[2], p3, sizeof(POINT));
// Call recursively for left and right halves
QuadricSubdivide(&pGl[0], &pGl[1], &pGl[2], --iLevel, pKeyPointArray, false);
QuadricSubdivide(&pGr[0], &pGr[1], &pGr[2], iLevel, pKeyPointArray, false);
// Add the end of the curve to the keypoint list if this is the first
// recursion level
if (bFirstSubdivision)
{
pKeyPointArray[iCurKeyPoint].fX = (float) p3->x;
pKeyPointArray[iCurKeyPoint].fY = (float) p3->y;
iCurKeyPoint++;
}
return iCurKeyPoint;
}
void CClouds::TraceCurveSegment(LPPOINT p1, LPPOINT p2, int iUCurveDeltaX,
int iUCurveDeltaY, unsigned int *pScanlineIntersection)
{
//////////////////////////////////////////////////////////////////////
// Use the Bresenham line drawing algorithm to find the scanline
// intersection points
//////////////////////////////////////////////////////////////////////
int iDeltaX, iDeltaY;
int iUDeltaX, iUDeltaY;
int iXAdd, iYAdd;
int iError, iLoop;
iDeltaX = p2->x - p1->x; // Work out X delta
iDeltaY = p2->y - p1->y; // Work out Y delta
iUDeltaX = abs(iDeltaX); // iUDeltaX is the unsigned X delta
iUDeltaY = abs(iDeltaY); // iUDeltaY is the unsigned Y delta
// Work out direction to step in the Y direction
if (iDeltaX < 0)
iXAdd = -1;
else
iXAdd = 1;
// Work out direction to step in the Y direction
if (iDeltaY < 0)
iYAdd = -1;
else
iYAdd = 1;
iError = 0;
iLoop = 0;
if (iUDeltaX > iUDeltaY)
{
// Delta X > Delta Y
do
{
iError += iUDeltaY;
// Time to move up / down ?
if (iError >= iUDeltaX)
{
iError -= iUDeltaX;
p1->y += iYAdd;
}
iLoop++;
// Save scanline intersection
if (iUCurveDeltaX < iUCurveDeltaY)
pScanlineIntersection[p1->y] = p1->x;
else
pScanlineIntersection[p1->x] = p1->y;
// Move horizontally
p1->x += iXAdd;
}
while (iLoop < iUDeltaX); // Repeat for x length of line
}
else
{
// Delta Y > Delta X
do
{
iError += iUDeltaX;
// Time to move left / right?
if (iError >= iUDeltaY)
{
iError -= iUDeltaY;
// Move across
p1->x += iXAdd;
}
iLoop++;
// Save scanline intersection
if (iUCurveDeltaX < iUCurveDeltaY)
pScanlineIntersection[p1->y] = p1->x;
else
pScanlineIntersection[p1->x] = p1->y;
// Move up / down a row
p1->y += iYAdd;
}
while (iLoop < iUDeltaY); // Repeat for y length of line
}
}
void CClouds::RandomPoints(LPPOINT p1, LPPOINT p2)
{
//////////////////////////////////////////////////////////////////////
// Make two random points that lay on the bitmap's boundaries
//////////////////////////////////////////////////////////////////////
bool bSwapSides;
assert(p1 && p2);
bSwapSides = (rand() % 2) ? true : false;
if (rand() % 2)
{
p1->x = (long) (rand() / (float) RAND_MAX * m_iWidth);
p1->y = bSwapSides ? 0 : m_iHeight - 1;
p2->x = (long) (rand() / (float) RAND_MAX * m_iWidth);
p2->y = bSwapSides ? m_iHeight - 1 : 0;
}
else
{
p1->x = bSwapSides ? m_iWidth - 1 : 0;
p1->y = (long) (rand() / (float) RAND_MAX * m_iHeight);
p2->x = bSwapSides ? 0 : m_iWidth - 1;
p2->y = (long) (rand() / (float) RAND_MAX * m_iHeight);
}
}
*/

49
Editor/Clouds.h Normal file
View File

@@ -0,0 +1,49 @@
// Clouds.h: Interface of the class CClouds.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_HEIGHTMAP_H__747B5795_AE67_4CA6_AF55_73A7659597FE__INCLUDED_)
#define AFX_HEIGHTMAP_H__747B5795_AE67_4CA6_AF55_73A7659597FE__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <time.h>
#include "Noise.h"
class CXmlArchive;
class CClouds : public CObject
{
DECLARE_SERIAL (CClouds)
public:
bool GenerateClouds(SNoiseParams *sParam, CWnd *pWndStatus);
void DrawClouds(CDC *pDC, LPRECT prcPosition);
void Serialize(CArchive& ar);
void Serialize( CXmlArchive &xmlAr );
SNoiseParams* GetLastParam() { return &m_sLastParam; };
CClouds();
virtual ~CClouds();
protected:
void CleanUp();
float CloudExpCurve(float v, unsigned int iCover, float fSharpness);
unsigned int m_iWidth;
unsigned int m_iHeight;
CBitmap m_bmpClouds;
CDC m_dcClouds;
// Used to hold the last used generation parameters
SNoiseParams m_sLastParam;
private:
void CalcCloudsPerlin(SNoiseParams *sParam, CWnd *pWndStatus);
};
#endif // !defined(AFX_HEIGHTMAP_H__747B5795_AE67_4CA6_AF55_73A7659597FE__INCLUDED_)

View File

@@ -0,0 +1,25 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: command.cpp
// Version: v1.00
// Created: 4/7/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "Command.h"
//////////////////////////////////////////////////////////////////////////
CCommand::CCommand( const CString &name,int Id,int flags )
{
m_name = name;
m_flags = flags;
m_id = Id;
}

61
Editor/Commands/Command.h Normal file
View File

@@ -0,0 +1,61 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: command.h
// Version: v1.00
// Created: 4/7/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __command_h__
#define __command_h__
#if _MSC_VER > 1000
#pragma once
#endif
/** CCommand is a base class for all commands exectuted in editor.
All new commands needs to be registered to CommandManager, each command
must have uniq name for Ex: "Edit.Clone"
Uses Command Pattern.
*/
class CCommand : public CRefCountBase
{
public:
//! Flags which can be specified for the name of the command.
enum Flags {
};
//! Command must have a name.
explicit CCommand( const CString &name,int Id=0,int flags=0 );
//! Retrieve command name.
const CString& GetName() const { return m_name; };
//! Retrieve command flags.
int GetFlags() const { return m_flags; };
//! Retrieve command Id.
int GetId() const { return m_id; }
/** Execute Command.
This method must be overriden in concrete command class, to perform specific action.
*/
virtual void Execute() = 0;
private:
CString m_name;
int m_flags;
//! Command id.
int m_id;
};
SMARTPTR_TYPEDEF(CCommand);
#endif // __command_h__

View File

@@ -0,0 +1,250 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: CommandManager.cpp
// Version: v1.00
// Created: 4/7/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "CommandManager.h"
//////////////////////////////////////////////////////////////////////////
// Functor command.
//////////////////////////////////////////////////////////////////////////
class CFunctorCommand : public CCommand
{
public:
explicit CFunctorCommand( const char *sName,Functor0 func ) : CCommand( sName,0 )
{
m_func = func;
}
virtual void Execute()
{
if (m_func)
m_func();
}
private:
Functor0 m_func;
};
///////////////////////////////////////////////////////////////////////////////
//
// CCommandManager.
//
///////////////////////////////////////////////////////////////////////////////
CCommandManager::CCommandManager()
{
// Make big enough hash table for faster searches.
// m_commands.resize( 1024 );
}
CCommandManager::~CCommandManager()
{
}
//////////////////////////////////////////////////////////////////////////
void CCommandManager::RegisterCommand( const CString &sCommand,CommandCallback callback )
{
assert( callback != 0 );
if (FindCommand( sCommand ) != 0)
{
CString err;
err.Format( "Error: Command %s already registered",(const char*)sCommand );
CLogFile::WriteLine( err );
AfxMessageBox( err );
}
CFunctorCommand *cmd = new CFunctorCommand(sCommand,callback);
m_commands.insert( Commands::value_type( sCommand,cmd ) );
}
//////////////////////////////////////////////////////////////////////////
void CCommandManager::UnregisterCommand( const CString &sCommand )
{
CCommand *pCmd = FindCommand( sCommand );
if (pCmd)
UnregisterCommand( pCmd );
}
//////////////////////////////////////////////////////////////////////////
void CCommandManager::RegisterCommand( CCommand *cmd )
{
assert( cmd != 0 );
if (FindCommand( cmd->GetName() ) != 0)
{
CString err;
err.Format( "Error: Command %s already registered",cmd->GetName() );
CLogFile::WriteLine( err );
AfxMessageBox( err );
}
m_commands.insert( Commands::value_type( cmd->GetName(),cmd ) );
}
void CCommandManager::UnregisterCommand( CCommand *cmd )
{
for (Commands::iterator it = m_commands.begin(); it != m_commands.end(); ++it)
{
if (it->second == cmd)
{
m_commands.erase( it );
break;
}
}
//error( "Cannot unregister command %s",cmd->name() );
}
CCommand* CCommandManager::FindCommand( const CString &sCommand ) const
{
Commands::const_iterator it = m_commands.find( sCommand );
if (it != m_commands.end())
{
return it->second;
}
return 0;
}
void CCommandManager::Execute( const char *command )
{
CCommand *cmd = FindCommand( command );
if (cmd)
{
for (CmdHandlers::iterator it = m_cmdHandlers.begin(); it != m_cmdHandlers.end(); ++it)
{
// if OnCommand handler return false ignore this commmand.
if (!(*it)->OnCommand( cmd ))
return;
}
cmd->Execute();
}
else
{
CString err;
err.Format( "Error: Trying to execute unknown Command: %s",command );
CLogFile::WriteLine( err );
}
}
//////////////////////////////////////////////////////////////////////////
void CCommandManager::ExecuteId( int commandId )
{
CCommand *cmd = 0;
for (Commands::iterator it = m_commands.begin(); it != m_commands.end(); it++)
{
CCommand *c = it->second;
if (c->GetId() == commandId)
{
cmd = c;
break;
}
}
if (cmd)
{
for (CmdHandlers::iterator it = m_cmdHandlers.begin(); it != m_cmdHandlers.end(); ++it)
{
// if OnCommand handler return false ignore this commmand.
if (!(*it)->OnCommand( cmd ))
return;
}
cmd->Execute();
}
/*
else
{
CString err;
err.Format( "Error: Tring to execute unknown Command: %s",command );
CLogFile::WriteLine( err );
}
*/
}
//////////////////////////////////////////////////////////////////////////
void CCommandManager::AddCommandHandler( ICommandHandler *handler )
{
m_cmdHandlers.push_back( handler );
}
void CCommandManager::RemoveCommandHandler( ICommandHandler *handler )
{
CmdHandlers::iterator it = std::find( m_cmdHandlers.begin(),m_cmdHandlers.end(),handler );
if (it != m_cmdHandlers.end()) {
m_cmdHandlers.erase( it );
}
}
//////////////////////////////////////////////////////////////////////////
void CCommandManager::GetSortedCmdList( std::vector<CString> &cmds )
{
cmds.clear();
cmds.reserve( m_commands.size() );
for (Commands::iterator it = m_commands.begin(); it != m_commands.end(); it++)
{
if (!cmds.empty())
{
// Ignore duplicate strings.
if (stricmp(cmds.back(),it->first) == 0) continue;
}
cmds.push_back( it->first );
}
std::sort( cmds.begin(),cmds.end() );
}
//////////////////////////////////////////////////////////////////////////
CString CCommandManager::AutoComplete( const char* substr )
{
std::vector<CString> cmds;
GetSortedCmdList( cmds );
int substrLen = strlen(substr);
// If substring is empty return first command.
if (substrLen==0 && cmds.size()>0)
return cmds[0];
for (int i = 0; i < cmds.size(); i++)
{
int cmdlen = strlen(cmds[i]);
if (cmdlen >= substrLen && memicmp(cmds[i],substr,substrLen) == 0)
{
if (substrLen == cmdlen)
{
i++;
if (i < cmds.size()) return cmds[i];
return cmds[i-1];
}
return cmds[i];
}
}
// Not found.
return "";
}
//////////////////////////////////////////////////////////////////////////
CString CCommandManager::AutoCompletePrev( const char* substr )
{
std::vector<CString> cmds;
GetSortedCmdList( cmds );
// If substring is empty return last command.
if (strlen(substr)==0 && cmds.size()>0)
return cmds[cmds.size()-1];
for (int i = 0; i < cmds.size(); i++)
{
if (stricmp(substr,cmds[i])==0)
{
if (i > 0)
return cmds[i-1];
else
return cmds[0];
}
}
return AutoComplete( substr );
}

View File

@@ -0,0 +1,78 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: commandmanager.h
// Version: v1.00
// Created: 4/7/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __commandmanager_h__
#define __commandmanager_h__
#if _MSC_VER > 1000
#pragma once
#endif
#include "Command.h"
/** Implement this interface and register it to command manager to intercept commands
before they executed.
*/
class ICommandHandler
{
public:
/** Called before this command is executed.
@return Return false to stop command from executing.
*/
virtual bool OnCommand( CCommand *command ) = 0;
};
/** Command manager stores all commands in the Editor.
*/
class CCommandManager
{
public:
typedef Functor0 CommandCallback;
CCommandManager(); // Ctor.
~CCommandManager();
//! Execute command by name.
void Execute( const char *command );
//! Execute command by id.
void ExecuteId( int commandId );
void GetSortedCmdList( std::vector<CString> &cmds );
CString AutoComplete( const char* substr );
CString AutoCompletePrev( const char* substr );
void RegisterCommand( CCommand *cmd );
void UnregisterCommand( CCommand *cmd );
void AddCommandHandler( ICommandHandler *handler );
void RemoveCommandHandler( ICommandHandler *handler );
//! Regster callback command.
void RegisterCommand( const CString &sCommand,CommandCallback callback );
//! Unregister command by name.
void UnregisterCommand( const CString &sCommand );
private:
CCommand* FindCommand( const CString &sCommand ) const;
//typedef string_hash_multimap<CommandOp*> Commands;
typedef std::map<CString,CCommandPtr> Commands;
Commands m_commands;
typedef std::vector<ICommandHandler*> CmdHandlers;
CmdHandlers m_cmdHandlers;
};
#endif // __commandmanager_h__

45
Editor/ConsoleDialog.cpp Normal file
View File

@@ -0,0 +1,45 @@
// ConsoleDialog.cpp : implementation file
//
#include "stdafx.h"
#include "ConsoleDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CConsoleDialog dialog
CConsoleDialog::CConsoleDialog(CWnd* pParent /*=NULL*/)
: CDialog(CConsoleDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CConsoleDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CConsoleDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CConsoleDialog)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CConsoleDialog, CDialog)
//{{AFX_MSG_MAP(CConsoleDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CConsoleDialog message handlers
void CConsoleDialog::OnOK()
{
}

47
Editor/ConsoleDialog.h Normal file
View File

@@ -0,0 +1,47 @@
#if !defined(AFX_CONSOLEDIALOG_H__D9B5584C_9F90_4AA9_B54B_4E4B6BD3A977__INCLUDED_)
#define AFX_CONSOLEDIALOG_H__D9B5584C_9F90_4AA9_B54B_4E4B6BD3A977__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ConsoleDialog.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CConsoleDialog dialog
class CConsoleDialog : public CDialog
{
// Construction
public:
CConsoleDialog(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CConsoleDialog)
enum { IDD = IDD_CONSOLE };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CConsoleDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
virtual void OnCancel() {};
// Generated message map functions
//{{AFX_MSG(CConsoleDialog)
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CONSOLEDIALOG_H__D9B5584C_9F90_4AA9_B54B_4E4B6BD3A977__INCLUDED_)

View File

@@ -0,0 +1,80 @@
// AnimSequences.cpp : implementation file
//
#include "stdafx.h"
#include "AnimSequences.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAnimSequences
CAnimSequences::CAnimSequences()
{
}
CAnimSequences::~CAnimSequences()
{
}
BEGIN_MESSAGE_MAP(CAnimSequences, CComboBox)
//{{AFX_MSG_MAP(CAnimSequences)
ON_WM_CTLCOLOR()
ON_WM_CREATE()
ON_CONTROL_REFLECT(CBN_DROPDOWN, OnDropdown)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAnimSequences message handlers
HBRUSH CAnimSequences::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
////////////////////////////////////////////////////////////////////////
// The combox box should be drawn with a different font
////////////////////////////////////////////////////////////////////////
CFont cComboBoxFont;
HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);
if (nCtlColor == CTLCOLOR_LISTBOX)
{
VERIFY(cComboBoxFont.CreatePointFont(60, "Terminal"));
pDC->SelectObject(&cComboBoxFont);
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
int CAnimSequences::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
////////////////////////////////////////////////////////////////////////
// Change some states of the controls
////////////////////////////////////////////////////////////////////////
static CFont cComboBoxFont;
if (CComboBox::OnCreate(lpCreateStruct) == -1)
return -1;
// Set item size and list box heigt
VERIFY(SetItemHeight(0, 11) != CB_ERR);
VERIFY(SetItemHeight(-1, 150) != CB_ERR);
// Change the font to a smaller one
VERIFY(cComboBoxFont.CreatePointFont(60, "Terminal"));
SetFont(&cComboBoxFont, TRUE);
return 0;
}
void CAnimSequences::OnDropdown()
{
}

View File

@@ -0,0 +1,50 @@
#if !defined(AFX_ANIMSEQUENCES_H__AF987D7B_1EC7_403A_B190_E05E2B2D3FD6__INCLUDED_)
#define AFX_ANIMSEQUENCES_H__AF987D7B_1EC7_403A_B190_E05E2B2D3FD6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// AnimSequences.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CAnimSequences window
class CAnimSequences : public CComboBox
{
// Construction
public:
CAnimSequences();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAnimSequences)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CAnimSequences();
// Generated message map functions
protected:
//{{AFX_MSG(CAnimSequences)
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDropdown();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_ANIMSEQUENCES_H__AF987D7B_1EC7_403A_B190_E05E2B2D3FD6__INCLUDED_)

View File

@@ -0,0 +1,179 @@
// AnimationToolBar.cpp : implementation file
//
#include "stdafx.h"
#include "AnimationToolBar.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAnimationToolBar
CAnimationToolBar::CAnimationToolBar()
{
}
CAnimationToolBar::~CAnimationToolBar()
{
}
BEGIN_MESSAGE_MAP(CAnimationToolBar, CToolBar)
//{{AFX_MSG_MAP(CAnimationToolBar)
ON_WM_SIZE()
ON_WM_CTLCOLOR()
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAnimationToolBar message handlers
void CAnimationToolBar::OnSize(UINT nType, int cx, int cy)
{
////////////////////////////////////////////////////////////////////////
// Resize the keyframe slider
////////////////////////////////////////////////////////////////////////
unsigned int iIndex;
RECT rcCtrl, rcToolbar;
CToolBar::OnSize(nType, cx, cy);
if (!GetToolBarCtrl().GetButtonCount())
return;
// Get the index of the keyframe slider position in the toolbar
iIndex = 0;
while (GetItemID(iIndex) != IDR_KEYFRAMES)
iIndex++;
if (GetItemID(iIndex) != IDR_KEYFRAMES)
return;
// Get size and position of toolbar and slider control
GetItemRect(iIndex, &rcCtrl);
GetClientRect(&rcToolbar);
// Get new slider width
rcCtrl.right = rcToolbar.right;
// Set in if the slider is created
if (m_cKeyframes.m_hWnd)
{
m_cKeyframes.SetWindowPos(NULL, 0, 0, (rcToolbar.right - rcCtrl.left) / 2,
18, SWP_NOMOVE | SWP_NOOWNERZORDER);
}
// Get the index of the animation sequence combo box position in the toolbar
iIndex = 0;
while (GetItemID(iIndex) != IDR_ANIM_SEQUENCES)
iIndex++;
if (GetItemID(iIndex) != IDR_ANIM_SEQUENCES)
return;
// Get size and position of toolbar and combo box control
GetItemRect(iIndex, &rcCtrl);
GetClientRect(&rcToolbar);
// Get new combo box width
rcCtrl.right = rcToolbar.right;
// Set in if the combo box is created
if (m_cAnimSequences.m_hWnd)
{
m_cAnimSequences.SetWindowPos(NULL, 0, 0, (rcToolbar.right - rcCtrl.left) / 2,
18, SWP_NOMOVE | SWP_NOOWNERZORDER);
// Place the combox box right of the keyframe slider
GetItemRect(iIndex, &rcCtrl);
rcCtrl.top += 3;
rcCtrl.bottom += 200;
rcCtrl.left = (rcToolbar.right) / 2 + 65;
rcCtrl.right = (rcToolbar.right) / 2 - 75;
::SetWindowPos(m_cAnimSequences.m_hWnd, NULL, rcCtrl.left, rcCtrl.top,
rcCtrl.right, rcCtrl.bottom, SWP_NOZORDER);
}
}
HBRUSH CAnimationToolBar::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CToolBar::OnCtlColor(pDC, pWnd, nCtlColor);
CFont cComboBoxFont;
if (nCtlColor == CTLCOLOR_EDIT)
{
VERIFY(cComboBoxFont.CreatePointFont(60, "Terminal"));
pDC->SelectObject(&cComboBoxFont);
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
int CAnimationToolBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CToolBar::OnCreate(lpCreateStruct) == -1)
return -1;
if (!LoadToolBar(IDR_ANIMATION))
return -1;
// Create controls in the animation bar
CRect rect;
GetClientRect( &rect );
// Get the index of the keyframe slider position in the toolbar
int iIndex = 0;
while (GetItemID(iIndex) != IDR_KEYFRAMES)
iIndex++;
// Convert that button to a seperator and get its position
SetButtonInfo(iIndex, IDR_KEYFRAMES, TBBS_SEPARATOR, 0);
GetItemRect(iIndex, &rect);
// Expand the rectangle
rect.top += 2;
rect.bottom -= 2;
// TODO: Remove WS_DISABLED when animation is implemented
m_cKeyframes.Create(WS_CHILD|WS_VISIBLE|TBS_HORZ|TBS_BOTTOM|TBS_AUTOTICKS,rect,this,NULL);
// Get the index of the animation sequence combo box position in the toolbar
iIndex = 0;
while (GetItemID(iIndex) != IDR_ANIM_SEQUENCES)
iIndex++;
// Convert that button to a seperator and get its position
//SetButtonInfo(iIndex, IDR_ANIM_SEQUENCES, TBBS_SEPARATOR, 252);
SetButtonInfo(iIndex, IDR_ANIM_SEQUENCES, TBBS_SEPARATOR, 0);
GetItemRect(iIndex, &rect);
// Expand the rectangle
rect.top += 2;
rect.bottom += 75;
// TODO: Remove WS_DISABLED when animation is implemented
m_cAnimSequences.Create(WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST,rect,this,NULL);
m_cKeyframes.SetRange(0, 50);
return 0;
}
CString CAnimationToolBar::GetAnimName()
{
int sel = m_cAnimSequences.GetCurSel();
if (sel == CB_ERR)
{
return "";
}
CString str;
m_cAnimSequences.GetLBText( sel,str );
return str;
}

View File

@@ -0,0 +1,56 @@
#if !defined(AFX_ANIMATIONTOOLBAR_H__4ED3FCE4_CB04_487F_84B5_AE815BE2711D__INCLUDED_)
#define AFX_ANIMATIONTOOLBAR_H__4ED3FCE4_CB04_487F_84B5_AE815BE2711D__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// AnimationToolBar.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CAnimationToolBar window
#include "AnimSequences.h"
class CAnimationToolBar : public CToolBar
{
// Construction
public:
CAnimationToolBar();
// Attributes
public:
// Operations
public:
CString GetAnimName();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAnimationToolBar)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CAnimationToolBar();
CSliderCtrl m_cKeyframes; // IDR_KEYFRAMES
CAnimSequences m_cAnimSequences; // IDR_ANIM_SEQUENCES
// Generated message map functions
protected:
//{{AFX_MSG(CAnimationToolBar)
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_ANIMATIONTOOLBAR_H__4ED3FCE4_CB04_487F_84B5_AE815BE2711D__INCLUDED_)

View File

@@ -0,0 +1,61 @@
// ColorCheckBox.cpp : implementation file
//
#include "stdafx.h"
#include "ColorCheckBox.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CColorCheckBox
IMPLEMENT_DYNCREATE( CColorCheckBox,CButton )
CColorCheckBox::CColorCheckBox()
{
m_nChecked = 0;
}
CColorCheckBox::~CColorCheckBox()
{
}
//BEGIN_MESSAGE_MAP(CColorCheckBox, CColoredPushButton)
// //{{AFX_MSG_MAP(CColorCheckBox)
// // NOTE - the ClassWizard will add and remove mapping macros here.
// //}}AFX_MSG_MAP
//END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CColorCheckBox message handlers
void CColorCheckBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if (m_nChecked == 1)
{
lpDrawItemStruct->itemState |= ODS_SELECTED;
}
CColoredPushButton::DrawItem( lpDrawItemStruct );
}
//////////////////////////////////////////////////////////////////////////
void CColorCheckBox::SetCheck(int nCheck)
{
if (m_nChecked != nCheck)
{
m_nChecked = nCheck;
if(::IsWindow(m_hWnd))
Invalidate();
}
};
//////////////////////////////////////////////////////////////////////////
void CColorCheckBox::PreSubclassWindow()
{
CColoredPushButton::PreSubclassWindow();
SetButtonStyle( BS_PUSHBUTTON|BS_OWNERDRAW );
}

View File

@@ -0,0 +1,62 @@
#if !defined(AFX_COLORCHECKBOX_H__8D5C1FE0_9A53_4247_8CF6_C23C0C829291__INCLUDED_)
#define AFX_COLORCHECKBOX_H__8D5C1FE0_9A53_4247_8CF6_C23C0C829291__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ColorCheckBox.h : header file
//
#define STD_PUSHED_COLOR (RGB(255,255,0))
typedef CColorCtrl<CColorPushButton<CButton> > CColoredPushButton;
typedef CColorCtrl<CColorPushButton<CButton> > CCustomButton;
/////////////////////////////////////////////////////////////////////////////
// CColorCheckBox window
class CColorCheckBox : public CColoredPushButton
{
DECLARE_DYNCREATE( CColorCheckBox )
// Construction
public:
CColorCheckBox();
int GetCheck() const { return m_nChecked; };
void SetCheck(int nCheck);
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CColorCheckBox)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CColorCheckBox();
// Generated message map functions
protected:
//{{AFX_MSG(CColorCheckBox)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
// DECLARE_MESSAGE_MAP()
int m_nChecked;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COLORCHECKBOX_H__8D5C1FE0_9A53_4247_8CF6_C23C0C829291__INCLUDED_)

796
Editor/Controls/ColorCtrl.h Normal file
View File

@@ -0,0 +1,796 @@
#if !defined(AFX_COLORCTRL_H__CA4DE73C_CDC9_11D3_B261_00104BB13A66__INCLUDED_)
#define AFX_COLORCTRL_H__CA4DE73C_CDC9_11D3_B261_00104BB13A66__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include "TemplDef.h" // message map extensions for templates
///////////////////////////////////////////////////////////////////////////////
// class CColorCtrl
//
// Author: Yury Goltsman
// email: ygprg@go.to
// page: http://go.to/ygprg
// Copyright <20> 2000, Yury Goltsman
//
// This code provided "AS IS," without any kind of warranty.
// You may freely use or modify this code provided this
// Copyright is included in all derived versions.
//
// version : 1.5
// fixed - problem with transparency (CLR_NONE)
//
// version : 1.4
// added CColorPushButton - class that allows to change colors for button
//
// version : 1.3
// added pattern for background (for win9x restricted to 8*8 pixels)
// added posibility to use solid colors (in this case we don't
// select transparency for background color)
//
// version : 1.2
// bug fixing
// added typedefs for some mfc controls
// derived templates CColorCtrlEx and CBlinkCtrlEx with initial
// template parameters added
// message map macro added
//
// version : 1.1
// bug fixing
//
enum
{
CC_BLINK_NOCHANGE = 0,
CC_BLINK_FAST = 500,
CC_BLINK_NORMAL = 1000,
CC_BLINK_SLOW = 2000
};
enum
{
CC_BLINK_TEXT = 1,
CC_BLINK_BK = 2,
CC_BLINK_BOTH = CC_BLINK_TEXT|CC_BLINK_BK
};
#define CC_SYSCOLOR(ind) (0x80000000|((ind) & ~CLR_DEFAULT))
template<class BASE_TYPE = CWnd>
class CColorCtrl : public BASE_TYPE
{
public:
CColorCtrl();
virtual ~CColorCtrl(){}
public:
void SetTextColor(COLORREF rgbText = CLR_DEFAULT);
COLORREF GetTextColor(){ return GetColor(m_rgbText); }
void SetTextBlinkColors(COLORREF rgbBlinkText1, COLORREF rgbBlinkText2);
void SetBkColor(COLORREF rgbBk = CLR_DEFAULT);
COLORREF GetBkColor(){ return GetColor(m_rgbBk); }
void SetBkBlinkColors(COLORREF rgbBlinkBk1, COLORREF rgbBlinkBk2);
void SetBkPattern(UINT nBkID = 0);
void SetBkPattern(HBITMAP hbmpBk = 0);
void SetBkBlinkPattern(UINT nBkID1, UINT nBkID2);
void SetBkBlinkPattern(HBITMAP hbmpBk1, HBITMAP hbmpBk2);
void StartBlink(int iWho = CC_BLINK_BOTH, UINT nDelay = CC_BLINK_NOCHANGE);
void StopBlink(int iWho = CC_BLINK_BOTH);
UINT GetDelay() { return m_nDelay; }
void UseSolidColors(BOOL fSolid = TRUE);
void ForceOpaque(){m_fForceOpaque = TRUE;}
//protected:
void SetBlinkTimer()
{
// set timer if blinking mode
if(m_nTimerID <= 0 && (m_fBlinkText || m_fBlinkBk))
m_nTimerID = SetTimer(1, m_nDelay, NULL);
}
void KillBlinkTimer()
{
// reset timer
KillTimer(m_nTimerID);
m_nTimerID = 0;
m_iBlinkPhase = 0;
}
COLORREF GetColor(COLORREF clr)
{
if(clr == CLR_NONE)
return clr;
DWORD mask = clr & CLR_DEFAULT;
if(mask == 0x80000000)
return ::GetSysColor(clr & ~CLR_DEFAULT); // system color
if(mask == CLR_DEFAULT)
return CLR_DEFAULT; // default color
return clr & ~CLR_DEFAULT; // normal color
}
//protected:
UINT m_nTimerID;
int m_iBlinkPhase;
UINT m_nDelay;
BOOL m_fBlinkText;
BOOL m_fBlinkBk;
BOOL m_fSolid;
BOOL m_fForceOpaque;
COLORREF m_rgbText;
COLORREF m_rgbBlinkText[2];
COLORREF m_rgbBk;
CBitmap m_bmpBk;
COLORREF m_rgbBlinkBk[2];
CBitmap m_bmpBlinkBk[2];
CBrush m_brBk;
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CColorCtrl)
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL
//protected:
//{{AFX_MSG(CColorCtrl)
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg void OnDestroy();
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_TEMPLATE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
typedef CColorCtrl<CEdit> CColoredEdit;
typedef CColorCtrl<CButton> CColoredButton;
typedef CColorCtrl<CStatic> CColoredStatic;
typedef CColorCtrl<CScrollBar> CColoredScrollBar;
typedef CColorCtrl<CListBox> CColoredListBox;
typedef CColorCtrl<CComboBox> CColoredComboBox;
typedef CColorCtrl<CDialog> CColoredDialog;
/////////////////////////////////////////////////////////////////////////////
template<class BASE_TYPE>
CColorCtrl<BASE_TYPE>::CColorCtrl()
{
// set control to non-blinking mode
m_nTimerID = 0;
m_iBlinkPhase = 0;
m_nDelay = CC_BLINK_NORMAL;
m_fSolid = FALSE;
m_fForceOpaque = FALSE;
m_fBlinkText = FALSE;
m_fBlinkBk = FALSE;
// set foreground colors
m_rgbText = CLR_DEFAULT;
m_rgbBlinkText[0] = m_rgbText;
m_rgbBlinkText[1] = m_rgbText;
// set background colors
m_rgbBk = CLR_DEFAULT;
m_rgbBlinkBk[0] = m_rgbBk;
m_rgbBlinkBk[1] = m_rgbBk;
}
BEGIN_TEMPLATE_MESSAGE_MAP(class BASE_TYPE, CColorCtrl<BASE_TYPE>, BASE_TYPE)
//{{AFX_MSG_MAP(CColorCtrl)
ON_WM_CTLCOLOR_REFLECT()
ON_WM_CTLCOLOR()
ON_WM_DESTROY()
ON_WM_TIMER()
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_TEMPLATE_MESSAGE_MAP()
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetTextColor(COLORREF rgbText)
{
m_rgbText = rgbText;
if(::IsWindow(m_hWnd))
Invalidate();
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetTextBlinkColors(COLORREF rgbBlinkText1, COLORREF rgbBlinkText2)
{
m_rgbBlinkText[0] = rgbBlinkText1;
m_rgbBlinkText[1] = rgbBlinkText2;
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetBkColor(COLORREF rgbBk)
{
m_rgbBk = rgbBk;
if(::IsWindow(m_hWnd))
Invalidate();
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetBkBlinkColors(COLORREF rgbBlinkBk1, COLORREF rgbBlinkBk2)
{
m_rgbBlinkBk[0] = rgbBlinkBk1;
m_rgbBlinkBk[1] = rgbBlinkBk2;
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetBkPattern(UINT nBkID)
{
m_bmpBk.DeleteObject();
if(nBkID > 0)
m_bmpBk.LoadBitmap(nBkID);
if(::IsWindow(m_hWnd))
Invalidate();
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetBkPattern(HBITMAP hbmpBk)
{
m_bmpBk.DeleteObject();
if(hbmpBk != 0)
m_bmpBk.Attach(hbmpBk);
if(::IsWindow(m_hWnd))
Invalidate();
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetBkBlinkPattern(UINT nBkID1, UINT nBkID2)
{
m_bmpBlinkBk[0].DeleteObject();
m_bmpBlinkBk[1].DeleteObject();
if(nBkID1 > 0)
m_bmpBlinkBk[0].LoadBitmap(nBkID1);
if(nBkID2 > 0)
m_bmpBlinkBk[1].LoadBitmap(nBkID2);
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetBkBlinkPattern(HBITMAP hbmpBk1, HBITMAP hbmpBk2)
{
m_bmpBlinkBk[0].DeleteObject();
m_bmpBlinkBk[1].DeleteObject();
if(hbmpBk1 != 0)
m_bmpBlinkBk[0].Attach(hbmpBk1);
if(hbmpBk2 != 0)
m_bmpBlinkBk[1].Attach(hbmpBk2);
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::UseSolidColors(BOOL fSolid)
{
m_fSolid = fSolid;
if(::IsWindow(m_hWnd))
Invalidate();
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::StartBlink(int iWho, UINT nDelay)
{
if(iWho & CC_BLINK_TEXT)
m_fBlinkText = TRUE;
if(iWho & CC_BLINK_BK)
m_fBlinkBk = TRUE;
if(nDelay != CC_BLINK_NOCHANGE)
{
m_nDelay = nDelay;
if (m_nTimerID > 0)
{
ASSERT(::IsWindow(m_hWnd));
// reset old timer if delay changed
KillBlinkTimer();
}
}
ASSERT(m_fBlinkText||m_fBlinkBk);
if(!::IsWindow(m_hWnd))
return;
// if no timer - set it
SetBlinkTimer();
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::StopBlink(int iWho)
{
if(iWho & CC_BLINK_TEXT)
m_fBlinkText = FALSE;
if(iWho & CC_BLINK_BK)
m_fBlinkBk = FALSE;
if(m_nTimerID > 0 && !m_fBlinkText && !m_fBlinkBk)
{
ASSERT(::IsWindow(m_hWnd));
// stop timer if no blinking and repaint
KillBlinkTimer();
Invalidate();
}
}
template<class BASE_TYPE>
HBRUSH CColorCtrl<BASE_TYPE>::CtlColor(CDC* pDC, UINT nCtlColor)
{
// Get foreground color
COLORREF rgbText = GetColor(m_fBlinkText ? m_rgbBlinkText[m_iBlinkPhase]
: m_rgbText);
// Get background color
COLORREF rgbBk = GetColor(m_fBlinkBk ? m_rgbBlinkBk[m_iBlinkPhase]
: m_rgbBk);
// Get background pattern
CBitmap& bmpBk = m_fBlinkBk ? m_bmpBlinkBk[m_iBlinkPhase] : m_bmpBk;
// if both colors are default - use default colors
if(rgbText == CLR_DEFAULT && rgbBk == CLR_DEFAULT && !bmpBk.GetSafeHandle())
return 0;
// if one of colors is default - get system color for it
if(rgbBk == CLR_DEFAULT)
{
// text color specified and background - not.
switch(nCtlColor)
{
case CTLCOLOR_EDIT:
case CTLCOLOR_LISTBOX:
rgbBk = GetSysColor(COLOR_WINDOW);
break;
case CTLCOLOR_BTN:
case CTLCOLOR_DLG:
case CTLCOLOR_MSGBOX:
case CTLCOLOR_STATIC:
default:
rgbBk = ::GetSysColor(COLOR_BTNFACE);
break;
case CTLCOLOR_SCROLLBAR:
// for scroll bar no meaning in text color - use parent OnCtlColor
return 0;
}
}
if(rgbText == CLR_DEFAULT)
{
// background color specified and text - not.
switch(nCtlColor)
{
default:
rgbText = ::GetSysColor(COLOR_WINDOWTEXT);
break;
case CTLCOLOR_BTN:
rgbText = ::GetSysColor(COLOR_BTNTEXT);
break;
}
}
ASSERT(rgbText != CLR_DEFAULT);
ASSERT(rgbBk != CLR_DEFAULT);
if(m_fSolid)
{
if(rgbBk != CLR_NONE)
rgbBk = ::GetNearestColor(pDC->m_hDC, rgbBk);
rgbText = ::GetNearestColor(pDC->m_hDC, rgbText);
}
if(m_fForceOpaque && rgbBk != CLR_NONE)
pDC->SetBkMode(OPAQUE);
else
pDC->SetBkMode(TRANSPARENT);
// set colors
pDC->SetTextColor(rgbText);
pDC->SetBkColor(rgbBk);
// update brush
m_brBk.DeleteObject();
if(bmpBk.GetSafeHandle())
m_brBk.CreatePatternBrush(&bmpBk);
else if(rgbBk != CLR_NONE)
m_brBk.CreateSolidBrush(rgbBk);
else
return (HBRUSH) ::GetStockObject (HOLLOW_BRUSH);
return (HBRUSH)m_brBk;
}
template<class BASE_TYPE>
HBRUSH CColorCtrl<BASE_TYPE>::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if(pWnd->m_hWnd == m_hWnd)
return BASE_TYPE::OnCtlColor(pDC, pWnd, nCtlColor); // for dialogs
return BASE_TYPE::OnCtlColor(pDC, this, nCtlColor); // send reflect message
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::OnDestroy()
{
// kill timer
KillBlinkTimer();
BASE_TYPE::OnDestroy();
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent != m_nTimerID)
{
BASE_TYPE::OnTimer(nIDEvent);
return;
}
// if there is active blinking
if (m_fBlinkBk || m_fBlinkText)
{
// change blinking phase and repaint
m_iBlinkPhase = !m_iBlinkPhase;
Invalidate();
}
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::PreSubclassWindow()
{
// set timer if blinking mode
SetBlinkTimer();
BASE_TYPE::PreSubclassWindow();
}
template<class BASE_TYPE>
int CColorCtrl<BASE_TYPE>::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (BASE_TYPE::OnCreate(lpCreateStruct) == -1)
return -1;
// set timer if blinking mode
SetBlinkTimer();
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// class CColorCtrlEx
template<class BASE_TYPE, int InitialTextColor = CLR_DEFAULT, int InitialBkColor = CLR_DEFAULT>
class CColorCtrlEx : public CColorCtrl<BASE_TYPE>
{
public:
CColorCtrlEx()
{
m_rgbText = InitialTextColor;
m_rgbBk = InitialBkColor;
}
};
///////////////////////////////////////////////////////////////////////////////
// class CBlinkCtrlEx
template<class BASE_TYPE,
int InitialTextColor0 = CLR_DEFAULT,
int InitialTextColor1 = CLR_DEFAULT,
int InitialBkColor0 = CLR_DEFAULT,
int InitialBkColor1 = CLR_DEFAULT,
int InitialDelay = CC_BLINK_NORMAL>
class CBlinkCtrlEx : public CColorCtrl<BASE_TYPE>
{
public:
CBlinkCtrlEx()
{
m_nDelay = InitialDelay;
m_rgbBlinkText[0] = InitialTextColor0;
m_rgbBlinkText[1] = InitialTextColor1;
if(InitialTextColor0 != CLR_DEFAULT || InitialTextColor1 != CLR_DEFAULT)
m_fBlinkText = TRUE;
m_rgbBlinkBk[0] = InitialBkColor0;
m_rgbBlinkBk[1] = InitialBkColor1;
if(InitialBkColor0 != CLR_DEFAULT || InitialBkColor1 != CLR_DEFAULT)
m_fBlinkBk = TRUE;
}
};
///////////////////////////////////////////////////////////////////////////////
// class CColorPushButton
template<class BASE_TYPE>
class CColorPushButton : public BASE_TYPE
{
public:
CColorPushButton();
~CColorPushButton();
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CColorPushButton)
protected:
virtual void PreSubclassWindow();
virtual BOOL PreTranslateMessage(MSG* pMsg);
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL
public:
void SetNoFocus(bool fNoFocus = true){m_fNoFocus = fNoFocus;}
void SetNoDisabledState(bool fNoDisabledState = true) {m_fNoDisabledState = fNoDisabledState;}
void SetPushedBkColor(COLORREF rgbBk = CLR_DEFAULT);
COLORREF GetPushedBkColor(){ return GetColor(m_rgbBk); }
//! Set icon to display on button, (must not be shared).
void SetIcon( HICON hIcon );
void SetIcon( LPCSTR lpszIconResource );
void SetToolTip( const char *tooltipText );
protected:
void ChangeStyle();
bool m_fNoFocus;
bool m_fNoDisabledState;
COLORREF m_rgbPushedBk;
CBrush m_pushedBk;
HICON m_hIcon;
CToolTipCtrl *m_tooltip;
//{{AFX_MSG(CColorPushButton)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_TEMPLATE_MESSAGE_MAP()
};
BEGIN_TEMPLATE_MESSAGE_MAP(class BASE_TYPE, CColorPushButton<BASE_TYPE>, BASE_TYPE)
//{{AFX_MSG_MAP(CColorPushButton)
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_TEMPLATE_MESSAGE_MAP()
template<class BASE_TYPE>
CColorPushButton<BASE_TYPE>::CColorPushButton()
{
m_fNoFocus = true;
m_fNoDisabledState = false;
m_hIcon = 0;
m_tooltip=0;
// Yellow pushed button.
m_pushedBk.CreateSolidBrush( RGB(255,255,0) );
}
template<class BASE_TYPE>
CColorPushButton<BASE_TYPE>::~CColorPushButton()
{
if (m_tooltip)
delete m_tooltip;
m_tooltip = 0;
if (m_hIcon)
DestroyIcon(m_hIcon);
}
template<class BASE_TYPE>
void CColorPushButton<BASE_TYPE>::SetToolTip( const char *tooltipText )
{
if (!m_tooltip)
{
m_tooltip = new CToolTipCtrl;
m_tooltip->Create( this );
CRect rc;
GetClientRect(rc);
m_tooltip->AddTool( this,tooltipText,rc,1 );
}
else
{
m_tooltip->UpdateTipText( tooltipText,this,1 );
}
m_tooltip->Activate(TRUE);
}
template<class BASE_TYPE>
void CColorPushButton<BASE_TYPE>::SetIcon( LPCSTR lpszIconResource )
{
if (m_hIcon)
DestroyIcon(m_hIcon);
SetIcon( (HICON)::LoadImage( AfxGetInstanceHandle(),lpszIconResource,IMAGE_ICON,0,0,0 ) );
}
template<class BASE_TYPE>
void CColorPushButton<BASE_TYPE>::SetIcon( HICON hIcon )
{
m_hIcon = hIcon;
// Get tool tip from title.
CString sCaption;
GetWindowText(sCaption);
SetToolTip(sCaption);
};
template<class BASE_TYPE>
void CColorPushButton<BASE_TYPE>::SetPushedBkColor(COLORREF rgbBk)
{
m_rgbPushedBk = rgbBk;
m_pushedBk.DeleteObject();
m_pushedBk.CreateSolidBrush( m_rgbPushedBk );
if(::IsWindow(m_hWnd))
Invalidate();
}
template<class BASE_TYPE>
BOOL CColorPushButton<BASE_TYPE>::PreTranslateMessage(MSG* pMsg)
{
if (m_tooltip && m_tooltip->m_hWnd != 0)
m_tooltip->RelayEvent(pMsg);
return BASE_TYPE::PreTranslateMessage(pMsg);
}
template<class BASE_TYPE>
void CColorPushButton<BASE_TYPE>::PreSubclassWindow()
{
ChangeStyle();
BASE_TYPE::PreSubclassWindow();
}
template<class BASE_TYPE>
int CColorPushButton<BASE_TYPE>::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (BASE_TYPE::OnCreate(lpCreateStruct) == -1)
return -1;
ChangeStyle();
return 0;
}
template<class BASE_TYPE>
void CColorPushButton<BASE_TYPE>::ChangeStyle()
{
CString sClassName;
GetClassName(m_hWnd, sClassName.GetBuffer(10), 10);
sClassName.ReleaseBuffer();
DWORD style = GetStyle();
ASSERT(sClassName.CompareNoCase(_T("BUTTON")) == 0); // must be used only with buttons
ASSERT((style & (BS_BITMAP)) == 0); // dont supports bitmap buttons
//ASSERT((style & (BS_ICON|BS_BITMAP)) == 0); // dont supports icon/bitmap buttons
if((style & 0xf) == BS_PUSHBUTTON ||
(style & 0xf) == BS_DEFPUSHBUTTON)
{
ModifyStyle(0xf, BS_OWNERDRAW);
Invalidate(FALSE);
}
}
template<class BASE_TYPE>
void CColorPushButton<BASE_TYPE>::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rc(lpDrawItemStruct->rcItem);
UINT state = lpDrawItemStruct->itemState;
CString sCaption;
GetWindowText(sCaption);
DWORD style = GetStyle();
CRect rcFocus(rc);
rcFocus.DeflateRect(4, 4);
int iSavedDC = pDC->SaveDC();
//pDC->SetBkColor( m_rgbPushedBk );
// draw frame
if(((state & ODS_DEFAULT) || (state & ODS_FOCUS)) && !m_fNoFocus)
{
// draw def button black rectangle
pDC->Draw3dRect(rc, GetSysColor(COLOR_WINDOWFRAME), GetSysColor(COLOR_WINDOWFRAME));
rc.DeflateRect(1, 1);
}
if(style & BS_FLAT)
{
pDC->Draw3dRect(rc, GetSysColor(COLOR_WINDOWFRAME), GetSysColor(COLOR_WINDOWFRAME));
rc.DeflateRect(1, 1);
pDC->Draw3dRect(rc, GetSysColor(COLOR_WINDOW), GetSysColor(COLOR_WINDOW));
rc.DeflateRect(1, 1);
}
else
{
if(state & ODS_SELECTED)
{
pDC->Draw3dRect(rc, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DSHADOW));
rc.DeflateRect(1, 1);
//pDC->Draw3dRect(rc, GetSysColor(COLOR_3DFACE), GetSysColor(COLOR_3DFACE));
//rc.DeflateRect(1, 1);
}
else
{
pDC->Draw3dRect(rc, GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
rc.DeflateRect(1, 1);
//pDC->Draw3dRect(rc, GetSysColor(COLOR_3DFACE), GetSysColor(COLOR_3DSHADOW));
//rc.DeflateRect(1, 1);
}
}
// fill background
HBRUSH brush = (HBRUSH)SendMessage(WM_CTLCOLORBTN, (WPARAM)pDC->m_hDC, (LPARAM)m_hWnd);
if(state & ODS_SELECTED)
{
pDC->SetBkMode(TRANSPARENT);
brush = m_pushedBk;
}
if(brush)
::FillRect(pDC->m_hDC, rc, brush);
if (m_hIcon)
{
// draw icon.
int w = GetSystemMetrics(SM_CXICON);
int h = GetSystemMetrics(SM_CYICON);
int x = rc.left + rc.Width()/2 - w/2+1;
int y = rc.top + rc.Height()/2 - h/2;
if(state & ODS_SELECTED)
{
x += 1; y += 1;
}
pDC->DrawIcon( CPoint(x,y),m_hIcon );
}
else
{
// draw text
UINT fTextStyle = 0;
switch(style & BS_CENTER)
{
case BS_LEFT : fTextStyle |= DT_LEFT; break;
case BS_RIGHT : fTextStyle |= DT_RIGHT; break;
default:
case BS_CENTER : fTextStyle |= DT_CENTER; break;
}
switch(style & BS_VCENTER)
{
case BS_TOP : fTextStyle |= DT_TOP; break;
case BS_BOTTOM : fTextStyle |= DT_BOTTOM; break;
default:
case BS_VCENTER : fTextStyle |= DT_VCENTER; break;
}
if(!(style & BS_MULTILINE)) fTextStyle |= DT_SINGLELINE;
else fTextStyle |= DT_WORDBREAK;
if(state & ODS_DISABLED && !m_fNoDisabledState)
{
pDC->SetBkMode(TRANSPARENT);
rc.DeflateRect(2, 2, 0, 0); // shift text down
pDC->SetTextColor(GetSysColor(COLOR_3DHILIGHT));
pDC->DrawText(sCaption, rc, fTextStyle);
rc.OffsetRect(-1, -1); // shift text up
pDC->SetTextColor(GetSysColor(COLOR_3DSHADOW));
pDC->DrawText(sCaption, rc, fTextStyle);
}
else
{
if(state & ODS_SELECTED)
rc.DeflateRect(2, 2, 0, 0); // shift text
pDC->DrawText(sCaption, rc, fTextStyle);
}
}
pDC->RestoreDC(iSavedDC);
// draw focus rect
if ((state & ODS_FOCUS) && !m_fNoFocus)
pDC->DrawFocusRect(rcFocus);
}
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COLORCTRL_H__CA4DE73C_CDC9_11D3_B261_00104BB13A66__INCLUDED_)

View File

@@ -0,0 +1,384 @@
// ConsoleSCB.cpp: implementation of the CConsoleSCB class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ConsoleSCB.h"
#include "PropertiesDialog.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
static CPropertiesDialog *gPropertiesDlg = 0;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(CConsoleEdit, CEdit)
ON_WM_GETDLGCODE()
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(CConsoleSCB, CWnd)
//{{AFX_MSG_MAP(CConsoleSCB)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_DESTROY()
ON_WM_SETFOCUS()
ON_EN_SETFOCUS( IDC_EDIT,OnEditSetFocus )
ON_EN_KILLFOCUS( IDC_EDIT,OnEditKillFocus )
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
static CVarBlock* VarBlockFromConsoleVars()
{
IConsole *console = GetIEditor()->GetSystem()->GetIConsole();
std::vector<const char*> cmds;
cmds.resize( console->GetNumVars() );
console->GetSortedVars( &cmds[0],cmds.size() );
CVarBlock *vb = new CVarBlock;
IVariable* pVariable;
for (int i = 0; i < cmds.size(); i++)
{
ICVar *pCVar = console->GetCVar(cmds[i]);
int varType = pCVar->GetType();
switch(varType) {
case CVAR_INT:
pVariable = new CVariable<int>;
pVariable->SetName(cmds[i]);
pVariable->Set( pCVar->GetIVal() );
vb->AddVariable( pVariable );
pVariable->SetDescription( pCVar->GetHelp() );
pVariable->SetDescription( pCVar->GetHelp() );
break;
case CVAR_FLOAT:
pVariable = new CVariable<float>;
pVariable->SetName(cmds[i]);
pVariable->Set( pCVar->GetFVal() );
pVariable->SetDescription( pCVar->GetHelp() );
vb->AddVariable( pVariable );
break;
case CVAR_STRING:
pVariable = new CVariable<CString>;
pVariable->SetName(cmds[i]);
pVariable->Set( pCVar->GetString() );
pVariable->SetDescription( pCVar->GetHelp() );
vb->AddVariable( pVariable );
break;
}
}
return vb;
}
static void OnConsoleVariableUpdated( IVariable *pVar )
{
if (!pVar)
return;
CString varName = pVar->GetName();
ICVar *pCVar = GetIEditor()->GetSystem()->GetIConsole()->GetCVar(varName);
if (!pCVar)
return;
if (pVar->GetType() == IVariable::INT)
{
int val;
pVar->Get(val);
pCVar->Set(val);
}
else if (pVar->GetType() == IVariable::FLOAT)
{
float val;
pVar->Get(val);
pCVar->Set(val);
}
else if (pVar->GetType() == IVariable::STRING)
{
CString val;
pVar->Get(val);
pCVar->Set(val);
}
}
//////////////////////////////////////////////////////////////////////////
static CString popup_helper( HWND hwnd,int x,int y )
{
IConsole *console = GetIEditor()->GetSystem()->GetIConsole();
std::vector<const char*> cmds;
cmds.resize( console->GetNumVars() );
console->GetSortedVars( &cmds[0],cmds.size() );
TSmartPtr<CVarBlock> vb = VarBlockFromConsoleVars();
XmlNodeRef node;
if (!gPropertiesDlg)
gPropertiesDlg = new CPropertiesDialog( "Console Variables",node,AfxGetMainWnd() );
if (!gPropertiesDlg->m_hWnd)
{
gPropertiesDlg->Create( CPropertiesDialog::IDD,AfxGetMainWnd() );
gPropertiesDlg->SetUpdateCallback( functor(OnConsoleVariableUpdated) );
}
gPropertiesDlg->ShowWindow( SW_SHOW );
gPropertiesDlg->GetPropertyCtrl()->AddVarBlock( vb );
/*
HMENU hm = CreatePopupMenu();
for (int i = 0; i < cmds.size(); i++) {
AppendMenu( hm,MF_STRING,i+1,cmds[i] );
}
int res = TrackPopupMenuEx( hm,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD,x,y,hwnd,NULL );
if (res > 0) {
return cmds[res-1];
}
*/
return "";
}
UINT CConsoleEdit::OnGetDlgCode()
{
UINT code = CEdit::OnGetDlgCode();
code |= DLGC_WANTMESSAGE;
return code;
}
BOOL CConsoleEdit::PreTranslateMessage(MSG* msg)
{
if (msg->message == WM_LBUTTONDBLCLK || msg->message == WM_RBUTTONDOWN)
{
CPoint pnt;
GetCursorPos(&pnt);
CString str = popup_helper( GetSafeHwnd(),pnt.x,pnt.y );
if (!str.IsEmpty())
{
SetWindowText( str+" " );
}
}
else if (msg->message == WM_CHAR)
{
switch (msg->wParam)
{
case '~':
case '`':
// disable log.
GetIEditor()->ShowConsole( false );
SetWindowText( "" );
break;
}
} else if (msg->message == WM_KEYDOWN)
{
switch (msg->wParam)
{
case VK_RETURN:
{
CString str;
GetWindowText( str );
// Execute this string as command.
if (!str.IsEmpty())
{
CLogFile::WriteLine( str );
GetIEditor()->GetSystem()->GetIConsole()->ExecuteString( str );
m_history.erase( std::remove(m_history.begin(),m_history.end(),str),m_history.end() );
m_history.push_back(str);
}
SetWindowText( "" );
return 0;
}
return TRUE;
break;
case VK_TAB:
{
GetAsyncKeyState(VK_CONTROL);
bool bCtrl = GetAsyncKeyState(VK_CONTROL) != 0;
IConsole *console = GetIEditor()->GetSystem()->GetIConsole();
CString inputStr,newStr;
GetWindowText( inputStr );
inputStr = inputStr.SpanExcluding( " " );
if (!bCtrl)
{
newStr = console->AutoComplete( inputStr );
}
else
{
newStr = console->AutoCompletePrev( inputStr );
}
if (!newStr.IsEmpty())
{
newStr += " ";
SetWindowText( newStr );
}
CString str;
GetWindowText( str );
SetSel( str.GetLength(),str.GetLength() );
return TRUE;
}
return TRUE;
break;
case VK_UP:
case VK_DOWN:
{
CString str;
CMenu menu;
menu.CreatePopupMenu();
for (int i = 0; i < m_history.size(); i++) {
menu.AppendMenu( MF_STRING,i+1,m_history[i] );
}
CPoint pnt;
GetCursorPos(&pnt);
int res = ::TrackPopupMenuEx( menu.GetSafeHmenu(),TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD,pnt.x,pnt.y,GetSafeHwnd(),NULL );
if (res > 0) {
str = m_history[res-1];
}
if (!str.IsEmpty())
{
SetWindowText( str );
SetSel( str.GetLength(),str.GetLength() );
}
}
return TRUE;
case VK_ESCAPE:
// disable log.
GetIEditor()->ShowConsole( false );
return TRUE;
break;
}
}
return CEdit::PreTranslateMessage(msg);
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CConsoleSCB::CConsoleSCB()
{
CLogFile::WriteLine("Console created");
}
CConsoleSCB::~CConsoleSCB()
{
if (gPropertiesDlg)
delete gPropertiesDlg;
gPropertiesDlg = 0;
CLogFile::WriteLine("Console destroyed");
}
int CConsoleSCB::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
////////////////////////////////////////////////////////////////////////
// Create the edit control and register it
////////////////////////////////////////////////////////////////////////
RECT rcEdit;
CFont cListBoxFont;
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
/*
// Create the edit control
VERIFY(m_cListBox.Create(WS_CHILD | WS_VISIBLE | WS_VSCROLL |
LBS_NOSEL, rcEdit, this, NULL));
m_cListBox.ShowWindow( SW_HIDE );
*/
m_dialog.Create( CConsoleDialog::IDD,this );
m_edit.Create( WS_CHILD|WS_VISIBLE|ES_MULTILINE|WS_VSCROLL|ES_AUTOVSCROLL|ES_AUTOHSCROLL|ES_READONLY, rcEdit, &m_dialog, NULL );
m_edit.SetFont( CFont::FromHandle( (HFONT)::GetStockObject(DEFAULT_GUI_FONT)) );
m_edit.ModifyStyleEx( 0,WS_EX_STATICEDGE );
m_edit.SetLimitText(0);
m_input.Create( WS_CHILD|WS_VISIBLE|ES_WANTRETURN|ES_AUTOHSCROLL|WS_TABSTOP, rcEdit, &m_dialog, IDC_EDIT );
m_input.SetFont( CFont::FromHandle( (HFONT)::GetStockObject(SYSTEM_FONT)) );
m_input.ModifyStyleEx( 0,WS_EX_STATICEDGE );
m_input.SetWindowText( "" );
/*
// Change
cListBoxFont.Attach(::GetStockObject(DEFAULT_GUI_FONT));
m_cListBox.SetFont(&cListBoxFont);
cListBoxFont.Detach();
*/
// Attach / register the listbox control
//CLogFile::AttachListBox(m_cListBox.m_hWnd);
CLogFile::AttachEditBox(m_edit.GetSafeHwnd());
return 0;
}
void CConsoleSCB::OnSize(UINT nType, int cx, int cy)
{
////////////////////////////////////////////////////////////////////////
// Resize the edit control
////////////////////////////////////////////////////////////////////////
RECT rcEdit;
CWnd::OnSize(nType, cx, cy);
// Get the size of the client window
GetClientRect(&rcEdit);
/*
// Set the position of the listbox
m_cListBox.SetWindowPos(NULL, rcEdit.left + 3, rcEdit.top + 3, rcEdit.right - 6,
rcEdit.bottom - 6, SWP_NOZORDER);
*/
int inputH = 18;
m_dialog.MoveWindow( rcEdit.left,rcEdit.top,rcEdit.right,rcEdit.bottom );
m_edit.SetWindowPos(NULL, rcEdit.left, rcEdit.top + 2, rcEdit.right, rcEdit.bottom - 1 - inputH, SWP_NOZORDER);
m_input.SetWindowPos(NULL, rcEdit.left, rcEdit.bottom-inputH, rcEdit.right, rcEdit.bottom - 2, SWP_NOZORDER);
m_input.SetFocus();
}
void CConsoleSCB::OnDestroy()
{
////////////////////////////////////////////////////////////////////////
// Unregister the edit control
////////////////////////////////////////////////////////////////////////
CLogFile::AttachEditBox(NULL);
CLogFile::WriteLine("Console control bar destroied");
}
void CConsoleSCB::OnSetFocus( CWnd* pOldWnd )
{
m_input.SetFocus();
}
BOOL CConsoleSCB::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
return TRUE;
}
void CConsoleSCB::OnEditSetFocus()
{
// Disable accelerators when Edit gets focus.
GetIEditor()->EnableAcceleratos( false );
}
void CConsoleSCB::OnEditKillFocus()
{
// Enable accelerators when Edit loose focus.
GetIEditor()->EnableAcceleratos( true );
}
void CConsoleSCB::SetInputFocus()
{
m_input.SetFocus();
m_input.SetWindowText( "" );
}

View File

@@ -0,0 +1,63 @@
// ConsoleSCB.h: interface for the CConsoleSCB class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CONSOLESCB_H__F8855885_1C08_4504_BDA3_7BFB98D381EA__INCLUDED_)
#define AFX_CONSOLESCB_H__F8855885_1C08_4504_BDA3_7BFB98D381EA__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "sizecbar.h"
#include "scbarg.h"
#include "ConsoleDialog.h"
/** Edit box used for input in Console.
*/
class CConsoleEdit : public CEdit
{
public:
DECLARE_MESSAGE_MAP()
virtual BOOL PreTranslateMessage(MSG* pMsg);
afx_msg UINT OnGetDlgCode();
private:
std::vector<CString> m_history;
};
/** Console class.
*/
class CConsoleSCB : public CWnd
{
public:
CConsoleSCB();
virtual ~CConsoleSCB();
void SetInputFocus();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMyBar)
//}}AFX_VIRTUAL
protected:
CListBox m_cListBox;
CEdit m_edit;
CConsoleEdit m_input;
CConsoleDialog m_dialog;
//{{AFX_MSG(CMyBar)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void CConsoleSCB::OnDestroy();
afx_msg void OnSetFocus( CWnd* pOldWnd );
afx_msg void OnEditSetFocus();
afx_msg void OnEditKillFocus();
virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif // !defined(AFX_CONSOLESCB_H__F8855885_1C08_4504_BDA3_7BFB98D381EA__INCLUDED_)

View File

@@ -0,0 +1,98 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: customcomboboxex.h
// Version: v1.00
// Created: 4/9/2003 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __customcomboboxex_h__
#define __customcomboboxex_h__
#pragma once
/////////////////////////////////////////////////////////////////////////////
// CCustomComboBoxEx template control
template<class BASE_TYPE>
class CCustomComboBoxEx : public BASE_TYPE
{
protected:
virtual BOOL PreTranslateMessage(MSG* pMsg);
afx_msg UINT OnGetDlgCode();
DECLARE_TEMPLATE_MESSAGE_MAP()
};
BEGIN_TEMPLATE_MESSAGE_MAP(class BASE_TYPE, CCustomComboBoxEx<BASE_TYPE>, BASE_TYPE)
//{{AFX_MSG_MAP(CColorPushButton)
ON_WM_GETDLGCODE()
//}}AFX_MSG_MAP
END_TEMPLATE_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////////
template<class BASE_TYPE>
UINT CCustomComboBoxEx<BASE_TYPE>::OnGetDlgCode()
{
return DLGC_WANTMESSAGE;
}
//////////////////////////////////////////////////////////////////////////
template<class BASE_TYPE>
BOOL CCustomComboBoxEx<BASE_TYPE>::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN)
{
if (pMsg->wParam == VK_RETURN)
{
NMCBEENDEDIT endEdit;
endEdit.hdr.code = CBEN_ENDEDIT;
endEdit.hdr.hwndFrom = m_hWnd;
endEdit.hdr.idFrom = GetDlgCtrlID();
endEdit.fChanged = true;
endEdit.iNewSelection = CB_ERR;
endEdit.iWhy = CBENF_RETURN;
CString text;
GetWindowText( text );
strcpy( endEdit.szText,text );
GetParent()->SendMessage( WM_NOTIFY,(WPARAM)GetDlgCtrlID(),(LPARAM)(&endEdit) );
return TRUE;
}
if (pMsg->wParam == VK_ESCAPE)
{
SetWindowText( "" );
return TRUE;
}
}
if (pMsg->message == WM_KILLFOCUS)
{
NMCBEENDEDIT endEdit;
endEdit.hdr.code = CBEN_ENDEDIT;
endEdit.hdr.hwndFrom = m_hWnd;
endEdit.hdr.idFrom = GetDlgCtrlID();
endEdit.fChanged = true;
endEdit.iNewSelection = CB_ERR;
endEdit.iWhy = CBENF_KILLFOCUS;
CString text;
GetWindowText( text );
strcpy( endEdit.szText,text );
GetParent()->SendMessage( WM_NOTIFY,(WPARAM)GetDlgCtrlID(),(LPARAM)(&endEdit) );
return TRUE;
}
return BASE_TYPE::PreTranslateMessage(pMsg);
}
#endif // __customcomboboxex_h__

170
Editor/Controls/DLGBARS.CPP Normal file
View File

@@ -0,0 +1,170 @@
/*****************************************************************************
DLGBARS.CPP
Purpose:
Interface for CDlgToolBar, a special type of CToolBar which does not
expect a parent frame window to be available, and CDlgStatusBar, which
does the same for CStatusBars. This allows the control bars
to be used in applications where the main window is a dialog bar.
Functions:
CDlgToolBar::CDlgToolBar() -- constructor
CDlgToolBar::~CDlgToolBar() -- destructor
CDlgToolBar::OnIdleUpdateCmdUI() -- WM_IDLEUPDATECMDUI handler
CDlgStatusBar::CDlgStatusBar() -- constructor
CDlgStatusBar::~CDlgStatusBar() -- destructor
CDlgStatusBar::OnIdleUpdateCmdUI() -- WM_IDLEUPDATECMDUI handler
Development Team:
Mary Kirtland
Ported to 32-bit by:
Mike Hedley
Written by Microsoft Product Support Services, Premier ISV Support
Copyright (c) 1996 Microsoft Corporation. All rights reserved.
\****************************************************************************/
#include "stdafx.h"
#include <afxpriv.h>
#include "dlgbars.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDlgToolBar
BEGIN_MESSAGE_MAP(CDlgToolBar, CToolBar)
//{{AFX_MSG_MAP(CDlgToolBar)
ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgToolBar Construction/Destruction
CDlgToolBar::CDlgToolBar()
{
}
CDlgToolBar::~CDlgToolBar()
{
}
/////////////////////////////////////////////////////////////////////////////
// CDlgToolBar::OnIdleUpdateCmdUI
// OnIdleUpdateCmdUI handles the WM_IDLEUPDATECMDUI message, which is
// used to update the status of user-interface elements within the MFC
// framework.
//
// We have to get a little tricky here: CToolBar::OnUpdateCmdUI
// expects a CFrameWnd pointer as its first parameter. However, it
// doesn't do anything but pass the parameter on to another function
// which only requires a CCmdTarget pointer. We can get a CWnd pointer
// to the parent window, which is a CCmdTarget, but may not be a
// CFrameWnd. So, to make CToolBar::OnUpdateCmdUI happy, we will call
// our CWnd pointer a CFrameWnd pointer temporarily.
LRESULT CDlgToolBar::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM)
{
if (IsWindowVisible())
{
CFrameWnd *pParent = (CFrameWnd *)GetParent();
if (pParent)
OnUpdateCmdUI(pParent, (BOOL)wParam);
}
return 0L;
}
//////////////////////////////////////////////////////////////////////////
BOOL CDlgToolBar::LoadToolBar24( UINT nIDResource,int nBtnWidth )
{
CBitmap toolbarBitmap;
CImageList toolbarImageList;
BOOL bRes = LoadToolBar(nIDResource);
VERIFY(bRes);
/*
//////////////////////////////////////////////////////////////////////////
// Use 24Bit toolbars.
//////////////////////////////////////////////////////////////////////////
toolbarBitmap.LoadBitmap(IDR_MAINFRAME);
toolbarImageList.Create(16, 15, ILC_COLORDDB|ILC_MASK, 1, 1);
toolbarImageList.Add(&toolbarBitmap,TOOLBAR_TRANSPARENT_COLOR);
SendMessage(TB_SETIMAGELIST, 0, (LPARAM)toolbarImageList.m_hImageList);
*/
CImageList imageList;
CBitmap bitmap;
BITMAP bmBitmap;
if (!bitmap.Attach(LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(nIDResource),IMAGE_BITMAP, 0, 0,LR_DEFAULTSIZE|LR_CREATEDIBSECTION)))
return FALSE;
if (!bitmap.GetBitmap(&bmBitmap))
return FALSE;
CSize cSize(bmBitmap.bmWidth, bmBitmap.bmHeight);
RGBTRIPLE* rgb = (RGBTRIPLE*)(bmBitmap.bmBits);
int nCount = cSize.cx/nBtnWidth;
if (!imageList.Create(nBtnWidth, cSize.cy, ILC_COLOR24|ILC_MASK, nCount, 0))
return FALSE;
if (imageList.Add(&bitmap,TOOLBAR_TRANSPARENT_COLOR) == -1)
return FALSE;
SendMessage(TB_SETIMAGELIST, 0, (LPARAM)imageList.m_hImageList);
imageList.Detach();
bitmap.Detach();
return bRes;
}
/////////////////////////////////////////////////////////////////////////////
// CDlgStatusBar
BEGIN_MESSAGE_MAP(CDlgStatusBar, CStatusBar)
//{{AFX_MSG_MAP(CDlgStatusBar)
ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgStatusBar Construction/Destruction
CDlgStatusBar::CDlgStatusBar()
{
}
CDlgStatusBar::~CDlgStatusBar()
{
}
/////////////////////////////////////////////////////////////////////////////
// CDlgStatusBar::OnIdleUpdateCmdUI
// OnIdleUpdateCmdUI handles the WM_IDLEUPDATECMDUI message, which is
// used to update the status of user-interface elements within the MFC
// framework.
//
// We have to get a little tricky here: CStatusBar::OnUpdateCmdUI
// expects a CFrameWnd pointer as its first parameter. However, it
// doesn't do anything but pass the parameter on to another function
// which only requires a CCmdTarget pointer. We can get a CWnd pointer
// to the parent window, which is a CCmdTarget, but may not be a
// CFrameWnd. So, to make CStatusBar::OnUpdateCmdUI happy, we will call
// our CWnd pointer a CFrameWnd pointer temporarily.
LRESULT CDlgStatusBar::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM)
{
if (IsWindowVisible())
{
CFrameWnd *pParent = (CFrameWnd *)GetParent();
if (pParent)
OnUpdateCmdUI(pParent, (BOOL)wParam);
}
return 0L;
}

73
Editor/Controls/DLGBARS.H Normal file
View File

@@ -0,0 +1,73 @@
/*****************************************************************************
DLGBARS.H
Purpose:
Interface for CDlgToolBar, a special type of CToolBar which does not
expect a parent frame window to be available, and CDlgStatusBar, which
does the same for CStatusBars. This allows the control bars
to be used in applications where the main window is a dialog bar.
Functions:
CDlgToolBar::CDlgToolBar() -- constructor
CDlgToolBar::~CDlgToolBar() -- destructor
CDlgToolBar::OnIdleUpdateCmdUI() -- WM_IDLEUPDATECMDUI handler
CDlgStatusBar::CDlgStatusBar() -- constructor
CDlgStatusBar::~CDlgStatusBar() -- destructor
CDlgStatusBar::OnIdleUpdateCmdUI() -- WM_IDLEUPDATECMDUI handler
Development Team:
Mary Kirtland
Ported to 32-bit by:
Mike Hedley
Written by Microsoft Product Support Services, Premier ISV Support
Copyright (c) 1996 Microsoft Corporation. All rights reserved.
\****************************************************************************/
#ifndef __DLGBARS_H__
#define __DLGBARS_H__
class CDlgToolBar : public CToolBar
{
// Construction
public:
CDlgToolBar();
// Implementation
public:
virtual ~CDlgToolBar();
BOOL LoadToolBar24( UINT nIDResource,int nBtnWidth=16 );
protected:
// Generated message map functions
//{{AFX_MSG(CDlgToolBar)
afx_msg LRESULT OnIdleUpdateCmdUI(WPARAM wParam, LPARAM);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
class CDlgStatusBar : public CStatusBar
{
// Construction
public:
CDlgStatusBar();
// Implementation
public:
virtual ~CDlgStatusBar();
protected:
// Generated message map functions
//{{AFX_MSG(CDlgStatusBar)
afx_msg LRESULT OnIdleUpdateCmdUI(WPARAM wParam, LPARAM);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif //__DLGBARS_H__

View File

@@ -0,0 +1,244 @@
/////////////////////////////////////////////////////////////////////////////
// DropListBox.cpp : implementation file
//
// CAdvComboBox Control
// Version: 2.1
// Date: September 2002
// Author: Mathias Tunared
// Email: Mathias@inorbit.com
// Copyright (c) 2002. All Rights Reserved.
//
// This code, in compiled form or as source code, may be redistributed
// unmodified PROVIDING it is not sold for profit without the authors
// written consent, and providing that this notice and the authors name
// and all copyright notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DropListBox.h"
#include "Resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDropListBox
CDropListBox::CDropListBox()
{
m_nLastTopIdx = 0;
}
CDropListBox::~CDropListBox()
{
}
BEGIN_MESSAGE_MAP(CDropListBox, CListBox)
//{{AFX_MSG_MAP(CDropListBox)
ON_WM_CREATE()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
//}}AFX_MSG_MAP
ON_MESSAGE( WM_VRC_SETCAPTURE, OnSetCapture )
ON_MESSAGE( WM_VRC_RELEASECAPTURE, OnReleaseCapture )
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDropListBox message handlers
int CDropListBox::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListBox::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
//
// Because this window doesn't have an owner, there will appear
// a 'blank' button on the taskbar. The following are to hide
// that 'blank' button on the taskbar
ShowWindow( SW_HIDE );
ModifyStyleEx( 0, WS_EX_TOOLWINDOW );// |WS_VSCROLL );//| WS_EX_NOACTIVATE ); // WS_EX_CONTROLPARENT
ShowWindow( SW_SHOW );
SetWindowPos( &wndTopMost, lpCreateStruct->x, lpCreateStruct->y, lpCreateStruct->cx, lpCreateStruct->cy, SWP_SHOWWINDOW );
SetFont( GetOwner()->GetFont() );
return 0;
}
LRESULT CDropListBox::OnSetCapture( WPARAM wParam, LPARAM lParam )
{
SetCapture();
return FALSE;
}
LRESULT CDropListBox::OnReleaseCapture( WPARAM wParam, LPARAM lParam )
{
ReleaseCapture();
return FALSE;
}
void CDropListBox::OnMouseMove(UINT nFlags, CPoint point)
{
//
// Is mouse within listbox
CRect rcClient;
GetClientRect( rcClient );
if( !rcClient.PtInRect( point ) )
{
ReleaseCapture();
GetParent()->SendMessage( WM_VRC_SETCAPTURE );
}
//
// Set selection item under mouse
int nPos = point.y / GetItemHeight(0) + GetTopIndex();
if (GetCurSel() != nPos)
{
SetCurSel( nPos );
}
//
// Check if we have autoscrolled
if( m_nLastTopIdx != GetTopIndex() )
{
int nDiff = m_nLastTopIdx - GetTopIndex();
m_nLastTopIdx = GetTopIndex();
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
if( m_pScroll->GetScrollInfo( &info, SIF_ALL|SIF_DISABLENOSCROLL ) )
{
info.nPos = m_nLastTopIdx;
m_pScroll->SetScrollInfo( &info );
}
}
// OutputDebugString( "DropListBox MouseMove\n" );
CListBox::OnMouseMove(nFlags, point);
}
void CDropListBox::OnLButtonUp(UINT nFlags, CPoint point)
{
//
// Is mouse within listbox
CRect rcClient;
GetClientRect( rcClient );
if( !rcClient.PtInRect( point ) )
{
ReleaseCapture();
GetParent()->SendMessage( WM_VRC_SETCAPTURE );
}
int nPos = GetCurSel();
//
// Send current selection to comboedit
if( nPos != -1 )
GetOwner()->PostMessage( WM_SELECTED_ITEM, (WPARAM)nPos, 0 );
// CString str;
// str.Format( "DropListWnd: Selected item: %d\n", nPos );
// OutputDebugString( str );
//
// Destroy dropdown
ReleaseCapture();
GetOwner()->PostMessage( WM_DESTROY_DROPLIST );
}
void CDropListBox::OnLButtonDown(UINT nFlags, CPoint point)
{
//
// Send input to parent
/* CRect rc;
GetClientRect( &rc );
CPoint pt = point;
ClientToScreen( &pt );
INPUT input;
input.type = INPUT_MOUSE;
input.mi.dx = pt.x;
input.mi.dy = pt.y;
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
input.mi.time = 0;
SendInput( 1, &input, sizeof(INPUT) );
*/
//
// Return so that the listbox can be destroyed
// CListBox::OnLButtonDown(nFlags, point);
}
int CDropListBox::GetBottomIndex()
{
int nTop = GetTopIndex();
CRect rc;
GetClientRect( &rc );
int nVisCount = rc.Height() / GetItemHeight(0);
return nTop + nVisCount;
}
void CDropListBox::SetTopIdx(int nPos, BOOL bUpdateScrollbar)
{
m_nLastTopIdx = nPos;
SetTopIndex( nPos );
if( bUpdateScrollbar )
{
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
if( m_pScroll->GetScrollInfo( &info, SIF_ALL|SIF_DISABLENOSCROLL ) )
{
info.nPos = m_nLastTopIdx;
m_pScroll->SetScrollInfo( &info );
}
}
}
void CDropListBox::GetTextSize(LPCTSTR lpszText, int nCount, CSize &size)
{
CClientDC dc(this);
int nSave = dc.SaveDC();
dc.SelectObject( GetOwner()->GetFont() );
size = dc.GetTextExtent( lpszText, nCount );
dc.RestoreDC(nSave);
}
int CDropListBox::SetCurSel(int nSelect)
{
int nr = CListBox::SetCurSel( nSelect );
if( nr != -1 )
{
//
// Set scrollbar
int nTopIdx = GetTopIndex();
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
if( m_pScroll->GetScrollInfo( &info, SIF_ALL|SIF_DISABLENOSCROLL ) )
{
info.nPos = nTopIdx;
m_pScroll->SetScrollInfo( &info );
}
}
return nr;
}

View File

@@ -0,0 +1,94 @@
/////////////////////////////////////////////////////////////////////////////
// DropListBox.h : header file
//
// CAdvComboBox Control
// Version: 2.1
// Date: September 2002
// Author: Mathias Tunared
// Email: Mathias@inorbit.com
// Copyright (c) 2002. All Rights Reserved.
//
// This code, in compiled form or as source code, may be redistributed
// unmodified PROVIDING it is not sold for profit without the authors
// written consent, and providing that this notice and the authors name
// and all copyright notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_DROPLISTBOX_H__E49DED7C_CBC2_4458_A72C_F4C428927132__INCLUDED_)
#define AFX_DROPLISTBOX_H__E49DED7C_CBC2_4458_A72C_F4C428927132__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DropListBox.h : header file
//
#include "DropScrollBar.h"
#define WM_SELECTED_ITEM (WM_USER+1)
#define WM_DESTROY_DROPLIST (WM_USER+2)
#define WM_VRC_SETCAPTURE (WM_USER+3)
#define WM_VRC_RELEASECAPTURE (WM_USER+4)
class CDropScrollBar;
/////////////////////////////////////////////////////////////////////////////
// CDropListBox window
class CDropListBox : public CListBox
{
// Construction
public:
CDropListBox();
// Attributes
public:
// Operations
public:
void SetScrollBar( CDropScrollBar* pScroll ) { m_pScroll = pScroll; }
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDropListBox)
public:
//}}AFX_VIRTUAL
// Implementation
public:
int SetCurSel( int nSelect );
void GetTextSize( LPCTSTR lpszText, int nCount, CSize& size );
void SetTopIdx( int nPos, BOOL bUpdateScrollbar = FALSE );
int GetBottomIndex();
virtual ~CDropListBox();
// Generated message map functions
protected:
//{{AFX_MSG(CDropListBox)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
//}}AFX_MSG
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg LRESULT OnSetCapture( WPARAM wParam, LPARAM lParam );
afx_msg LRESULT OnReleaseCapture( WPARAM wParam, LPARAM lParam );
DECLARE_MESSAGE_MAP()
private:
CWnd* m_pComboParent;
CDropScrollBar* m_pScroll;
int m_nLastTopIdx;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DROPLISTBOX_H__E49DED7C_CBC2_4458_A72C_F4C428927132__INCLUDED_)

View File

@@ -0,0 +1,199 @@
/////////////////////////////////////////////////////////////////////////////
// DropScrollBar.cpp : implementation file
//
// CAdvComboBox Control
// Version: 2.1
// Date: September 2002
// Author: Mathias Tunared
// Email: Mathias@inorbit.com
// Copyright (c) 2002. All Rights Reserved.
//
// This code, in compiled form or as source code, may be redistributed
// unmodified PROVIDING it is not sold for profit without the authors
// written consent, and providing that this notice and the authors name
// and all copyright notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DropScrollBar.h"
#include "DropListBox.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDropScrollBar
CDropScrollBar::CDropScrollBar()
:
m_pListBox( 0 )
{
}
CDropScrollBar::~CDropScrollBar()
{
}
BEGIN_MESSAGE_MAP(CDropScrollBar, CScrollBar)
//{{AFX_MSG_MAP(CDropScrollBar)
ON_WM_MOUSEMOVE()
ON_WM_VSCROLL_REFLECT()
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
ON_MESSAGE( WM_VRC_SETCAPTURE, OnSetCapture )
ON_MESSAGE( WM_VRC_RELEASECAPTURE, OnReleaseCapture )
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDropScrollBar message handlers
void CDropScrollBar::OnMouseMove(UINT nFlags, CPoint point)
{
//
// Is mouse within listbox
CRect rcClient;
GetClientRect( rcClient );
if( !rcClient.PtInRect( point ) )
{
ReleaseCapture();
GetParent()->SendMessage( WM_VRC_SETCAPTURE );
}
// OutputDebugString( "DropScrollBar MouseMove\n" );
CScrollBar::OnMouseMove(nFlags, point);
}
LRESULT CDropScrollBar::OnSetCapture( WPARAM wParam, LPARAM lParam )
{
SetCapture();
return FALSE;
}
LRESULT CDropScrollBar::OnReleaseCapture( WPARAM wParam, LPARAM lParam )
{
ReleaseCapture();
return FALSE;
}
void CDropScrollBar::VScroll(UINT nSBCode, UINT nPos)
{
// TODO: Add your message handler code here
if( !m_pListBox )
return;
int nTop = m_pListBox->GetTopIndex();
int nBottom = m_pListBox->GetBottomIndex();
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
if( !GetScrollInfo( &info, SIF_ALL|SIF_DISABLENOSCROLL ) )
return;
switch( nSBCode )
{
case SB_BOTTOM: // Scroll to bottom.
break;
case SB_ENDSCROLL: // End scroll.
break;
case SB_LINEDOWN: // Scroll one line down.
info.nPos++;
if( info.nPos > info.nMax )
info.nPos = info.nMax;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_LINEUP: // Scroll one line up.
info.nPos--;
if( info.nPos < info.nMin )
info.nPos = info.nMin;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_PAGEDOWN: // Scroll one page down.
info.nPos += info.nPage;
if( info.nPos > info.nMax )
info.nPos = info.nMax;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_PAGEUP: // Scroll one page up.
info.nPos -= info.nPage;
if( info.nPos < info.nMin )
info.nPos = info.nMin;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_THUMBPOSITION: // Scroll to the absolute position. The current position is provided in nPos.
info.nPos = nPos;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_THUMBTRACK: // Drag scroll box to specified position. The current position is provided in nPos.
info.nPos = nPos;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_TOP: // Scroll to top.
break;
}
SetScrollInfo( &info );
}
void CDropScrollBar::SetListBox( CDropListBox* pListBox )
{
ASSERT( pListBox != NULL );
m_pListBox = pListBox;
int nTop = m_pListBox->GetTopIndex();
int nBottom = m_pListBox->GetBottomIndex();
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
info.fMask = SIF_ALL | SIF_DISABLENOSCROLL;
info.nMax = m_pListBox->GetCount()-1;
info.nMin = 0;
info.nPage = nBottom - nTop;
info.nPos = 0;
info.nTrackPos = 0;
SetScrollInfo( &info );
}
void CDropScrollBar::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rc;
GetClientRect( &rc );
if( !rc.PtInRect( point ) )
{
ReleaseCapture();
GetParent()->SendMessage( WM_VRC_SETCAPTURE );
}
CScrollBar::OnLButtonDown(nFlags, point);
}

View File

@@ -0,0 +1,77 @@
/////////////////////////////////////////////////////////////////////////////
// DropScrollBar.h : header file
//
// CAdvComboBox Control
// Version: 2.1
// Date: September 2002
// Author: Mathias Tunared
// Email: Mathias@inorbit.com
// Copyright (c) 2002. All Rights Reserved.
//
// This code, in compiled form or as source code, may be redistributed
// unmodified PROVIDING it is not sold for profit without the authors
// written consent, and providing that this notice and the authors name
// and all copyright notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_DROPSCROLLBAR_H__8814CD20_3D94_4B9C_8A64_DF4E9F6DD4DC__INCLUDED_)
#define AFX_DROPSCROLLBAR_H__8814CD20_3D94_4B9C_8A64_DF4E9F6DD4DC__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CDropListBox;
/////////////////////////////////////////////////////////////////////////////
// CDropScrollBar window
class CDropScrollBar : public CScrollBar
{
// Construction
public:
CDropScrollBar();
// Attributes
public:
// Operations
public:
void SetListBox( CDropListBox* pListBox );
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDropScrollBar)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CDropScrollBar();
// Generated message map functions
protected:
//{{AFX_MSG(CDropScrollBar)
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void VScroll(UINT nSBCode, UINT nPos);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG
afx_msg LRESULT OnSetCapture( WPARAM wParam, LPARAM lParam );
afx_msg LRESULT OnReleaseCapture( WPARAM wParam, LPARAM lParam );
DECLARE_MESSAGE_MAP()
private:
CDropListBox* m_pListBox;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DROPSCROLLBAR_H__8814CD20_3D94_4B9C_8A64_DF4E9F6DD4DC__INCLUDED_)

471
Editor/Controls/DropWnd.cpp Normal file
View File

@@ -0,0 +1,471 @@
/////////////////////////////////////////////////////////////////////////////
// DropWnd.cpp : implementation file
//
// CAdvComboBox Control
// Version: 2.1
// Date: September 2002
// Author: Mathias Tunared
// Email: Mathias@inorbit.com
// Copyright (c) 2002. All Rights Reserved.
//
// This code, in compiled form or as source code, may be redistributed
// unmodified PROVIDING it is not sold for profit without the authors
// written consent, and providing that this notice and the authors name
// and all copyright notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DropWnd.h"
#include "DropListBox.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDropWnd
CDropWnd::CDropWnd()
{
m_bResizing = false;
}
CDropWnd::~CDropWnd()
{
}
BEGIN_MESSAGE_MAP(CDropWnd, CWnd)
//{{AFX_MSG_MAP(CDropWnd)
ON_WM_CREATE()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_SIZE()
ON_WM_PAINT()
ON_WM_LBUTTONUP()
ON_WM_SHOWWINDOW()
ON_WM_ACTIVATEAPP()
//}}AFX_MSG_MAP
ON_MESSAGE( WM_VRC_SETCAPTURE, OnSetCapture )
ON_MESSAGE( WM_VRC_RELEASECAPTURE, OnReleaseCapture )
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDropWnd message handlers
BOOL CDropWnd::PreCreateWindow(CREATESTRUCT& cs)
{
//
// Calc the size of the wnd
return CWnd::PreCreateWindow(cs);
}
//////////////////////////////////////////////////////////////////////////
int CDropWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
CRect rcWnd;
GetClientRect( &rcWnd );
//
// Because this window doesn't have an owner, there will appear
// a 'blank' button on the taskbar. The following are to hide
// that 'blank' button on the taskbar
ModifyStyleEx( 0, WS_EX_TOOLWINDOW|WS_EX_TOPMOST );
MoveWindow( lpCreateStruct->x, lpCreateStruct->y, lpCreateStruct->cx, lpCreateStruct->cy, FALSE );
//SetWindowPos( &wndTopMost, lpCreateStruct->x, lpCreateStruct->y, lpCreateStruct->cx, lpCreateStruct->cy, SWP_SHOWWINDOW );
//
// Create scrollbar
m_rcScroll = rcWnd;
m_rcScroll.left = m_rcScroll.right - ::GetSystemMetrics(SM_CXVSCROLL);
m_rcScroll.bottom -= ::GetSystemMetrics(SM_CYVSCROLL);
m_scrollbar.Create( SBS_VERT | SBS_RIGHTALIGN | WS_CHILD, m_rcScroll, this, 100);
//
// Create listbox
m_rcList.SetRect( lpCreateStruct->x, lpCreateStruct->y, lpCreateStruct->x+lpCreateStruct->cx-::GetSystemMetrics(SM_CXVSCROLL), lpCreateStruct->y+lpCreateStruct->cy );
ScreenToClient( m_rcList );
VERIFY(m_listbox.Create( WS_VISIBLE|WS_CHILD|LBS_NOINTEGRALHEIGHT|LBS_HASSTRINGS, m_rcList, this, 101 ) );
m_listbox.SetScrollBar( &m_scrollbar );
//
// Resize this wnd so INTEGRAL_HEIGHT applies!?
CRect rc;
int nH = m_listbox.GetItemHeight(0);
nH = nH*m_listbox.GetCount()+2;
// Get screen size
int nScrX = GetSystemMetrics( SM_CXSCREEN );
int nScrY = GetSystemMetrics( SM_CYSCREEN );
//int nDefaultItems = static_cast<CAdvComboBox*>(GetParent())->GetDefaultVisibleItems();
int nDefaultItems = 10;
int minVisibleItems = 2;
//
// Check to see if the window should be placed over the combobox
int nY = lpCreateStruct->y;
int nItems = m_listbox.GetCount();
int nItemHeight = m_listbox.GetItemHeight(0);
int nVisHeight = nScrY - lpCreateStruct->y;
if ((nVisHeight / nItemHeight) < minVisibleItems)
{
CRect rcCombo(0,0,100,10);
int nComboTopY = lpCreateStruct->y - rcCombo.Height();
if( nDefaultItems == -1 || nDefaultItems > nItems )
{
nY = (nComboTopY - nH) < 0 ? 0 : (nComboTopY - nH);
nH = (nY + nH) > nComboTopY ? nComboTopY - nY : nH;
}
else
{
nY = nComboTopY - nItemHeight*nDefaultItems;
nY -= 2;
nY = nY < 0 ? 0 : nY;
nH = nComboTopY - nY;
}
}
else
{
//
// Place the window below the combo
// Check height
if( nDefaultItems == -1 || nDefaultItems > nItems )
{
if( lpCreateStruct->y + nH > nScrY )
{
nH = nScrY - lpCreateStruct->y;
}
else
if( nH < ::GetSystemMetrics(SM_CYVSCROLL) )
{
nH = ::GetSystemMetrics(SM_CYVSCROLL);
}
}
else
{
nH = nDefaultItems * nItemHeight;
nH = (nY+nH) > nScrY ? nScrY-nY : nH;
nH += 2;
}
}
// Calc width
int nW = 0;
CSize size(0,0);
for( int i = 0; i < m_listbox.GetCount(); i++)
{
CString strText;
m_listbox.GetText(i,strText);
m_listbox.GetTextSize( strText,strText.GetLength(), size );
nW = (size.cx > nW) ? size.cx : nW;
}
nW += m_rcScroll.Width() +8;
// Check min width
if( nW < m_rcList.Width() )
{
nW = lpCreateStruct->cx;
}
// Check max width
int nX = lpCreateStruct->x;
if( nW > nScrX - lpCreateStruct->x )
{
nX = nScrX - nW;
if( nX < 0 )
nX = 0;
}
if( nX == 0 && nW > nScrX )
nW = nScrX;
MoveWindow( nX, nY, nW, nH,FALSE );
GetClientRect( &rcWnd );
//
// Create sizehandle
m_rcSizeHandle = rcWnd;
GetClientRect( &m_rcSizeHandle );
m_rcSizeHandle.left = m_rcSizeHandle.right - ::GetSystemMetrics(SM_CXVSCROLL);
m_rcSizeHandle.top = m_rcSizeHandle.bottom - ::GetSystemMetrics(SM_CYVSCROLL);
//
// Set values in scrollbar
m_scrollbar.SetListBox( &m_listbox );
m_scrollbar.ShowScrollBar();
// SendMessage( WM_SHOWWINDOW, (WPARAM)1, 0 );
return 0;
}
LRESULT CDropWnd::OnSetCapture( WPARAM wParam, LPARAM lParam )
{
SetCapture();
return FALSE;
}
LRESULT CDropWnd::OnReleaseCapture( WPARAM wParam, LPARAM lParam )
{
ReleaseCapture();
return FALSE;
}
void CDropWnd::OnMouseMove(UINT nFlags, CPoint point)
{
//
//
if( m_bResizing )
{
CRect rcWnd;
GetWindowRect( &rcWnd );
if( point.x + m_nMouseDiffX >= ::GetSystemMetrics(SM_CXVSCROLL) )
{
rcWnd.right = rcWnd.left + point.x + m_nMouseDiffX +2;
}
else
{
rcWnd.right = rcWnd.left + ::GetSystemMetrics(SM_CXVSCROLL) +1;
}
if( point.y + m_nMouseDiffY >= ::GetSystemMetrics(SM_CYVSCROLL) )
{
rcWnd.bottom = rcWnd.top + point.y + m_nMouseDiffY +2;
}
else
{
rcWnd.bottom = rcWnd.top + ::GetSystemMetrics(SM_CXVSCROLL) +1;
}
MoveWindow( &rcWnd );
return;
}
//
// Check point
if( m_rcList.PtInRect( point ) )
{
HCURSOR hCursor = LoadCursor( NULL, IDC_ARROW );
SetCursor( hCursor );
ReleaseCapture();
m_scrollbar.SendMessage( WM_VRC_RELEASECAPTURE );
m_listbox.SetFocus();
m_listbox.SendMessage( WM_VRC_SETCAPTURE );
}
else
if( m_rcScroll.PtInRect( point ) )
{
HCURSOR hCursor = LoadCursor( NULL, IDC_ARROW );
SetCursor( hCursor );
m_scrollbar.SetFocus();
ReleaseCapture();
m_listbox.SendMessage( WM_VRC_RELEASECAPTURE );
m_scrollbar.SendMessage( WM_VRC_SETCAPTURE );
}
else
{
if( m_rcSizeHandle.PtInRect( point ) )
{
HCURSOR hCursor = LoadCursor( NULL, IDC_SIZENWSE );
SetCursor( hCursor );
}
else
{
HCURSOR hCursor = LoadCursor( NULL, IDC_ARROW );
SetCursor( hCursor );
}
SetCapture();
CWnd::OnMouseMove(nFlags, point);
}
}
void CDropWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
if( m_rcSizeHandle.PtInRect( point ) )
{
m_bResizing = true;
m_ptLastResize = point;
CRect rcClient;
GetClientRect( &rcClient );
m_nMouseDiffX = rcClient.Width() - point.x;
m_nMouseDiffY = rcClient.Height() - point.y;
return;
}
//
// Clean up the code below...
//
CRect rc;
CRect rcVScroll(0,0,0,0);
GetClientRect( &rc );
DWORD dwStyle = GetStyle();
// Take away vertical scroll
if( rc.PtInRect( point ) )
{
}
else
{
//
// Calc the point in the parent(PropertyListBox)
CWnd* pParent = GetOwner()->GetParent();
CRect rcParentClient;
CRect rcParentWnd;
pParent->GetClientRect( &rcParentClient );
pParent->GetWindowRect( &rcParentWnd );
CPoint pt = point;
ClientToScreen( &pt );
pt.x -= rcParentWnd.left;
pt.y -= rcParentWnd.top;
CRect rc;
GetOwner()->GetWindowRect( &rc );
if( !rc.PtInRect( pt ) )
{
ReleaseCapture();
// CString str;
// str.Format( "MousePos (NOT PtInRect): X:%d, y:%d\n", pt.x, pt.y );
// OutputDebugString( str );
GetOwner()->PostMessage( WM_DESTROY_DROPLIST );
}
else
{
// CString str;
// str.Format( "MousePos in combo\n " );
// OutputDebugString( str );
ReleaseCapture();
GetOwner()->PostMessage( WM_DESTROY_DROPLIST );
}
//
// Send input to parent
/* INPUT input;
input.type = INPUT_MOUSE;
input.mi.dx = pt.x;
input.mi.dy = pt.y;
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
input.mi.time = 0;
SendInput( 1, &input, sizeof(INPUT) );
*/
}
CWnd::OnLButtonDown(nFlags, point);
}
void CDropWnd::OnLButtonUp(UINT nFlags, CPoint point)
{
if( m_bResizing )
{
m_bResizing = false;
}
CWnd::OnLButtonUp(nFlags, point);
}
void CDropWnd::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
m_rcList.SetRect( 0, 0, cx-::GetSystemMetrics(SM_CXVSCROLL), cy );
m_listbox.MoveWindow( &m_rcList,FALSE );
m_rcScroll.SetRect( cx-::GetSystemMetrics(SM_CXVSCROLL), 0, cx, cy-::GetSystemMetrics(SM_CYVSCROLL) );
m_scrollbar.MoveWindow( &m_rcScroll,FALSE );
m_rcSizeHandle.SetRect( cx-::GetSystemMetrics(SM_CXVSCROLL), cy-::GetSystemMetrics(SM_CYVSCROLL), cx, cy );
InvalidateRect( &m_rcSizeHandle );
//
// Fix the scrollbar
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
if( m_scrollbar.GetScrollInfo( &info, SIF_ALL|SIF_DISABLENOSCROLL ) )
{
info.nPage = m_listbox.GetBottomIndex() - m_listbox.GetTopIndex();
m_scrollbar.SetScrollInfo( &info );
}
}
void CDropWnd::OnPaint()
{
CPaintDC dc(this); // device context for painting
dc.DrawFrameControl(m_rcSizeHandle, DFC_SCROLL, DFCS_SCROLLSIZEGRIP );
// Do not call CWnd::OnPaint() for painting messages
}
BOOL CDropWnd::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
ReleaseCapture();
m_listbox.DestroyWindow();
return CWnd::DestroyWindow();
}
void CDropWnd::OnShowWindow(BOOL bShow, UINT nStatus)
{
CWnd::OnShowWindow(bShow, nStatus);
// TODO: Add your message handler code here
if( bShow )
{
// AnimateWindow( GetSafeHwnd(), 80, AW_VER_POSITIVE | AW_ACTIVATE | AW_SLIDE);
}
else
{
// AnimateWindow( GetSafeHwnd(), 80, AW_VER_NEGATIVE | AW_HIDE | AW_SLIDE);
}
}
#if _MFC_VER >= 0x0700 //MFC 7.0
void CDropWnd::OnActivateApp(BOOL bActive, DWORD dwThreadID )
{
CWnd::OnActivateApp(bActive, dwThreadID);
#else // MFC7.0
void CDropWnd::OnActivateApp(BOOL bActive, HTASK hTask ) // MFC6 -
{
CWnd::OnActivateApp(bActive, hTask);
#endif // MFC7.0
// TODO: Add your message handler code here
if( bActive )
{
}
else
{
GetOwner()->PostMessage( WM_DESTROY_DROPLIST );
}
}
BOOL CDropWnd::OnEraseBkgnd(CDC* pDC)
{
// Not erase background.
return TRUE;
}

104
Editor/Controls/DropWnd.h Normal file
View File

@@ -0,0 +1,104 @@
/////////////////////////////////////////////////////////////////////////////
// DropWnd.h : header file
//
// CAdvComboBox Control
// Version: 2.1
// Date: September 2002
// Author: Mathias Tunared
// Email: Mathias@inorbit.com
// Copyright (c) 2002. All Rights Reserved.
//
// This code, in compiled form or as source code, may be redistributed
// unmodified PROVIDING it is not sold for profit without the authors
// written consent, and providing that this notice and the authors name
// and all copyright notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_DROPWND_H__F873AF0A_BD7D_4B20_BDF6_1EBB973AA348__INCLUDED_)
#define AFX_DROPWND_H__F873AF0A_BD7D_4B20_BDF6_1EBB973AA348__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DropWnd.h : header file
//
#include "DropListBox.h"
#include "DropScrollBar.h"
/////////////////////////////////////////////////////////////////////////////
// CDropWnd window
class CDropWnd : public CWnd
{
// Construction
public:
CDropWnd();
// Attributes
public:
const CDropListBox& GetListBox() const { return m_listbox; }
CDropListBox& GetListBox() { return m_listbox; }
const CDropScrollBar& GetScrollBar() const { return m_scrollbar; }
CDropScrollBar& GetScrollBar() { return m_scrollbar; }
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDropWnd)
public:
virtual BOOL DestroyWindow();
protected:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CDropWnd();
// Generated message map functions
protected:
//{{AFX_MSG(CDropWnd)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnPaint();
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
#if _MFC_VER >= 0x0700 //MFC 7.0
afx_msg void OnActivateApp(BOOL bActive, DWORD dwThreadID);
#else
afx_msg void OnActivateApp(BOOL bActive, HTASK hTask );
#endif
//}}AFX_MSG
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg LRESULT OnSetCapture( WPARAM wParam, LPARAM lParam );
afx_msg LRESULT OnReleaseCapture( WPARAM wParam, LPARAM lParam );
DECLARE_MESSAGE_MAP()
private:
CDropListBox m_listbox;
CDropScrollBar m_scrollbar;
CRect m_rcList;
CRect m_rcScroll;
CRect m_rcSizeHandle;
bool m_bResizing;
CPoint m_ptLastResize;
int m_nMouseDiffX;
int m_nMouseDiffY;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DROPWND_H__F873AF0A_BD7D_4B20_BDF6_1EBB973AA348__INCLUDED_)

View File

@@ -0,0 +1,528 @@
// EditModeToolBar.cpp : implementation file
//
#include "stdafx.h"
#include "EditModeToolBar.h"
#include "Objects\ObjectManager.h"
#include "UndoDropDown.h"
#include "ViewManager.h"
#include "GridSettingsDialog.h"
#include "Settings.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CEditModeToolBar
CEditModeToolBar::CEditModeToolBar()
{
//{{AFX_DATA_INIT(CEditModeToolBar)
m_szSelection = "";
//}}AFX_DATA_INIT
m_coordSys = (RefCoordSys)-1;
m_objectSelectionMask = 0;
}
CEditModeToolBar::~CEditModeToolBar()
{
}
BEGIN_MESSAGE_MAP(CEditModeToolBar, CXTToolBar)
//{{AFX_MSG_MAP(CEditModeToolBar)
ON_WM_CREATE()
ON_CBN_SELENDOK( IDC_SELECTION,OnSelectionChanged )
ON_CBN_SELCHANGE( IDC_SELECTION,OnSelectionChanged )
ON_NOTIFY( CBEN_ENDEDIT, IDC_SELECTION, OnNotifyOnSelectionChanged)
ON_NOTIFY_REFLECT( TBN_DROPDOWN, OnToolbarDropDown )
ON_UPDATE_COMMAND_UI(ID_REF_COORDS_SYS, OnUpdateCoordsRefSys)
ON_CBN_SELENDOK( ID_REF_COORDS_SYS,OnCoordsRefSys )
ON_UPDATE_COMMAND_UI(IDC_SELECTION_MASK, OnUpdateSelectionMask)
ON_CBN_SELENDOK( IDC_SELECTION_MASK,OnSelectionMask )
ON_WM_RBUTTONUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CEditModeToolBar::DoDataExchange(CDataExchange* pDX)
{
CXTToolBar::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CEditModeToolBar)
DDX_CBString(pDX, IDC_SELECTION, m_szSelection);
//}}AFX_DATA_MAP
}
/////////////////////////////////////////////////////////////////////////////
// CEditModeToolBar message handlers
BOOL CEditModeToolBar::Create( CWnd *pParentWnd,DWORD dwStyle,UINT nID )
{
if (!CXTToolBar::CreateEx( pParentWnd,TBSTYLE_FLAT|TBSTYLE_TRANSPARENT|TBSTYLE_LIST,dwStyle,CRect(0,0,0,0),nID ))
return FALSE;
LoadToolBar( IDR_EDIT_MODE );
/*
// Set up hot bar image lists.
CImageList toolbarImageList;
CBitmap toolbarBitmap;
toolbarBitmap.LoadBitmap(IDR_EDIT_MODE);
toolbarImageList.Create(16, 15, ILC_COLORDDB|ILC_MASK, 13, 1);
toolbarImageList.Add(&toolbarBitmap,TOOLBAR_TRANSPARENT_COLOR);
GetToolBarCtrl().SetImageList( &toolbarImageList );
toolbarImageList.Detach();
toolbarBitmap.Detach();
*/
GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS|TBSTYLE_EX_MIXEDBUTTONS);
//GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);
// Replace buttons to check boxes.
for (int i = 0; i < GetCount(); i++)
{
int style = GetButtonStyle(i);
if (style & TBBS_SEPARATOR)
continue;
int id = GetItemID(i);
if (/*(id == ID_EDITMOD_LINK)||(id == ID_EDITMODE_UNLINK)||*/(id == ID_EDITMODE_SELECT)||(id == ID_EDITMODE_MOVE)||(id == ID_EDITMODE_ROTATE)||(id == ID_EDITMODE_SCALE))
{
if (style == TBBS_BUTTON)
{
style = TBBS_CHECKGROUP;
SetButtonStyle(i,style);
}
}
}
int iIndex;
// Layer select button.
SetButtonStyle( CommandToIndex(ID_LAYER_SELECT),BTNS_BUTTON|BTNS_SHOWTEXT );
//SetButtonText( CommandToIndex(ID_LAYER_SELECT)," " );
// Snap.
iIndex = CommandToIndex(ID_SNAP_TO_GRID);
SetButtonStyle( iIndex,GetButtonStyle(iIndex)|TBSTYLE_DROPDOWN|BTNS_SHOWTEXT );
SetButtonText( iIndex," " );
// Terrain Axis.
//iIndex = CommandToIndex(ID_SELECT_AXIS_TERRAIN);
//SetButtonStyle( iIndex,GetButtonStyle(iIndex)|TBSTYLE_DROPDOWN );
// Place drop down buttons for Undo and Redo.
iIndex = CommandToIndex(ID_UNDO);
SetButtonStyle( iIndex,GetButtonStyle(iIndex)|TBSTYLE_DROPDOWN );
iIndex = CommandToIndex(ID_REDO);
SetButtonStyle( iIndex,GetButtonStyle(iIndex)|TBSTYLE_DROPDOWN );
// Create controls in the animation bar
CRect rect;
// Get the index of the keyframe slider position in the toolbar
iIndex = CommandToIndex(IDC_SELECTION);
/*
if (iIndex >= 0)
{
// Convert that button to a seperator and get its position
SetButtonInfo(iIndex, IDC_SELECTION, TBBS_SEPARATOR, 100);
GetItemRect(iIndex, &rect);
}
*/
CalcLayout(LM_HORZ);
rect.SetRect( 2,0,100,150 );
m_selections.Create(WS_CHILD|WS_VISIBLE|CBS_DROPDOWN|CBS_SORT,rect,this,IDC_SELECTION);
InsertControl( &m_selections );
//SetButtonCtrl( iIndex,&m_selections,FALSE );
m_selections.SetItemHeight( -1, 16 );
//m_selections.SetFont( &g_PaintManager->m_FontNormal );
rect.SetRect( 2,0,60,150 );
m_refCoords.Create(WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST,rect,this,ID_REF_COORDS_SYS);
m_refCoords.AddString("View");
m_refCoords.AddString("Local");
m_refCoords.AddString("World");
InsertControl( &m_refCoords );
//SetButtonCtrl( iIndex,&m_selections,FALSE );
//m_refCoords.SetItemHeight( -1, 16 );
//////////////////////////////////////////////////////////////////////////
// Initialize selection mask.
//////////////////////////////////////////////////////////////////////////
int id;
rect.SetRect( 2,0,80,300 );
m_selectionMask.Create(WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST,rect,this,IDC_SELECTION_MASK);
//////////////////////////////////////////////////////////////////////////
id = m_selectionMask.AddString("Select All");
m_selectionMask.SetItemData( id,OBJTYPE_ANY );
//////////////////////////////////////////////////////////////////////////
id = m_selectionMask.AddString("No Brushes");
m_selectionMask.SetItemData( id,(~OBJTYPE_BRUSH) );
//////////////////////////////////////////////////////////////////////////
id = m_selectionMask.AddString("Brushes");
m_selectionMask.SetItemData( id,OBJTYPE_BRUSH );
//////////////////////////////////////////////////////////////////////////
id = m_selectionMask.AddString("Entities");
m_selectionMask.SetItemData( id,OBJTYPE_ENTITY );
//////////////////////////////////////////////////////////////////////////
id = m_selectionMask.AddString("Prefabs");
m_selectionMask.SetItemData( id,OBJTYPE_PREFAB );
//////////////////////////////////////////////////////////////////////////
id = m_selectionMask.AddString("Areas");
m_selectionMask.SetItemData( id,OBJTYPE_VOLUME );
//////////////////////////////////////////////////////////////////////////
id = m_selectionMask.AddString("AI Points");
m_selectionMask.SetItemData( id,OBJTYPE_AIPOINT );
InsertControl( &m_selectionMask );
//////////////////////////////////////////////////////////////////////////
/*
{
CMenu menu;
menu.CreatePopupMenu();
int size = 1;
for (int i = 0; i < 7; i++)
{
CString str;
str.Format( "%d",size );
menu.AppendMenu( MF_STRING,1+i,str );
size *= 2;
}
menu.AppendMenu( MF_SEPARATOR );
menu.AppendMenu( MF_STRING,100,"Setup grid" );
SetButtonMenu( CommandToIndex(ID_SNAP_TO_GRID),menu.Detach(),FALSE );
}
*/
CalcLayout(LM_HORZ);
GetToolBarCtrl().AutoSize();
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::SetGridSize( float size )
{
// Snap.
int iIndex = CommandToIndex(ID_SNAP_TO_GRID);
CString str;
str.Format( "%g",size );
SetButtonText( iIndex,str );
AutoSize();
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::SetCurrentLayer( const CString &layerName )
{
int iIndex = CommandToIndex(ID_LAYER_SELECT);
if (iIndex >= 0)
{
SetButtonText( iIndex,CString(" ")+layerName );
//m_layerName.SetWindowText( layerName );
}
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnSelectionChanged()
{
CString selection = GetSelection();
if (!selection.IsEmpty())
GetIEditor()->GetObjectManager()->SetSelection( selection );
}
void CEditModeToolBar::OnNotifyOnSelectionChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NMCBEENDEDIT *endEdit = (NMCBEENDEDIT*)pNMHDR;
if (endEdit->iWhy == CBENF_RETURN || endEdit->iWhy == CBENF_KILLFOCUS)
{
// Add new selection.
CString selection = endEdit->szText;
if (!selection.IsEmpty())
{
AddSelection( selection );
GetIEditor()->GetObjectManager()->NameSelection( selection );
}
}
}
CString CEditModeToolBar::GetSelection()
{
UpdateData( TRUE );
if (m_selections.m_hWnd)
{
int sel = m_selections.GetCurSel();
if (sel != CB_ERR)
{
m_selections.GetLBText( sel,m_szSelection );
}
}
return m_szSelection;
}
void CEditModeToolBar::AddSelection( const CString &name )
{
if (m_selections.FindStringExact( 0,name ) == CB_ERR)
{
//char str[1024];
//strcpy( str,name );
//m_selections.AddString( name );
//COMBOBOXEXITEM item;
//memset(&item,0,sizeof(item));
//item.mask = CBEIF_TEXT;
//item.pszText = str;
//item.cchTextMax = name.GetLength();
m_selections.AddString( name );
}
}
void CEditModeToolBar::RemoveSelection( const CString &name )
{
int i = m_selections.FindStringExact( 0,name );
if (i != CB_ERR)
m_selections.DeleteString( i );
}
void CEditModeToolBar::SetSelection( const CString &name )
{
m_szSelection = name;
UpdateData( FALSE );
}
void CEditModeToolBar::OnRButtonUp(UINT nFlags, CPoint point)
{
/*
CRect rc;
for (int i = 0; i < GetCount(); i++)
{
GetItemRect(i,rc);
if (rc.PtInRect(point))
{
int id = GetButtonID(i);
if ((id == ID_EDITMODE_MOVE)||(id == ID_EDITMODE_ROTATE)||(id == ID_EDITMODE_SCALE))
{
if (GetToolBarCtrl().IsButtonChecked(id))
{
CLogFile::WriteLine( "Clicked" );
}
}
}
}
*/
CXTToolBar::OnRButtonUp(nFlags, point);
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnToolbarDropDown(NMHDR* pnhdr, LRESULT *plr)
{
CRect rc;
CPoint pos;
GetCursorPos( &pos );
NMTOOLBAR* pnmtb = (NMTOOLBAR*)pnhdr;
//GetItemRect( pnmtb->iItem,rc );
rc = pnmtb->rcButton;
ClientToScreen( rc );
pos.x = rc.left;
pos.y = rc.bottom;
// Switch on button command id's.
switch (pnmtb->iItem)
{
case ID_UNDO:
{
CUndoDropDown undoDialog( pos,true,AfxGetMainWnd() );
undoDialog.DoModal();
}
break;
case ID_REDO:
{
CUndoDropDown undoDialog( pos,false,AfxGetMainWnd() );
undoDialog.DoModal();
}
break;
case ID_SELECT_AXIS_TERRAIN:
//OnAxisTerrainMenu(pos);
break;
case ID_SNAP_TO_GRID:
{
// Display drop down menu with snap values.
OnSnapMenu(pos);
}
break;
default:
return;
}
*plr = TBDDRET_DEFAULT;
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnAxisTerrainMenu( CPoint pos )
{
/*
CMenu menu;
menu.CreatePopupMenu();
menu.AppendMenu( MF_STRING,1,"Terrain And Objects" );
menu.AppendMenu( MF_STRING,2,"Only Terrain" );
int cmd = menu.TrackPopupMenu( TPM_RETURNCMD|TPM_LEFTALIGN|TPM_LEFTBUTTON,pos.x,pos.y,this );
if (cmd == 1)
{
GetIEditor()->SetTerrainAxisIgnoreObjects(false);
}
if (cmd == 1)
{
GetIEditor()->SetTerrainAxisIgnoreObjects(true);
}
*/
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnSnapMenu( CPoint pos )
{
CMenu menu;
menu.CreatePopupMenu();
float startSize = 0.125;
int steps = 10;
double size = startSize;
for (int i = 0; i < steps; i++)
{
CString str;
str.Format( "%g",size );
menu.AppendMenu( MF_STRING,1+i,str );
size *= 2;
}
menu.AppendMenu( MF_SEPARATOR );
menu.AppendMenu( MF_STRING,100,"Setup grid" );
int cmd = menu.TrackPopupMenu( TPM_RETURNCMD|TPM_LEFTALIGN|TPM_LEFTBUTTON,pos.x,pos.y,this );
if (cmd >= 1 && cmd < 100)
{
size = startSize;
for (int i = 0; i < cmd-1; i++)
{
size *= 2;
}
// Set grid to size.
GetIEditor()->GetViewManager()->GetGrid()->size = size;
}
if (cmd == 100)
{
// Setup grid dialog.
CGridSettingsDialog dlg;
dlg.DoModal();
}
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnUpdateCoordsRefSys(CCmdUI *pCmdUI)
{
if (m_coordSys != GetIEditor()->GetReferenceCoordSys() && m_refCoords.m_hWnd)
{
int sel = LB_ERR;
m_coordSys = GetIEditor()->GetReferenceCoordSys();
switch (m_coordSys)
{
case COORDS_VIEW:
sel = 0;
break;
case COORDS_LOCAL:
sel = 1;
break;
case COORDS_WORLD:
sel = 2;
break;
};
if (sel != LB_ERR)
{
m_refCoords.SetCurSel(sel);
}
}
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnCoordsRefSys()
{
int sel = m_refCoords.GetCurSel();
if (sel != LB_ERR)
{
switch (sel)
{
case 0:
GetIEditor()->SetReferenceCoordSys( COORDS_VIEW );
break;
case 1:
GetIEditor()->SetReferenceCoordSys( COORDS_LOCAL );
break;
case 2:
GetIEditor()->SetReferenceCoordSys( COORDS_WORLD );
break;
};
}
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnUpdateSelectionMask(CCmdUI *pCmdUI)
{
if (m_objectSelectionMask != gSettings.objectSelectMask && m_selectionMask.m_hWnd)
{
m_objectSelectionMask = gSettings.objectSelectMask;
int sel = LB_ERR;
for (int i = 0; i < m_selectionMask.GetCount(); i++)
{
if (m_selectionMask.GetItemData(i) == gSettings.objectSelectMask)
{
sel = i;
break;
}
}
if (sel != LB_ERR && sel != m_selectionMask.GetCurSel())
{
m_selectionMask.SetCurSel(sel);
}
}
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnSelectionMask()
{
int sel = m_selectionMask.GetCurSel();
if (sel != LB_ERR)
{
gSettings.objectSelectMask = m_selectionMask.GetItemData(sel);
m_objectSelectionMask = gSettings.objectSelectMask;
}
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::NextSelectMask()
{
int sel = m_selectionMask.GetCurSel();
if (sel == LB_ERR || sel == m_selectionMask.GetCount()-1)
{
sel = 0;
}
else
sel++;
m_selectionMask.SetCurSel(sel);
OnSelectionMask();
}

View File

@@ -0,0 +1,86 @@
#if !defined(AFX_EDITMODETOOLBAR_H__1A7415BB_DA82_4A27_BA14_F06B74A05080__INCLUDED_)
#define AFX_EDITMODETOOLBAR_H__1A7415BB_DA82_4A27_BA14_F06B74A05080__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// EditModeToolBar.h : header file
//
#include "SelectionCombo.h"
/////////////////////////////////////////////////////////////////////////////
// CEditModeToolBar window
class CEditModeToolBar : public CXTToolBar
{
// Construction
public:
CEditModeToolBar();
BOOL Create( CWnd *pParentWnd,DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP,UINT nID = AFX_IDW_TOOLBAR );
// Attributes
public:
// Operations
public:
CString GetSelection();
void SetSelection( const CString &name );
void AddSelection( const CString &name );
void RemoveSelection( const CString &name );
void SetCurrentLayer( const CString &layerName );
void SetGridSize( float size );
void NextSelectMask();
// Data
//{{AFX_DATA(CEditModeToolBar)
CString m_szSelection;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CEditModeToolBar)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CEditModeToolBar();
void OnSnapMenu( CPoint pos );
void OnAxisTerrainMenu( CPoint pos );
// Generated message map functions
protected:
//{{AFX_MSG(CEditModeToolBar)
afx_msg void OnSelectionChanged();
afx_msg void OnNotifyOnSelectionChanged(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg void OnToolbarDropDown(NMHDR* pnhdr, LRESULT *plr);
afx_msg void OnUpdateCoordsRefSys(CCmdUI *pCmdUI);
afx_msg void OnCoordsRefSys();
afx_msg void OnUpdateSelectionMask(CCmdUI *pCmdUI);
afx_msg void OnSelectionMask();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
CSelectionCombo m_selections;
CXTFlatComboBox m_refCoords;
CXTFlatComboBox m_selectionMask;
//CExtComboBox m_selections;
CMenu m_gridMenu;
RefCoordSys m_coordSys;
int m_objectSelectionMask;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_EDITMODETOOLBAR_H__1A7415BB_DA82_4A27_BA14_F06B74A05080__INCLUDED_)

View File

@@ -0,0 +1,163 @@
// FileTree.cpp : implementation file
//
#include "stdafx.h"
#include "FileTree.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include <io.h>
/////////////////////////////////////////////////////////////////////////////
// CFileTree
CFileTree::CFileTree()
{
CLogFile::WriteLine("File tree control created");
m_strFileSpec = "*.cgf";
m_strSearchFolder = "Objects";
}
CFileTree::~CFileTree()
{
CLogFile::WriteLine("File tree control destoried");
}
BEGIN_MESSAGE_MAP(CFileTree, CTreeCtrl)
//{{AFX_MSG_MAP(CFileTree)
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFileTree message handlers
BOOL CFileTree::PreCreateWindow(CREATESTRUCT& cs)
{
////////////////////////////////////////////////////////////////////////
// Modify the window styles
////////////////////////////////////////////////////////////////////////
cs.style |= WS_VISIBLE | WS_CHILD | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT;
cs.dwExStyle |= WS_EX_CLIENTEDGE;
return CTreeCtrl::PreCreateWindow(cs);
}
int CFileTree::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
////////////////////////////////////////////////////////////////////////
// Fill the tree control with the correct data
////////////////////////////////////////////////////////////////////////
HTREEITEM hRoot;
char szSearchPath[_MAX_PATH];
char szRootName[_MAX_PATH + 512];
if (CTreeCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
// Create the list
//m_cImageList.Create(IDB_TREE_VIEW, 16, 1, RGB (255, 0, 255));
CMFCUtils::LoadTrueColorImageList( m_cImageList,IDB_TREE_VIEW,16,RGB(255,0,255) );
// Attach it to the control
SetImageList(&m_cImageList, TVSIL_NORMAL);
// Create name of the root
sprintf(szRootName, "Master CD %s Folder", m_strSearchFolder.GetBuffer(0));
// Add the Master CD folder to the list
hRoot = InsertItem(szRootName, 2, 2, TVI_ROOT);
// Create the folder path
sprintf(szSearchPath, "%s%s", GetIEditor()->GetMasterCDFolder(), (const char*)m_strSearchFolder );
// Fill the list
RecurseDirectory(szSearchPath, hRoot, m_strFileSpec.GetBuffer(0));
Expand(hRoot, TVE_EXPAND);
return 0;
}
void CFileTree::RecurseDirectory(char szFolder[_MAX_PATH], HTREEITEM hRoot, PSTR pszFileSpec)
{
////////////////////////////////////////////////////////////////////////
// Enumerate all files in the passed directory which match to the the
// passed pattern. Also continue with adding all subdirectories
////////////////////////////////////////////////////////////////////////
CFileEnum cTempFiles;
__finddata64_t sFile;
char szFilePath[_MAX_PATH];
HTREEITEM hNewRoot, hNewItem;
ASSERT(pszFileSpec);
// Make the path ready for appening a folder or filename
PathAddBackslash(szFolder);
// Start the enumeration of the files
if (cTempFiles.StartEnumeration(szFolder, "*.*", &sFile))
{
do
{
// Construct the full filepath of the current file
strcpy(szFilePath, szFolder);
strcat(szFilePath, sFile.name);
// Have we found a directory ?
if (sFile.attrib & _A_SUBDIR)
{
// Skip the parent directory entries
if (_stricmp(sFile.name, ".") == 0 ||
_stricmp(sFile.name, "..") == 0)
{
continue;
}
// Add it to the list and start recursion
hNewRoot = InsertItem(sFile.name, 0, 0, hRoot);
RecurseDirectory(szFilePath, hNewRoot, pszFileSpec);
continue;
}
// Check if the file name maches the pattern
if (!PathMatchSpec(sFile.name, pszFileSpec))
continue;
// Remove the extension from the name
PathRenameExtension(sFile.name, "");
// Add the file to the list
hNewItem = InsertItem(sFile.name, 1, 1, hRoot);
// Associate the handle of this item with the path
// of its file
m_cFileNames[hNewItem] = CString(szFilePath);
} while (cTempFiles.GetNextFile(&sFile));
}
}
CString CFileTree::GetSelectedFile()
{
////////////////////////////////////////////////////////////////////////
// Return the path of the currently selected file. If there is no
// currently selected file, just a NULL terminated string will be
// returned
////////////////////////////////////////////////////////////////////////
Files::iterator it = m_cFileNames.find(GetSelectedItem());
if (it != m_cFileNames.end())
return it->second;
else
return CString("");
}

View File

@@ -0,0 +1,68 @@
#if !defined(AFX_FILETREE_H__9848DF42_CD7E_4ADD_96F9_E01605C420D6__INCLUDED_)
#define AFX_FILETREE_H__9848DF42_CD7E_4ADD_96F9_E01605C420D6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// FileTree.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CFileTree window
class CFileTree : public CTreeCtrl
{
// Construction
public:
CFileTree();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CFileTree)
protected:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL
// Implementation
public:
CString GetSelectedFile();
virtual ~CFileTree();
// Sets the search pattern that decides which files should be displayed
void SetFileSpec(CString strFileSpec) { m_strFileSpec = strFileSpec; };
// Spezifies the root folder of the search, it is constructed as follows:
// X:\%MasterCD%\%SearchFolder%
void SetSearchFolder(CString strSearchFolder) { m_strSearchFolder = strSearchFolder; };
CString GetSearchFolder() { return m_strSearchFolder; };
// Generated message map functions
protected:
//{{AFX_MSG(CFileTree)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
CImageList m_cImageList;
void RecurseDirectory(char szFolder[_MAX_PATH], HTREEITEM hRoot, PSTR pszFileSpec);
typedef std::map<HTREEITEM,CString> Files;
Files m_cFileNames;
CString m_strFileSpec;
CString m_strSearchFolder;
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_FILETREE_H__9848DF42_CD7E_4ADD_96F9_E01605C420D6__INCLUDED_)

View File

@@ -0,0 +1,286 @@
// HiColorToolBar.cpp : implementation file
//
#include "stdafx.h"
#include "HiColorToolBar.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CHiColorToolBar
CHiColorToolBar::CHiColorToolBar()
{
}
CHiColorToolBar::~CHiColorToolBar()
{
}
BEGIN_MESSAGE_MAP(CHiColorToolBar, CToolBar)
//{{AFX_MSG_MAP(CHiColorToolBar)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHiColorToolBar message handlers
void CHiColorToolBar::AttachToolbarImages(UINT inNormalImageID)
{
////////////////////////////////////////////////////////////////////////
// Load the high color toolbar images and attach them to the toolbar
////////////////////////////////////////////////////////////////////////
// Make high-color image lists for each of the bitmaps
MakeToolbarImageList(inNormalImageID, m_ToolbarImages, LTNormal);
MakeToolbarImageList(inNormalImageID, m_ToolbarImagesDisabled, LTDisabled);
MakeToolbarImageList(inNormalImageID, m_ToolbarImagesHot, LTHot);
// Get the toolbar control associated with the CToolbar object
CToolBarCtrl& barCtrl = GetToolBarCtrl();
// Attach the image lists to the toolbar control
barCtrl.SetImageList(&m_ToolbarImages);
barCtrl.SetDisabledImageList(&m_ToolbarImagesDisabled);
barCtrl.SetHotImageList(&m_ToolbarImagesHot);
}
void CHiColorToolBar::ReplaceBackgroundColor(CBitmap& ioBM)
{
////////////////////////////////////////////////////////////////////////
// Find every pixel of the default background color in the specified
// bitmap and set each one to the user's button color
////////////////////////////////////////////////////////////////////////
// Figure out how many pixels there are in the bitmap
BITMAP bmInfo;
VERIFY (ioBM.GetBitmap (&bmInfo));
// Add support for additional bit depths if you choose
VERIFY (bmInfo.bmBitsPixel == 24);
VERIFY (bmInfo.bmWidthBytes == (bmInfo.bmWidth * 3));
const UINT numPixels (bmInfo.bmHeight * bmInfo.bmWidth);
// Get a pointer to the pixels
DIBSECTION ds;
VERIFY (ioBM.GetObject (sizeof (DIBSECTION), &ds) == sizeof (DIBSECTION));
RGBTRIPLE* pixels = reinterpret_cast<RGBTRIPLE *> (ds.dsBm.bmBits);
VERIFY (pixels != NULL);
// Get the user's preferred button color from the system
const COLORREF buttonColor (::GetSysColor (COLOR_BTNFACE));
const RGBTRIPLE userBackgroundColor = {
GetBValue (buttonColor), GetGValue (buttonColor), GetRValue (buttonColor)};
// Search through the pixels, substituting the user's button
// color for any pixel that has the magic background color
for (UINT i = 0; i < numPixels; ++i)
{
if (pixels[i].rgbtBlue == kBackgroundColor.rgbtBlue
&& pixels[i].rgbtGreen == kBackgroundColor.rgbtGreen
&& pixels[i].rgbtRed == kBackgroundColor.rgbtRed)
{
pixels [i] = userBackgroundColor;
}
}
}
void CHiColorToolBar::MakeDisabled(CBitmap &ioBM)
{
////////////////////////////////////////////////////////////////////////
// Give the bitmap a disabled look
////////////////////////////////////////////////////////////////////////
// Figure out how many pixels there are in the bitmap
BITMAP bmInfo;
VERIFY (ioBM.GetBitmap (&bmInfo));
// Add support for additional bit depths if you choose
VERIFY (bmInfo.bmBitsPixel == 24);
VERIFY (bmInfo.bmWidthBytes == (bmInfo.bmWidth * 3));
const UINT numPixels (bmInfo.bmHeight * bmInfo.bmWidth);
// Get a pointer to the pixels
DIBSECTION ds;
VERIFY (ioBM.GetObject (sizeof (DIBSECTION), &ds) == sizeof (DIBSECTION));
RGBTRIPLE* pixels = reinterpret_cast<RGBTRIPLE *> (ds.dsBm.bmBits);
VERIFY (pixels != NULL);
// Get the user's preferred button color from the system
const COLORREF buttonColor (::GetSysColor (COLOR_BTNFACE));
const RGBTRIPLE userBackgroundColor = {
GetBValue (buttonColor), GetGValue (buttonColor), GetRValue (buttonColor)};
// Loop trough all pixels
for (UINT i = 0; i < numPixels; ++i)
{
if (pixels[i].rgbtBlue == userBackgroundColor.rgbtBlue
&& pixels[i].rgbtGreen == userBackgroundColor.rgbtGreen
&& pixels[i].rgbtRed == userBackgroundColor.rgbtRed)
{
// Skip pixels that have the background color
continue;
}
// Average out the BGR channels
pixels[i].rgbtBlue = (pixels[i].rgbtBlue + pixels[i].rgbtGreen + pixels[i].rgbtRed) / 3;
pixels[i].rgbtRed = pixels[i].rgbtGreen = pixels[i].rgbtBlue;
}
}
void CHiColorToolBar::MakeToolbarImageList(UINT inBitmapID, CImageList& outImageList, LoadType lt)
{
////////////////////////////////////////////////////////////////////////
// Create an image list for the specified BMP resource
////////////////////////////////////////////////////////////////////////
CBitmap bm;
DWORD dwStyleParam = 0;
// If we use CBitmap::LoadBitmap() to load the bitmap, the colors
// will be reduced to the bit depth of the main screen and we won't
// be able to access the pixels directly. To avoid those problems,
// we'll load the bitmap as a DIBSection instead and attach the
// DIBSection to the CBitmap.
VERIFY(bm.Attach (::LoadImage (::AfxFindResourceHandle(
MAKEINTRESOURCE (inBitmapID), RT_BITMAP),
MAKEINTRESOURCE (inBitmapID), IMAGE_BITMAP, 0, 0,
(LR_DEFAULTSIZE | LR_CREATEDIBSECTION) | dwStyleParam)));
// Replace the specified color in the bitmap with the user's
// button color
ReplaceBackgroundColor(bm);
// Disable it when requested
if (lt == LTDisabled)
MakeDisabled(bm);
// Create a 24 bit image list with the same dimensions and number
// of buttons as the toolbar
VERIFY(outImageList.Create (
kImageWidth, kImageHeight, kToolBarBitDepth, kNumImages, 0));
// Attach the bitmap to the image list
VERIFY(outImageList.Add (&bm, RGB (0, 0, 0)) != -1);
}
void CHiColorToolBar::AddTextStrings()
{
////////////////////////////////////////////////////////////////////////
// Add text descriptions to a tool bar
////////////////////////////////////////////////////////////////////////
// Set the text for each button
CToolBarCtrl& bar = GetToolBarCtrl();
// Remove the string map in case we are loading another toolbar into this control
if (m_pStringMap)
{
delete m_pStringMap;
m_pStringMap = NULL;
}
int nIndex = 0;
TBBUTTON tb;
for (nIndex = bar.GetButtonCount() - 1; nIndex >= 0; nIndex--)
{
ZeroMemory(&tb, sizeof(TBBUTTON));
bar.GetButton(nIndex, &tb);
// Do we have a separator?
if ((tb.fsStyle & TBSTYLE_SEP) == TBSTYLE_SEP)
continue;
// Have we got a valid command id?
if (tb.idCommand == 0)
continue;
// Get the resource string if there is one.
CString strText;
LPCTSTR lpszButtonText = NULL;
CString strButtonText(_T(""));
_TCHAR seps[] = _T("\n");
strText.LoadString(tb.idCommand);
if (!strText.IsEmpty())
{
lpszButtonText = _tcstok((LPTSTR) (LPCTSTR) strText, seps);
while(lpszButtonText)
{
strButtonText = lpszButtonText;
lpszButtonText = _tcstok(NULL, seps);
}
}
if (!strButtonText.IsEmpty())
SetButtonText(nIndex, strButtonText);
}
// Resize the buttons so that the text will fit.
CRect rc(0, 0, 0, 0);
CSize sizeMax(0, 0);
for (nIndex = bar.GetButtonCount() - 1; nIndex >= 0; nIndex--)
{
bar.GetItemRect(nIndex, rc);
rc.NormalizeRect();
sizeMax.cx = __max(rc.Size().cx, sizeMax.cx);
sizeMax.cy = __max(rc.Size().cy, sizeMax.cy);
}
SetSizes(sizeMax, CSize(32, 32));
// Set the minimum button size
SendMessage(TB_SETBUTTONWIDTH, 0, (LPARAM) (DWORD) MAKELONG(85, 128));
}
bool CHiColorToolBar::CreateAll(UINT nIDRessource, UINT inNormalImageID, CWnd *pwndParent)
{
////////////////////////////////////////////////////////////////////////
// Load all data required for the full toolbar functionality
////////////////////////////////////////////////////////////////////////
CLogFile::WriteLine("Creating new high color toolbar...");
// Create the toolbar itself
if (!CreateEx(pwndParent, TBSTYLE_FLAT | TBSTYLE_WRAPABLE, WS_CHILD | CBRS_TOP
| CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC))
{
return false;
}
// Load the buttons
if (!LoadToolBar(nIDRessource))
return false;
// Attach the 24bpp images
AttachToolbarImages(inNormalImageID);
// Read the text strings out of the ressource and set them
AddTextStrings();
// Set maximum number of rows
GetToolBarCtrl().SetRows(99, TRUE, NULL);
// Indent the first button a few pixels so that the toolbar is centered
GetToolBarCtrl().SetIndent(4);
return true;
}

View File

@@ -0,0 +1,84 @@
#if !defined(AFX_HICOLORTOOLBAR_H__401DCAAA_ED0C_4838_8A8A_5B2C55328891__INCLUDED_)
#define AFX_HICOLORTOOLBAR_H__401DCAAA_ED0C_4838_8A8A_5B2C55328891__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// HiColorToolBar.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CHiColorToolBar window
// These constants represent the dimensions and number of buttons in
// the default MFC-generated toolbar. If you need something different,
// feel free to change them. For extra credit, you can load the
// toolbar's existing image list at runtime and copy the parameters from
// there.
static const int kImageWidth (32);
static const int kImageHeight (32);
static const int kNumImages (8);
static const UINT kToolBarBitDepth (ILC_COLOR24);
// This color will be treated as transparent in the loaded bitmaps --
// in other words, any pixel of this color will be set at runtime to
// the user's button color. The Visual Studio toolbar editor defaults
// to 255, 0, 255 (pink).
static const RGBTRIPLE kBackgroundColor = {255, 0, 255};
// Parameters for
class CHiColorToolBar : public CToolBar
{
// Construction
public:
CHiColorToolBar();
// Attributes MakeToolbarImageList()
enum LoadType
{
LTNormal,
LTDisabled,
LTHot
};
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHiColorToolBar)
//}}AFX_VIRTUAL
// Implementation
public:
bool CreateAll(UINT nIDRessource, UINT inHotImage, CWnd *pwndParent);
virtual ~CHiColorToolBar();
// Generated message map functions
protected:
//{{AFX_MSG(CHiColorToolBar)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
void ReplaceBackgroundColor(CBitmap& ioBM);
void MakeDisabled(CBitmap &ioBM);
void MakeToolbarImageList(UINT inBitmapID, CImageList& outImageList, LoadType lt);
void AddTextStrings();
void AttachToolbarImages(UINT inNormalImageID);
CImageList m_ToolbarImagesDisabled;
CImageList m_ToolbarImagesHot;
CImageList m_ToolbarImages;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_HICOLORTOOLBAR_H__401DCAAA_ED0C_4838_8A8A_5B2C55328891__INCLUDED_)

View File

@@ -0,0 +1,48 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: inplacebutton.cpp
// Version: v1.00
// Created: 6/6/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History: Based on Stefan Belopotocan code.
//
////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "InPlaceButton.h"
// CInPlaceButton
IMPLEMENT_DYNAMIC(CInPlaceButton, CXTButton)
CInPlaceButton::CInPlaceButton( OnClick onClickFunctor )
{
m_onClick = onClickFunctor;
}
CInPlaceButton::~CInPlaceButton()
{
}
BEGIN_MESSAGE_MAP(CInPlaceButton, CXTButton)
ON_CONTROL_REFLECT(BN_CLICKED, OnBnClicked)
END_MESSAGE_MAP()
// CInPlaceButton message handlers
void CInPlaceButton::OnBnClicked()
{
if (m_onClick)
m_onClick();
}
void CInPlaceButton::Click()
{
OnBnClicked();
}

View File

@@ -0,0 +1,47 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: inplacebutton.h
// Version: v1.00
// Created: 6/6/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __inplacebutton_h__
#define __inplacebutton_h__
#if _MSC_VER > 1000
#pragma once
#endif
// CInPlaceButton
#include <XTToolkit.h>
class CInPlaceButton : public CXTButton
{
DECLARE_DYNAMIC(CInPlaceButton)
public:
typedef Functor0 OnClick;
CInPlaceButton( OnClick onClickFunctor );
virtual ~CInPlaceButton();
// Simuale on click.
void Click();
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClicked();
OnClick m_onClick;
};
#endif // __inplacebutton_h__

Some files were not shown because too many files have changed in this diff Show More