Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

644 lines
19 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef MAPFACE_H
  7. #define MAPFACE_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #pragma warning(push, 1)
  12. #pragma warning(disable:4701 4702 4530)
  13. #include <fstream>
  14. #pragma warning(pop)
  15. #include "hammer_mathlib.h"
  16. #include "MapAtom.h"
  17. #include "DispManager.h"
  18. #include "mathlib/Vector4d.h"
  19. #include "utlvector.h"
  20. #include "Color.h"
  21. #include "smoothinggroupmgr.h"
  22. #include "detailobjects.h"
  23. class CCheckFaceInfo;
  24. class IEditorTexture;
  25. class CRender;
  26. class CRender3D;
  27. class CChunkFile;
  28. class CSaveInfo;
  29. class IMaterial;
  30. class CMapWorld;
  31. struct MapFaceRender_t;
  32. class CMeshBuilder;
  33. class IMesh;
  34. struct LoadFace_t;
  35. enum EditorRenderMode_t;
  36. enum ChunkFileResult_t;
  37. #define DEFAULT_TEXTURE_SCALE 0.25
  38. #define DEFAULT_LIGHTMAP_SCALE 16
  39. #define SMOOTHING_GROUP_MAX_COUNT 32
  40. #define SMOOTHING_GROUP_DEFAULT 0
  41. //
  42. // Flags for CMapFace::CopyFrom.
  43. //
  44. #define COPY_FACE_PLANE 0x00000001 // Copies only the face's plane. Used for carving.
  45. #define COPY_FACE_POINTS 0x00000002 // Copies the face's points and plane.
  46. //
  47. // Used for storing the extrema of a face. Each element of the Extents_t array
  48. // contains a point that represents a local extreme along a particular dimension.
  49. //
  50. enum
  51. {
  52. EXTENTS_XMIN = 0,
  53. EXTENTS_XMAX,
  54. EXTENTS_YMIN,
  55. EXTENTS_YMAX,
  56. EXTENTS_ZMIN,
  57. EXTENTS_ZMAX,
  58. NUM_EXTENTS_DIMS,
  59. };
  60. typedef Vector Extents_t[NUM_EXTENTS_DIMS];
  61. struct PLANE
  62. {
  63. Vector normal;
  64. float dist;
  65. Vector planepts[3];
  66. };
  67. typedef struct
  68. {
  69. int numpoints;
  70. Vector *p; // variable sized
  71. } winding_t;
  72. enum FaceOrientation_t
  73. {
  74. FACE_ORIENTATION_FLOOR = 0,
  75. FACE_ORIENTATION_CEILING,
  76. FACE_ORIENTATION_NORTH_WALL,
  77. FACE_ORIENTATION_SOUTH_WALL,
  78. FACE_ORIENTATION_EAST_WALL,
  79. FACE_ORIENTATION_WEST_WALL,
  80. FACE_ORIENTATION_INVALID
  81. };
  82. //
  83. // Both an enumeration and bitflags. Used as bitflags when querying a face for its texture
  84. // alignment because it could be world aligned and face aligned at the same time.
  85. //
  86. enum TextureAlignment_t
  87. {
  88. TEXTURE_ALIGN_NONE = 0x0000,
  89. TEXTURE_ALIGN_WORLD = 0x0001,
  90. TEXTURE_ALIGN_FACE = 0x0002,
  91. TEXTURE_ALIGN_QUAKE = 0x0004
  92. };
  93. enum TextureJustification_t
  94. {
  95. TEXTURE_JUSTIFY_NONE = 0,
  96. TEXTURE_JUSTIFY_TOP,
  97. TEXTURE_JUSTIFY_BOTTOM,
  98. TEXTURE_JUSTIFY_LEFT,
  99. TEXTURE_JUSTIFY_CENTER,
  100. TEXTURE_JUSTIFY_RIGHT,
  101. TEXTURE_JUSTIFY_FIT,
  102. TEXTURE_JUSTIFY_MAX
  103. };
  104. #define INIT_TEXTURE_FORCE 0x0001
  105. #define INIT_TEXTURE_AXES 0x0002
  106. #define INIT_TEXTURE_ROTATION 0x0004
  107. #define INIT_TEXTURE_SHIFT 0x0008
  108. #define INIT_TEXTURE_SCALE 0x0010
  109. #define INIT_TEXTURE_ALL (INIT_TEXTURE_AXES | INIT_TEXTURE_ROTATION | INIT_TEXTURE_SHIFT | INIT_TEXTURE_SCALE)
  110. //
  111. // Flags for CreateFace.
  112. //
  113. #define CREATE_FACE_PRESERVE_PLANE 0x0001 // Hack to prevent plane from being recalculated while building a solid from its planes.
  114. #define CREATE_FACE_CLIPPING 0x0002
  115. //
  116. // Serialized data structure. Do not modify!
  117. //
  118. struct TEXTURE_21
  119. {
  120. char texture[MAX_PATH];
  121. float rotate;
  122. float shift[2];
  123. float scale[2];
  124. BYTE smooth;
  125. BYTE material;
  126. DWORD q2surface;
  127. DWORD q2contents;
  128. DWORD q2value;
  129. };
  130. //
  131. // Post 2.1 explicit texture U/V axes were added.
  132. //
  133. // Serialized data structure. Do not modify!
  134. //
  135. struct TEXTURE_33
  136. {
  137. char texture[MAX_PATH];
  138. float UAxis[4]; // Must remain float[4] for RMF serialization.
  139. float VAxis[4]; // Must remain float[4] for RMF serialization.
  140. float rotate;
  141. float scale[2];
  142. BYTE smooth;
  143. BYTE material;
  144. DWORD q2surface;
  145. DWORD q2contents;
  146. int nLightmapScale;
  147. };
  148. struct TEXTURE
  149. {
  150. char texture[MAX_PATH];
  151. Vector4D UAxis;
  152. Vector4D VAxis;
  153. float rotate;
  154. float scale[2];
  155. BYTE smooth;
  156. BYTE material;
  157. DWORD q2surface;
  158. DWORD q2contents;
  159. int nLightmapScale;
  160. TEXTURE& operator=( TEXTURE const& src )
  161. {
  162. // necessary since operator= is private for UAxis
  163. memcpy( this, &src, sizeof(TEXTURE) );
  164. return *this;
  165. }
  166. };
  167. #define FACE_FLAGS_NOSHADOW 1
  168. #define FACE_FLAGS_NODRAW_IN_LPREVIEW 2
  169. class CMapFace : public CMapAtom
  170. {
  171. public:
  172. CMapFace(void);
  173. ~CMapFace(void);
  174. // If bRescaleTextureCoordinates is true, then it will rescale and reoffset the texture coordinates
  175. // so that the texture is in the same apparent spot as the old texture (if they are different sizes).
  176. void SetTexture(const char *pszNewTex, bool bRescaleTextureCoordinates = false);
  177. void SetTexture(IEditorTexture *pTexture, bool bRescaleTextureCoordinates = false);
  178. void GetTextureName(char *pszName) const;
  179. inline IEditorTexture *GetTexture(void) const;
  180. // Renders opaque faces
  181. static void AddFaceToQueue( CMapFace* pMapFace, IEditorTexture* pTexture, EditorRenderMode_t renderMode, bool selected, SelectionState_t faceSelectionState );
  182. static void PushFaceQueue( void );
  183. static void PopFaceQueue( void );
  184. static void RenderOpaqueFaces( CRender3D* pRender );
  185. //
  186. // Serialization.
  187. //
  188. ChunkFileResult_t LoadVMF(CChunkFile *pFile);
  189. ChunkFileResult_t SaveVMF(CChunkFile *pFile, CSaveInfo *pSaveInfo);
  190. int SerializeRMF(std::fstream&, BOOL);
  191. int SerializeMAP(std::fstream&, BOOL);
  192. BOOL CheckFace(CCheckFaceInfo* = NULL);
  193. BOOL Fix(void);
  194. float GetNormalDistance(Vector& fPoint);
  195. inline int GetPointCount(void);
  196. inline void GetPoint(Vector& Point, int nPoint);
  197. inline void GetLightmapCoord( Vector2D & LightmapCoord, int nIndex );
  198. inline void SetLightmapCoord( const Vector2D &LightmapCoord, int nIndex );
  199. inline void GetTexCoord( Vector2D & TexCoord, int nTexCoord );
  200. // Texture alignment.
  201. void GetCenter(Vector& Center);
  202. FaceOrientation_t GetOrientation(void) const;
  203. void RotateTextureAxes(float fDegrees);
  204. void InitializeTextureAxes(TextureAlignment_t eAlignment, DWORD dwFlags);
  205. void JustifyTexture(TextureJustification_t eJustification);
  206. void JustifyTextureUsingExtents(TextureJustification_t eJustification, Extents_t Extents);
  207. void GetFaceBounds(Vector& pfMins, Vector& pfMaxs) const;
  208. void GetFaceExtents(Extents_t Extents) const;
  209. void GetTextureExtents(Extents_t Extents, Vector2D & TopLeft, Vector2D & BottomRight) const;
  210. int GetTextureAlignment(void) const;
  211. void GetFaceTextureExtents(Vector2D & TopLeft, Vector2D & BottomRight) const;
  212. void CalcTextureCoordAtPoint( const Vector& pt, Vector2D & texCoord );
  213. void CalcLightmapCoordAtPoint( const Vector& pt, Vector2D & lightCoord );
  214. // Returns the max lightmap size for this face
  215. int MaxLightmapSize() const;
  216. void NormalizeTextureShifts(void);
  217. BOOL IsTextureAxisValid(void) const;
  218. inline void SetCordonFace( bool bCordonFace );
  219. inline bool IsCordonFace() const;
  220. // Old code for setting up texture axes. Needed for backwards compatibility.
  221. void InitializeQuakeStyleTextureAxes(Vector4D& UAxis, Vector4D& VAxis);
  222. void CreateFace(Vector *pPoints, int nPoints, bool bIsCordonFace = false);
  223. void CreateFace(winding_t *w, int nFlags = 0);
  224. CMapFace *CopyFrom(const CMapFace *pFrom, DWORD dwFlags = COPY_FACE_POINTS, bool bUpdateDependencies = true );
  225. size_t AllocatePoints(int nPoints);
  226. void OnUndoRedo();
  227. void CalcPlane(void);
  228. void CalcPlaneFromFacePoints(void);
  229. void CalcTextureCoords();
  230. void OffsetTexture(const Vector &Delta);
  231. void SetTextureCoords(int nPoint, float u, float v);
  232. struct TangentSpaceAxes_t
  233. {
  234. Vector tangent;
  235. Vector binormal;
  236. };
  237. void CalcTangentSpaceAxes( void );
  238. bool AllocTangentSpaceAxes( int count );
  239. void FreeTangentSpaceAxes( void );
  240. void Render2D(CRender2D *pRender);
  241. void Render3D(CRender3D *pRender);
  242. void Render3DGrid(CRender3D *pRender);
  243. void RenderVertices(CRender *pRender);
  244. void OnAddToWorld(CMapWorld *pWorld);
  245. void OnRemoveFromWorld(void);
  246. static void SetShowSelection(bool bShowSelection);
  247. inline void SetRenderAlpha(unsigned char uchAlpha) { m_uchAlpha = uchAlpha; } // HACK: should be in CMapAtom
  248. inline void GetFaceNormal( Vector& normal );
  249. bool TraceLine(Vector &HitPos, Vector &HitNormal, Vector const &Start, Vector const &End);
  250. bool TraceLineInside( Vector &HitPos, Vector &HitNormal, Vector const &Start, Vector const &End, bool bNoDisp = false );
  251. inline void SetDisp( EditDispHandle_t handle, bool bDestroyPrevious = true );
  252. inline EditDispHandle_t GetDisp( void );
  253. inline bool HasDisp( void ) const;
  254. bool ShouldRenderLast();
  255. void GetDownVector( int index, Vector& downVect );
  256. bool GetRender2DBox( Vector& boundMin, Vector& boundMax );
  257. bool GetCullBox( Vector& boundMin, Vector& boundMax );
  258. size_t GetDataSize( void );
  259. inline int GetFaceID(void);
  260. inline void SetFaceID(int nFaceID);
  261. // Smoothing group.
  262. int SmoothingGroupCount( void );
  263. void AddSmoothingGroup( int iGroup );
  264. void RemoveSmoothingGroup( int iGroup );
  265. bool InSmoothingGroup( int iGroup );
  266. // Indicates this guy should be unlit
  267. void RenderUnlit( bool enable );
  268. // (begin serialized information
  269. TEXTURE texture; // Texture info.
  270. Vector *Points; // Array of face points, dynamically allocated.
  271. int nPoints; // The number of points in the array.
  272. // end serialized information)
  273. PLANE plane;
  274. int m_nFaceFlags; // FACE_FLAGS_xx
  275. void DoTransform(const VMatrix &matrix);
  276. virtual void AddShadowingTriangles( CUtlVector<Vector> &tri_list );
  277. DetailObjects *m_pDetailObjects;
  278. protected:
  279. void ComputeColor( CRender3D* pRender, bool bRenderAsSelected, SelectionState_t faceSelectionState,
  280. bool ignoreLighting, Color &pColor );
  281. void DrawFace( Color &pColor, EditorRenderMode_t mode );
  282. void RenderGridIfCloseEnough( CRender3D* pRender );
  283. void RenderTextureAxes( CRender3D* pRender );
  284. // Adds a face's vertices to the meshbuilder
  285. void AddFaceVertices( CMeshBuilder &builder, CRender3D* pRender, bool bRenderSelected, SelectionState_t faceSelectionState );
  286. // render texture axes
  287. static void RenderTextureAxes( CRender3D* pRender, int nCount, CMapFace **ppFaces );
  288. static void RenderGridsIfCloseEnough( CRender3D* pRender, int nCount, CMapFace **ppFaces );
  289. static void Render3DGrids( CRender3D* pRender, int nCount, CMapFace **ppFaces );
  290. static void RenderWireframeFaces( CRender3D* pRender, int nCount, MapFaceRender_t **ppFaces );
  291. static void RenderFacesBatch( CMeshBuilder &MeshBuilder, IMesh* pMesh, CRender3D* pRender, MapFaceRender_t **ppFaces, int nFaceCount, int nVertexCount, int nIndexCount, bool bWireframe );
  292. static void RenderFaces( CRender3D* pRender, int nCount, MapFaceRender_t **ppFaces );
  293. void RenderFace3D( CRender3D* pRender, EditorRenderMode_t renderMode, bool renderSelected, SelectionState_t faceSelectionState );
  294. //
  295. // Serialization (chunk handlers).
  296. //
  297. static ChunkFileResult_t LoadDispInfoCallback(CChunkFile *pFile, CMapFace *pFace);
  298. static ChunkFileResult_t LoadKeyCallback(const char *szKey, const char *szValue, LoadFace_t *pLoadFace);
  299. unsigned char m_uchAlpha; // HACK: should be in CMapAtom
  300. int m_nFaceID; // The unique ID of this face in the world.
  301. IEditorTexture *m_pTexture; // Texture that is applied to this face.
  302. static IEditorTexture *m_pLightmapGrid; // Lightmap grid texture for use in viewing lightmap scales.
  303. EditDispHandle_t m_DispHandle; // Displacement map applied to this face, NULL if none.
  304. static bool m_bShowFaceSelection; // Whether to render faces with a special color when they are selected.
  305. Vector2D *m_pTextureCoords; // An array of texture coordinates, one per face point.
  306. Vector2D *m_pLightmapCoords; // An array of lightmap coordinates, one per face point.
  307. bool m_bIsCordonFace : 1;
  308. // should this be affected by lighting?
  309. bool m_bIgnoreLighting : 1;
  310. TangentSpaceAxes_t *m_pTangentAxes;
  311. unsigned int m_fSmoothingGroups; // 32-bits representing 32 smoothing groups
  312. void UpdateFaceFlags( void ); // sniff face flags from texture
  313. };
  314. //-----------------------------------------------------------------------------
  315. // Purpose: Returns the unique ID of this face.
  316. //-----------------------------------------------------------------------------
  317. inline int CMapFace::GetFaceID(void)
  318. {
  319. return(m_nFaceID);
  320. }
  321. //-----------------------------------------------------------------------------
  322. // Purpose:
  323. // Input : TexCoord -
  324. // nTexCoord -
  325. //-----------------------------------------------------------------------------
  326. inline void CMapFace::GetLightmapCoord( Vector2D& LightmapCoord, int nIndex )
  327. {
  328. Assert( nIndex < nPoints );
  329. LightmapCoord[0] = m_pLightmapCoords[nIndex][0];
  330. LightmapCoord[1] = m_pLightmapCoords[nIndex][1];
  331. }
  332. //-----------------------------------------------------------------------------
  333. // Purpose:
  334. // Input : &LightmapCoord -
  335. // nIndex -
  336. // Output : inline void
  337. //-----------------------------------------------------------------------------
  338. inline void CMapFace::SetLightmapCoord( const Vector2D &LightmapCoord, int nIndex )
  339. {
  340. Assert( nIndex < nPoints );
  341. m_pLightmapCoords[nIndex][0] = LightmapCoord[0];
  342. m_pLightmapCoords[nIndex][1] = LightmapCoord[1];
  343. }
  344. //-----------------------------------------------------------------------------
  345. // Purpose:
  346. // Input : TexCoord -
  347. // nTexCoord -
  348. //-----------------------------------------------------------------------------
  349. inline void CMapFace::GetTexCoord( Vector2D& TexCoord, int nTexCoord )
  350. {
  351. Assert( nTexCoord < nPoints );
  352. TexCoord[0] = m_pTextureCoords[nTexCoord][0];
  353. TexCoord[1] = m_pTextureCoords[nTexCoord][1];
  354. }
  355. //-----------------------------------------------------------------------------
  356. // Purpose: Returns a pointer to the texture that is applied to this face, NULL if none.
  357. //-----------------------------------------------------------------------------
  358. inline IEditorTexture *CMapFace::GetTexture(void) const
  359. {
  360. return(m_pTexture);
  361. }
  362. //-----------------------------------------------------------------------------
  363. // Purpose: Returns the number of vertices that define this face.
  364. //-----------------------------------------------------------------------------
  365. inline int CMapFace::GetPointCount(void)
  366. {
  367. return(nPoints);
  368. }
  369. //-----------------------------------------------------------------------------
  370. // Purpose: Retrieves a point on this face by its index.
  371. // Input : Point - Receives point coordinates.
  372. // nPoint - Index of point to retrieve.
  373. //-----------------------------------------------------------------------------
  374. inline void CMapFace::GetPoint(Vector& Point, int nPoint)
  375. {
  376. Assert(nPoint < nPoints);
  377. Point = Points[nPoint];
  378. }
  379. //-----------------------------------------------------------------------------
  380. //-----------------------------------------------------------------------------
  381. inline void CMapFace::GetFaceNormal( Vector& normal )
  382. {
  383. normal = plane.normal;
  384. }
  385. //-----------------------------------------------------------------------------
  386. // Purpose: Sets the unique ID of this face.
  387. //-----------------------------------------------------------------------------
  388. inline void CMapFace::SetFaceID(int nID)
  389. {
  390. m_nFaceID = nID;
  391. }
  392. //-----------------------------------------------------------------------------
  393. // Purpose: Attaches a displacement surface to this face.
  394. // Input : handle - Displacement surface handle of surface attached to this face
  395. //-----------------------------------------------------------------------------
  396. inline void CMapFace::SetDisp( EditDispHandle_t handle, bool bDestroyPrevious )
  397. {
  398. if ( ( m_DispHandle != EDITDISPHANDLE_INVALID ) && bDestroyPrevious )
  399. {
  400. // destroy old handle
  401. EditDispMgr()->Destroy( m_DispHandle );
  402. }
  403. Assert( ( handle == EDITDISPHANDLE_INVALID ) || ( EditDispMgr()->GetDisp( handle ) != NULL ) );
  404. m_DispHandle = handle;
  405. }
  406. //-----------------------------------------------------------------------------
  407. // Purpose: Returns the displacement surface applied to this face,
  408. // DISPHANDLE_INVALID if none.
  409. //-----------------------------------------------------------------------------
  410. inline EditDispHandle_t CMapFace::GetDisp( void )
  411. {
  412. return m_DispHandle;
  413. }
  414. //-----------------------------------------------------------------------------
  415. // Purpose: Returns true if this face has a displacement surface, false if not.
  416. //-----------------------------------------------------------------------------
  417. inline bool CMapFace::HasDisp( void ) const
  418. {
  419. return ( m_DispHandle != EDITDISPHANDLE_INVALID );
  420. }
  421. //-----------------------------------------------------------------------------
  422. // Whether this face belongs to a cordon brush.
  423. //-----------------------------------------------------------------------------
  424. inline void CMapFace::SetCordonFace( bool bCordonFace )
  425. {
  426. m_bIsCordonFace = bCordonFace;
  427. }
  428. inline bool CMapFace::IsCordonFace() const
  429. {
  430. return m_bIsCordonFace;
  431. }
  432. //-----------------------------------------------------------------------------
  433. // Defines a container class for a list of face pointers.
  434. //-----------------------------------------------------------------------------
  435. class CMapFaceList : public CUtlVector<CMapFace *>
  436. {
  437. public:
  438. inline CMapFaceList(void) {}
  439. inline CMapFaceList(CMapFaceList const &other);
  440. inline CMapFaceList &CMapFaceList::operator =(CMapFaceList const &other);
  441. inline int FindFaceID(int nFaceID);
  442. void Intersect(CMapFaceList &IntersectWith, CMapFaceList &In, CMapFaceList &Out);
  443. };
  444. //-----------------------------------------------------------------------------
  445. // Purpose: Copy constructor.
  446. //-----------------------------------------------------------------------------
  447. CMapFaceList::CMapFaceList(CMapFaceList const &other)
  448. {
  449. *this = other;
  450. }
  451. //-----------------------------------------------------------------------------
  452. // Purpose: Assignment operator for copying face lists.
  453. // Input : other -
  454. //-----------------------------------------------------------------------------
  455. CMapFaceList &CMapFaceList::operator =(CMapFaceList const &other)
  456. {
  457. AddVectorToTail(other);
  458. return *this;
  459. }
  460. //-----------------------------------------------------------------------------
  461. // Purpose: Searches the list for a face with the given ID.
  462. // Input : nFaceID - Numeric face ID to search for.
  463. // Output : Index of found element, -1 if none.
  464. //-----------------------------------------------------------------------------
  465. int CMapFaceList::FindFaceID(int nFaceID)
  466. {
  467. for (int i = 0; i < Count(); i++)
  468. {
  469. if ((Element(i) != NULL) && (Element(i)->GetFaceID() == nFaceID))
  470. {
  471. return(i);
  472. }
  473. }
  474. return(-1);
  475. }
  476. //-----------------------------------------------------------------------------
  477. // Defines a container class for a list of face IDs.
  478. //-----------------------------------------------------------------------------
  479. class CMapFaceIDList : public CUtlVector<int>
  480. {
  481. public:
  482. inline CMapFaceIDList(void) {}
  483. inline CMapFaceIDList(CMapFaceIDList const &other);
  484. inline CMapFaceIDList &CMapFaceIDList::operator =(CMapFaceIDList const &other);
  485. void Intersect(CMapFaceIDList &IntersectWith, CMapFaceIDList &In, CMapFaceIDList &Out);
  486. };
  487. //-----------------------------------------------------------------------------
  488. // Purpose: Copy constructor.
  489. //-----------------------------------------------------------------------------
  490. CMapFaceIDList::CMapFaceIDList(CMapFaceIDList const &other)
  491. {
  492. *this = other;
  493. }
  494. //-----------------------------------------------------------------------------
  495. // Purpose: Assignment operator for copying face ID lists.
  496. // Input : other -
  497. //-----------------------------------------------------------------------------
  498. CMapFaceIDList &CMapFaceIDList::operator =(CMapFaceIDList const &other)
  499. {
  500. AddVectorToTail(other);
  501. return *this;
  502. }
  503. #endif // MAPFACE_H