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

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__