diff options
Diffstat (limited to 'hammer/mapface.h')
| -rw-r--r-- | hammer/mapface.h | 644 |
1 files changed, 644 insertions, 0 deletions
diff --git a/hammer/mapface.h b/hammer/mapface.h new file mode 100644 index 0000000..df1f8c4 --- /dev/null +++ b/hammer/mapface.h @@ -0,0 +1,644 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef MAPFACE_H +#define MAPFACE_H + +#ifdef _WIN32 +#pragma once +#endif + + +#pragma warning(push, 1) +#pragma warning(disable:4701 4702 4530) +#include <fstream> +#pragma warning(pop) +#include "hammer_mathlib.h" +#include "MapAtom.h" +#include "DispManager.h" +#include "mathlib/Vector4d.h" +#include "utlvector.h" +#include "Color.h" +#include "smoothinggroupmgr.h" +#include "detailobjects.h" + +class CCheckFaceInfo; +class IEditorTexture; +class CRender; +class CRender3D; +class CChunkFile; +class CSaveInfo; +class IMaterial; +class CMapWorld; +struct MapFaceRender_t; +class CMeshBuilder; +class IMesh; + +struct LoadFace_t; + +enum EditorRenderMode_t; +enum ChunkFileResult_t; + +#define DEFAULT_TEXTURE_SCALE 0.25 +#define DEFAULT_LIGHTMAP_SCALE 16 + +#define SMOOTHING_GROUP_MAX_COUNT 32 +#define SMOOTHING_GROUP_DEFAULT 0 + +// +// Flags for CMapFace::CopyFrom. +// +#define COPY_FACE_PLANE 0x00000001 // Copies only the face's plane. Used for carving. +#define COPY_FACE_POINTS 0x00000002 // Copies the face's points and plane. + + +// +// Used for storing the extrema of a face. Each element of the Extents_t array +// contains a point that represents a local extreme along a particular dimension. +// +enum +{ + EXTENTS_XMIN = 0, + EXTENTS_XMAX, + EXTENTS_YMIN, + EXTENTS_YMAX, + EXTENTS_ZMIN, + EXTENTS_ZMAX, + NUM_EXTENTS_DIMS, +}; + +typedef Vector Extents_t[NUM_EXTENTS_DIMS]; + + +struct PLANE +{ + Vector normal; + float dist; + Vector planepts[3]; +}; + + +typedef struct +{ + int numpoints; + Vector *p; // variable sized +} winding_t; + + +enum FaceOrientation_t +{ + FACE_ORIENTATION_FLOOR = 0, + FACE_ORIENTATION_CEILING, + FACE_ORIENTATION_NORTH_WALL, + FACE_ORIENTATION_SOUTH_WALL, + FACE_ORIENTATION_EAST_WALL, + FACE_ORIENTATION_WEST_WALL, + FACE_ORIENTATION_INVALID +}; + + +// +// Both an enumeration and bitflags. Used as bitflags when querying a face for its texture +// alignment because it could be world aligned and face aligned at the same time. +// +enum TextureAlignment_t +{ + TEXTURE_ALIGN_NONE = 0x0000, + TEXTURE_ALIGN_WORLD = 0x0001, + TEXTURE_ALIGN_FACE = 0x0002, + TEXTURE_ALIGN_QUAKE = 0x0004 +}; + + +enum TextureJustification_t +{ + TEXTURE_JUSTIFY_NONE = 0, + TEXTURE_JUSTIFY_TOP, + TEXTURE_JUSTIFY_BOTTOM, + TEXTURE_JUSTIFY_LEFT, + TEXTURE_JUSTIFY_CENTER, + TEXTURE_JUSTIFY_RIGHT, + TEXTURE_JUSTIFY_FIT, + TEXTURE_JUSTIFY_MAX +}; + + +#define INIT_TEXTURE_FORCE 0x0001 +#define INIT_TEXTURE_AXES 0x0002 +#define INIT_TEXTURE_ROTATION 0x0004 +#define INIT_TEXTURE_SHIFT 0x0008 +#define INIT_TEXTURE_SCALE 0x0010 +#define INIT_TEXTURE_ALL (INIT_TEXTURE_AXES | INIT_TEXTURE_ROTATION | INIT_TEXTURE_SHIFT | INIT_TEXTURE_SCALE) + + +// +// Flags for CreateFace. +// +#define CREATE_FACE_PRESERVE_PLANE 0x0001 // Hack to prevent plane from being recalculated while building a solid from its planes. +#define CREATE_FACE_CLIPPING 0x0002 + +// +// Serialized data structure. Do not modify! +// +struct TEXTURE_21 +{ + char texture[MAX_PATH]; + float rotate; + float shift[2]; + float scale[2]; + BYTE smooth; + BYTE material; + DWORD q2surface; + DWORD q2contents; + DWORD q2value; +}; + + +// +// Post 2.1 explicit texture U/V axes were added. +// +// Serialized data structure. Do not modify! +// +struct TEXTURE_33 +{ + char texture[MAX_PATH]; + float UAxis[4]; // Must remain float[4] for RMF serialization. + float VAxis[4]; // Must remain float[4] for RMF serialization. + float rotate; + float scale[2]; + BYTE smooth; + BYTE material; + DWORD q2surface; + DWORD q2contents; + int nLightmapScale; +}; + + +struct TEXTURE +{ + char texture[MAX_PATH]; + Vector4D UAxis; + Vector4D VAxis; + float rotate; + float scale[2]; + BYTE smooth; + BYTE material; + DWORD q2surface; + DWORD q2contents; + int nLightmapScale; + + TEXTURE& operator=( TEXTURE const& src ) + { + // necessary since operator= is private for UAxis + memcpy( this, &src, sizeof(TEXTURE) ); + return *this; + } +}; + + +#define FACE_FLAGS_NOSHADOW 1 +#define FACE_FLAGS_NODRAW_IN_LPREVIEW 2 + + + +class CMapFace : public CMapAtom +{ +public: + + CMapFace(void); + ~CMapFace(void); + + // If bRescaleTextureCoordinates is true, then it will rescale and reoffset the texture coordinates + // so that the texture is in the same apparent spot as the old texture (if they are different sizes). + void SetTexture(const char *pszNewTex, bool bRescaleTextureCoordinates = false); + void SetTexture(IEditorTexture *pTexture, bool bRescaleTextureCoordinates = false); + void GetTextureName(char *pszName) const; + + inline IEditorTexture *GetTexture(void) const; + + // Renders opaque faces + static void AddFaceToQueue( CMapFace* pMapFace, IEditorTexture* pTexture, EditorRenderMode_t renderMode, bool selected, SelectionState_t faceSelectionState ); + static void PushFaceQueue( void ); + static void PopFaceQueue( void ); + static void RenderOpaqueFaces( CRender3D* pRender ); + + // + // Serialization. + // + ChunkFileResult_t LoadVMF(CChunkFile *pFile); + ChunkFileResult_t SaveVMF(CChunkFile *pFile, CSaveInfo *pSaveInfo); + int SerializeRMF(std::fstream&, BOOL); + int SerializeMAP(std::fstream&, BOOL); + + BOOL CheckFace(CCheckFaceInfo* = NULL); + BOOL Fix(void); + + float GetNormalDistance(Vector& fPoint); + + inline int GetPointCount(void); + inline void GetPoint(Vector& Point, int nPoint); + + inline void GetLightmapCoord( Vector2D & LightmapCoord, int nIndex ); + inline void SetLightmapCoord( const Vector2D &LightmapCoord, int nIndex ); + inline void GetTexCoord( Vector2D & TexCoord, int nTexCoord ); + + // Texture alignment. + void GetCenter(Vector& Center); + FaceOrientation_t GetOrientation(void) const; + void RotateTextureAxes(float fDegrees); + void InitializeTextureAxes(TextureAlignment_t eAlignment, DWORD dwFlags); + void JustifyTexture(TextureJustification_t eJustification); + void JustifyTextureUsingExtents(TextureJustification_t eJustification, Extents_t Extents); + void GetFaceBounds(Vector& pfMins, Vector& pfMaxs) const; + void GetFaceExtents(Extents_t Extents) const; + void GetTextureExtents(Extents_t Extents, Vector2D & TopLeft, Vector2D & BottomRight) const; + int GetTextureAlignment(void) const; + void GetFaceTextureExtents(Vector2D & TopLeft, Vector2D & BottomRight) const; + + void CalcTextureCoordAtPoint( const Vector& pt, Vector2D & texCoord ); + void CalcLightmapCoordAtPoint( const Vector& pt, Vector2D & lightCoord ); + + // Returns the max lightmap size for this face + int MaxLightmapSize() const; + + void NormalizeTextureShifts(void); + BOOL IsTextureAxisValid(void) const; + + inline void SetCordonFace( bool bCordonFace ); + inline bool IsCordonFace() const; + + // Old code for setting up texture axes. Needed for backwards compatibility. + void InitializeQuakeStyleTextureAxes(Vector4D& UAxis, Vector4D& VAxis); + + void CreateFace(Vector *pPoints, int nPoints, bool bIsCordonFace = false); + void CreateFace(winding_t *w, int nFlags = 0); + CMapFace *CopyFrom(const CMapFace *pFrom, DWORD dwFlags = COPY_FACE_POINTS, bool bUpdateDependencies = true ); + size_t AllocatePoints(int nPoints); + + void OnUndoRedo(); + + void CalcPlane(void); + void CalcPlaneFromFacePoints(void); + + void CalcTextureCoords(); + void OffsetTexture(const Vector &Delta); + void SetTextureCoords(int nPoint, float u, float v); + + struct TangentSpaceAxes_t + { + Vector tangent; + Vector binormal; + }; + + void CalcTangentSpaceAxes( void ); + bool AllocTangentSpaceAxes( int count ); + void FreeTangentSpaceAxes( void ); + + void Render2D(CRender2D *pRender); + void Render3D(CRender3D *pRender); + void Render3DGrid(CRender3D *pRender); + void RenderVertices(CRender *pRender); + + void OnAddToWorld(CMapWorld *pWorld); + void OnRemoveFromWorld(void); + + static void SetShowSelection(bool bShowSelection); + + inline void SetRenderAlpha(unsigned char uchAlpha) { m_uchAlpha = uchAlpha; } // HACK: should be in CMapAtom + + inline void GetFaceNormal( Vector& normal ); + bool TraceLine(Vector &HitPos, Vector &HitNormal, Vector const &Start, Vector const &End); + bool TraceLineInside( Vector &HitPos, Vector &HitNormal, Vector const &Start, Vector const &End, bool bNoDisp = false ); + + inline void SetDisp( EditDispHandle_t handle, bool bDestroyPrevious = true ); + inline EditDispHandle_t GetDisp( void ); + inline bool HasDisp( void ) const; + + bool ShouldRenderLast(); + void GetDownVector( int index, Vector& downVect ); + + bool GetRender2DBox( Vector& boundMin, Vector& boundMax ); + bool GetCullBox( Vector& boundMin, Vector& boundMax ); + size_t GetDataSize( void ); + + inline int GetFaceID(void); + inline void SetFaceID(int nFaceID); + + // Smoothing group. + int SmoothingGroupCount( void ); + void AddSmoothingGroup( int iGroup ); + void RemoveSmoothingGroup( int iGroup ); + bool InSmoothingGroup( int iGroup ); + + // Indicates this guy should be unlit + void RenderUnlit( bool enable ); + + // (begin serialized information + TEXTURE texture; // Texture info. + Vector *Points; // Array of face points, dynamically allocated. + int nPoints; // The number of points in the array. + // end serialized information) + + PLANE plane; + + int m_nFaceFlags; // FACE_FLAGS_xx + + void DoTransform(const VMatrix &matrix); + + virtual void AddShadowingTriangles( CUtlVector<Vector> &tri_list ); + + DetailObjects *m_pDetailObjects; + +protected: + + void ComputeColor( CRender3D* pRender, bool bRenderAsSelected, SelectionState_t faceSelectionState, + bool ignoreLighting, Color &pColor ); + + void DrawFace( Color &pColor, EditorRenderMode_t mode ); + void RenderGridIfCloseEnough( CRender3D* pRender ); + void RenderTextureAxes( CRender3D* pRender ); + + // Adds a face's vertices to the meshbuilder + void AddFaceVertices( CMeshBuilder &builder, CRender3D* pRender, bool bRenderSelected, SelectionState_t faceSelectionState ); + + // render texture axes + static void RenderTextureAxes( CRender3D* pRender, int nCount, CMapFace **ppFaces ); + static void RenderGridsIfCloseEnough( CRender3D* pRender, int nCount, CMapFace **ppFaces ); + static void Render3DGrids( CRender3D* pRender, int nCount, CMapFace **ppFaces ); + static void RenderWireframeFaces( CRender3D* pRender, int nCount, MapFaceRender_t **ppFaces ); + static void RenderFacesBatch( CMeshBuilder &MeshBuilder, IMesh* pMesh, CRender3D* pRender, MapFaceRender_t **ppFaces, int nFaceCount, int nVertexCount, int nIndexCount, bool bWireframe ); + static void RenderFaces( CRender3D* pRender, int nCount, MapFaceRender_t **ppFaces ); + + void RenderFace3D( CRender3D* pRender, EditorRenderMode_t renderMode, bool renderSelected, SelectionState_t faceSelectionState ); + + // + // Serialization (chunk handlers). + // + static ChunkFileResult_t LoadDispInfoCallback(CChunkFile *pFile, CMapFace *pFace); + static ChunkFileResult_t LoadKeyCallback(const char *szKey, const char *szValue, LoadFace_t *pLoadFace); + + unsigned char m_uchAlpha; // HACK: should be in CMapAtom + + int m_nFaceID; // The unique ID of this face in the world. + + IEditorTexture *m_pTexture; // Texture that is applied to this face. + static IEditorTexture *m_pLightmapGrid; // Lightmap grid texture for use in viewing lightmap scales. + EditDispHandle_t m_DispHandle; // Displacement map applied to this face, NULL if none. + + static bool m_bShowFaceSelection; // Whether to render faces with a special color when they are selected. + + Vector2D *m_pTextureCoords; // An array of texture coordinates, one per face point. + Vector2D *m_pLightmapCoords; // An array of lightmap coordinates, one per face point. + + bool m_bIsCordonFace : 1; + + // should this be affected by lighting? + bool m_bIgnoreLighting : 1; + + TangentSpaceAxes_t *m_pTangentAxes; + + unsigned int m_fSmoothingGroups; // 32-bits representing 32 smoothing groups + + void UpdateFaceFlags( void ); // sniff face flags from texture +}; + + +//----------------------------------------------------------------------------- +// Purpose: Returns the unique ID of this face. +//----------------------------------------------------------------------------- +inline int CMapFace::GetFaceID(void) +{ + return(m_nFaceID); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : TexCoord - +// nTexCoord - +//----------------------------------------------------------------------------- +inline void CMapFace::GetLightmapCoord( Vector2D& LightmapCoord, int nIndex ) +{ + Assert( nIndex < nPoints ); + LightmapCoord[0] = m_pLightmapCoords[nIndex][0]; + LightmapCoord[1] = m_pLightmapCoords[nIndex][1]; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &LightmapCoord - +// nIndex - +// Output : inline void +//----------------------------------------------------------------------------- +inline void CMapFace::SetLightmapCoord( const Vector2D &LightmapCoord, int nIndex ) +{ + Assert( nIndex < nPoints ); + m_pLightmapCoords[nIndex][0] = LightmapCoord[0]; + m_pLightmapCoords[nIndex][1] = LightmapCoord[1]; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : TexCoord - +// nTexCoord - +//----------------------------------------------------------------------------- +inline void CMapFace::GetTexCoord( Vector2D& TexCoord, int nTexCoord ) +{ + Assert( nTexCoord < nPoints ); + TexCoord[0] = m_pTextureCoords[nTexCoord][0]; + TexCoord[1] = m_pTextureCoords[nTexCoord][1]; +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns a pointer to the texture that is applied to this face, NULL if none. +//----------------------------------------------------------------------------- +inline IEditorTexture *CMapFace::GetTexture(void) const +{ + return(m_pTexture); +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns the number of vertices that define this face. +//----------------------------------------------------------------------------- +inline int CMapFace::GetPointCount(void) +{ + return(nPoints); +} + + +//----------------------------------------------------------------------------- +// Purpose: Retrieves a point on this face by its index. +// Input : Point - Receives point coordinates. +// nPoint - Index of point to retrieve. +//----------------------------------------------------------------------------- +inline void CMapFace::GetPoint(Vector& Point, int nPoint) +{ + Assert(nPoint < nPoints); + Point = Points[nPoint]; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CMapFace::GetFaceNormal( Vector& normal ) +{ + normal = plane.normal; +} + + +//----------------------------------------------------------------------------- +// Purpose: Sets the unique ID of this face. +//----------------------------------------------------------------------------- +inline void CMapFace::SetFaceID(int nID) +{ + m_nFaceID = nID; +} + + +//----------------------------------------------------------------------------- +// Purpose: Attaches a displacement surface to this face. +// Input : handle - Displacement surface handle of surface attached to this face +//----------------------------------------------------------------------------- +inline void CMapFace::SetDisp( EditDispHandle_t handle, bool bDestroyPrevious ) +{ + if ( ( m_DispHandle != EDITDISPHANDLE_INVALID ) && bDestroyPrevious ) + { + // destroy old handle + EditDispMgr()->Destroy( m_DispHandle ); + } + + Assert( ( handle == EDITDISPHANDLE_INVALID ) || ( EditDispMgr()->GetDisp( handle ) != NULL ) ); + + m_DispHandle = handle; +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns the displacement surface applied to this face, +// DISPHANDLE_INVALID if none. +//----------------------------------------------------------------------------- +inline EditDispHandle_t CMapFace::GetDisp( void ) +{ + return m_DispHandle; +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns true if this face has a displacement surface, false if not. +//----------------------------------------------------------------------------- +inline bool CMapFace::HasDisp( void ) const +{ + return ( m_DispHandle != EDITDISPHANDLE_INVALID ); +} + + +//----------------------------------------------------------------------------- +// Whether this face belongs to a cordon brush. +//----------------------------------------------------------------------------- +inline void CMapFace::SetCordonFace( bool bCordonFace ) +{ + m_bIsCordonFace = bCordonFace; +} + + +inline bool CMapFace::IsCordonFace() const +{ + return m_bIsCordonFace; +} + + +//----------------------------------------------------------------------------- +// Defines a container class for a list of face pointers. +//----------------------------------------------------------------------------- +class CMapFaceList : public CUtlVector<CMapFace *> +{ +public: + + inline CMapFaceList(void) {} + inline CMapFaceList(CMapFaceList const &other); + inline CMapFaceList &CMapFaceList::operator =(CMapFaceList const &other); + + inline int FindFaceID(int nFaceID); + void Intersect(CMapFaceList &IntersectWith, CMapFaceList &In, CMapFaceList &Out); +}; + + +//----------------------------------------------------------------------------- +// Purpose: Copy constructor. +//----------------------------------------------------------------------------- +CMapFaceList::CMapFaceList(CMapFaceList const &other) +{ + *this = other; +} + + +//----------------------------------------------------------------------------- +// Purpose: Assignment operator for copying face lists. +// Input : other - +//----------------------------------------------------------------------------- +CMapFaceList &CMapFaceList::operator =(CMapFaceList const &other) +{ + AddVectorToTail(other); + return *this; +} + + +//----------------------------------------------------------------------------- +// Purpose: Searches the list for a face with the given ID. +// Input : nFaceID - Numeric face ID to search for. +// Output : Index of found element, -1 if none. +//----------------------------------------------------------------------------- +int CMapFaceList::FindFaceID(int nFaceID) +{ + for (int i = 0; i < Count(); i++) + { + if ((Element(i) != NULL) && (Element(i)->GetFaceID() == nFaceID)) + { + return(i); + } + } + + return(-1); +} + + +//----------------------------------------------------------------------------- +// Defines a container class for a list of face IDs. +//----------------------------------------------------------------------------- +class CMapFaceIDList : public CUtlVector<int> +{ +public: + + inline CMapFaceIDList(void) {} + inline CMapFaceIDList(CMapFaceIDList const &other); + inline CMapFaceIDList &CMapFaceIDList::operator =(CMapFaceIDList const &other); + + void Intersect(CMapFaceIDList &IntersectWith, CMapFaceIDList &In, CMapFaceIDList &Out); +}; + + +//----------------------------------------------------------------------------- +// Purpose: Copy constructor. +//----------------------------------------------------------------------------- +CMapFaceIDList::CMapFaceIDList(CMapFaceIDList const &other) +{ + *this = other; +} + + +//----------------------------------------------------------------------------- +// Purpose: Assignment operator for copying face ID lists. +// Input : other - +//----------------------------------------------------------------------------- +CMapFaceIDList &CMapFaceIDList::operator =(CMapFaceIDList const &other) +{ + AddVectorToTail(other); + return *this; +} + + +#endif // MAPFACE_H |