Brush.h 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. /* Copyright (c) 2002-2012 Croteam Ltd.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of version 2 of the GNU General Public License as published by
  4. the Free Software Foundation
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along
  10. with this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
  12. #ifndef SE_INCL_BRUSH_H
  13. #define SE_INCL_BRUSH_H
  14. #ifdef PRAGMA_ONCE
  15. #pragma once
  16. #endif
  17. #include <Engine/Base/Lists.h>
  18. #include <Engine/Base/Relations.h>
  19. #include <Engine/Math/Vector.h>
  20. #include <Engine/Math/Plane.h>
  21. #include <Engine/Math/TextureMapping.h>
  22. #include <Engine/Math/AABBox.h>
  23. #include <Engine/Math/Projection.h>
  24. #include <Engine/Graphics/Texture.h>
  25. #include <Engine/Graphics/ShadowMap.h>
  26. #include <Engine/Brushes/BrushBase.h>
  27. #include <Engine/Templates/DynamicArray.h>
  28. #include <Engine/Templates/StaticArray.h>
  29. #include <Engine/Templates/Selection.h>
  30. // a vertex in brush
  31. #define BVXF_DRAWNINWIREFRAME (1L<<0) // vertex is already drawn in wireframe
  32. #define BVXF_SELECTED (1L<<1) // vertex is selected
  33. class ENGINE_API CBrushVertex {
  34. public:
  35. class CWorkingVertex *bvx_pwvxWorking; // used for rendering and ray casting
  36. FLOAT3D bvx_vAbsolute;
  37. FLOAT3D bvx_vRelative; // relative coordinates used for collision
  38. DOUBLE3D bvx_vdPreciseRelative; // precise relative coordinates used for editing
  39. DOUBLE3D *bvx_pvdPreciseAbsolute; // precise vertex coordinates in absolute space
  40. ULONG bvx_ulFlags; // flags
  41. CBrushSector *bvx_pbscSector; // back-pointer to sector
  42. /* Default constructor. */
  43. inline CBrushVertex(void) : bvx_pwvxWorking(NULL), bvx_ulFlags(0) {};
  44. /* Clear the object. */
  45. inline void Clear(void) {};
  46. // vertices may be selected
  47. IMPLEMENT_SELECTING(bvx_ulFlags)
  48. // set new absolute position for the vertex
  49. void SetAbsolutePosition(const DOUBLE3D &vAbsolute);
  50. // get amount of memory used by this object
  51. inline SLONG GetUsedMemory(void) { return sizeof(CBrushVertex); };
  52. };
  53. // selection of brush vertices
  54. typedef CSelection<CBrushVertex, BVXF_SELECTED> CBrushVertexSelection;
  55. // a plane in brush
  56. class ENGINE_API CBrushPlane {
  57. public:
  58. class CWorkingPlane *bpl_pwplWorking; // use for rendering and ray casting
  59. FLOATplane3D bpl_plAbsolute;
  60. FLOATplane3D bpl_plRelative; // relative coordinates used for collision
  61. DOUBLEplane3D *bpl_ppldPreciseAbsolute; // precise relative plane coordinates in absolute space
  62. DOUBLEplane3D bpl_pldPreciseRelative; // precise coordinates used for editing
  63. INDEX bpl_iPlaneMajorAxis1; // major axes of the plane in apsolute space
  64. INDEX bpl_iPlaneMajorAxis2;
  65. /* Default constructor. */
  66. inline CBrushPlane(void) : bpl_pwplWorking(NULL) {};
  67. /* Clear the object. */
  68. inline void Clear(void) {};
  69. // get amount of memory used by this object
  70. inline SLONG GetUsedMemory(void) { return sizeof(CBrushPlane); };
  71. };
  72. // an edge in brush
  73. class ENGINE_API CBrushEdge {
  74. public:
  75. CBrushVertex *bed_pbvxVertex0; // start vertex
  76. CBrushVertex *bed_pbvxVertex1; // end vertex
  77. CWorkingEdge *bed_pwedWorking; // pointer to screen edge if active in rendering
  78. /* Default constructor. */
  79. inline CBrushEdge(void) : bed_pwedWorking(NULL) {};
  80. /* Constructor with two vertices. */
  81. inline CBrushEdge(CBrushVertex *pbvx0, CBrushVertex *pbvx1)
  82. : bed_pwedWorking(NULL), bed_pbvxVertex0(pbvx0), bed_pbvxVertex1(pbvx1) {};
  83. /* Clear the object. */
  84. inline void Clear(void) {};
  85. /* Test if this edge touches another one. */
  86. BOOL TouchesInSameSector(CBrushEdge &bedOther);
  87. BOOL TouchesInAnySector(CBrushEdge &bedOther);
  88. // get amount of memory used by this object
  89. inline SLONG GetUsedMemory(void) { return sizeof(CBrushEdge); };
  90. };
  91. // a reference to edge used in brush polygon
  92. class ENGINE_API CBrushPolygonEdge {
  93. public:
  94. CBrushEdge *bpe_pbedEdge; // pointer to the edge
  95. BOOL bpe_bReverse; // true if the vertex0 and vertex1 must be swapped
  96. /* Clear the object. */
  97. inline void Clear(void) {};
  98. /* Get coordinates of the end vertices. */
  99. inline void GetVertices(CBrushVertex *&pbvx0, CBrushVertex *&pbvx1) {
  100. if (bpe_bReverse) {
  101. pbvx0 = bpe_pbedEdge->bed_pbvxVertex1;
  102. pbvx1 = bpe_pbedEdge->bed_pbvxVertex0;
  103. } else {
  104. pbvx0 = bpe_pbedEdge->bed_pbvxVertex0;
  105. pbvx1 = bpe_pbedEdge->bed_pbvxVertex1;
  106. }
  107. }
  108. inline void GetVertexCoordinatesAbsolute(FLOAT3D &v0, FLOAT3D &v1) {
  109. if (bpe_bReverse) {
  110. v0 = bpe_pbedEdge->bed_pbvxVertex1->bvx_vAbsolute;
  111. v1 = bpe_pbedEdge->bed_pbvxVertex0->bvx_vAbsolute;
  112. } else {
  113. v0 = bpe_pbedEdge->bed_pbvxVertex0->bvx_vAbsolute;
  114. v1 = bpe_pbedEdge->bed_pbvxVertex1->bvx_vAbsolute;
  115. }
  116. };
  117. inline void GetVertexCoordinatesRelative(FLOAT3D &v0, FLOAT3D &v1) {
  118. if (bpe_bReverse) {
  119. v0 = bpe_pbedEdge->bed_pbvxVertex1->bvx_vRelative;
  120. v1 = bpe_pbedEdge->bed_pbvxVertex0->bvx_vRelative;
  121. } else {
  122. v0 = bpe_pbedEdge->bed_pbvxVertex0->bvx_vRelative;
  123. v1 = bpe_pbedEdge->bed_pbvxVertex1->bvx_vRelative;
  124. }
  125. };
  126. inline void GetVertexCoordinatesPreciseRelative(DOUBLE3D &v0, DOUBLE3D &v1) {
  127. if (bpe_bReverse) {
  128. v0 = bpe_pbedEdge->bed_pbvxVertex1->bvx_vdPreciseRelative;
  129. v1 = bpe_pbedEdge->bed_pbvxVertex0->bvx_vdPreciseRelative;
  130. } else {
  131. v0 = bpe_pbedEdge->bed_pbvxVertex0->bvx_vdPreciseRelative;
  132. v1 = bpe_pbedEdge->bed_pbvxVertex1->bvx_vdPreciseRelative;
  133. }
  134. };
  135. inline void GetVertexCoordinatesPreciseAbsolute(DOUBLE3D &v0, DOUBLE3D &v1) {
  136. if (bpe_bReverse) {
  137. v0 = *bpe_pbedEdge->bed_pbvxVertex1->bvx_pvdPreciseAbsolute;
  138. v1 = *bpe_pbedEdge->bed_pbvxVertex0->bvx_pvdPreciseAbsolute;
  139. } else {
  140. v0 = *bpe_pbedEdge->bed_pbvxVertex0->bvx_pvdPreciseAbsolute;
  141. v1 = *bpe_pbedEdge->bed_pbvxVertex1->bvx_pvdPreciseAbsolute;
  142. }
  143. };
  144. };
  145. // one layer on brush shadow map (cross link between brush shadow map and light source)
  146. #define BSLF_CALCULATED (1L<<0)
  147. #define BSLF_RECTANGLE (1L<<1) // new version of layer with only influenced rectangle
  148. #define BSLF_ALLDARK (1L<<2) // polygon is not lighted by the light at all
  149. #define BSLF_ALLLIGHT (1L<<3) // whole polygon is lighted by the light (there are no shadows)
  150. class ENGINE_API CBrushShadowLayer {
  151. public:
  152. // implementation:
  153. ULONG bsl_ulFlags; // flags
  154. CListNode bsl_lnInShadowMap; // node in list of all layers of a shadow map
  155. CListNode bsl_lnInLightSource; // node in list of all layers of a light source
  156. class CBrushShadowMap *bsl_pbsmShadowMap; // the shadow map
  157. class CLightSource *bsl_plsLightSource; // the light source
  158. PIX bsl_pixMinU; // rectangle where the light influences the polygon
  159. PIX bsl_pixMinV;
  160. PIX bsl_pixSizeU;
  161. PIX bsl_pixSizeV;
  162. SLONG bsl_slSizeInPixels; // size of bit mask in pixels (with all mip-maps)
  163. UBYTE *bsl_pubLayer; // bit mask set where the polygon is lighted
  164. COLOR bsl_colLastAnim; // last animating color cached
  165. // interface:
  166. CBrushShadowLayer();
  167. ~CBrushShadowLayer(void);
  168. // discard shadows but keep the layer
  169. void DiscardShadows(void);
  170. // get shadow/light percentage at given coordinates in shadow layer
  171. FLOAT GetLightStrength(PIX pixU, PIX pixV, FLOAT fLt, FLOAT fUp);
  172. // get amount of memory used by this object
  173. SLONG GetUsedMemory(void);
  174. };
  175. class ENGINE_API CBrushShadowMap : public CShadowMap {
  176. public:
  177. // implementation:
  178. // for linking in list of all shadow maps that need calculation
  179. CListNode bsm_lnInUncalculatedShadowMaps;
  180. CListHead bsm_lhLayers; // list of all layers of this shadow map
  181. UBYTE *bsm_pubPolygonMask; // bit packed polygon mask
  182. // get pointer to embedding brush polygon
  183. inline CBrushPolygon *GetBrushPolygon(void);
  184. // overrides from CShadowMap:
  185. // mix all layers into cached shadow map
  186. virtual void MixLayers(INDEX iFirstMip, INDEX iLastMip, BOOL bDynamic=FALSE); // iFirstMip<iLastMip
  187. // read/write layers from/to stream
  188. virtual void ReadLayers_t( CTStream *pstrm); // throw char *
  189. virtual void WriteLayers_t( CTStream *pstrm); // throw char *
  190. // check if all layers are up to date
  191. virtual void CheckLayersUpToDate(void);
  192. // test if there is any dynamic layer
  193. virtual BOOL HasDynamicLayers(void);
  194. // returns TRUE if shadowmap is all flat along with colFlat variable set to that color
  195. virtual BOOL IsShadowFlat( COLOR &colFlat);
  196. // calculate the rectangle where a light influences the shadow map
  197. void FindLightRectangle(CLightSource &ls, class CLightRectangle &lr);
  198. // queue the shadow map for calculation
  199. void QueueForCalculation(void);
  200. // interface:
  201. // constructor
  202. CBrushShadowMap(void);
  203. // destructor
  204. ~CBrushShadowMap(void);
  205. // discard all layers on this shadow map
  206. void DiscardAllLayers(void);
  207. // discard shadows on all layers on this shadow map
  208. void DiscardShadows(void);
  209. // remove shadow layers without valid light source
  210. void RemoveDummyLayers(void);
  211. // get number of shadow layers
  212. INDEX GetShadowLayersCount(void) { return bsm_lhLayers.Count(); };
  213. // get amount of memory used by this object
  214. SLONG GetUsedMemory(void);
  215. };
  216. // one texture on a brush polygon
  217. #define BPTF_CLAMPU (1U<<0) // clamp u coordinate in texture
  218. #define BPTF_CLAMPV (1U<<1) // clamp v coordinate in texture
  219. #define BPTF_DISCARDABLE (1U<<2) // texture doesn't have to be drawn
  220. #define BPTF_AFTERSHADOW (1U<<3) // texture is to be applied after shadow
  221. #define BPTF_REFLECTION (1U<<4) // texture will be reflection-mapped
  222. // first few blending type must be these:
  223. #define BPT_BLEND_OPAQUE 0
  224. #define BPT_BLEND_SHADE 1
  225. #define BPT_BLEND_BLEND 2
  226. #define BPT_BLEND_ADD 3
  227. class ENGINE_API CBrushPolygonTexture {
  228. public:
  229. CTextureObject bpt_toTexture; // texture object
  230. CMappingDefinition bpt_mdMapping; // mapping of texture on polygon
  231. union {
  232. struct {
  233. UBYTE bpt_ubScroll; // texture scroll
  234. UBYTE bpt_ubBlend; // type of texture blending used
  235. UBYTE bpt_ubFlags; // additional flags
  236. UBYTE bpt_ubDummy; // unused (alignment)
  237. COLOR bpt_colColor; // defines constant color and alpha of polygon
  238. } s;
  239. UBYTE bpt_auProperties[8];
  240. };
  241. CBrushPolygonTexture(void)
  242. {
  243. s.bpt_ubScroll = 0;
  244. s.bpt_ubBlend = 0;
  245. s.bpt_ubFlags = BPTF_DISCARDABLE;
  246. s.bpt_ubDummy = 0;
  247. s.bpt_colColor = 0xFFFFFFFF;
  248. }
  249. /* Copy polygon properties */
  250. CBrushPolygonTexture &CopyTextureProperties(CBrushPolygonTexture &bptOther, BOOL bCopyMapping) {
  251. bpt_toTexture.SetData( bptOther.bpt_toTexture.GetData());
  252. s.bpt_ubScroll = bptOther.s.bpt_ubScroll;
  253. s.bpt_ubBlend = bptOther.s.bpt_ubBlend;
  254. s.bpt_ubFlags = bptOther.s.bpt_ubFlags;
  255. s.bpt_ubDummy = bptOther.s.bpt_ubDummy;
  256. s.bpt_colColor = bptOther.s.bpt_colColor;
  257. if( bCopyMapping) bpt_mdMapping = bptOther.bpt_mdMapping;
  258. return *this;
  259. };
  260. void Clear(void) {
  261. bpt_toTexture.SetData(NULL);
  262. };
  263. // read/write to stream
  264. void Read_t( CTStream &strm); // throw char *
  265. void Write_t( CTStream &strm); // throw char *
  266. // get amount of memory used by this object
  267. inline SLONG GetUsedMemory(void) { return sizeof(CBrushPolygonTexture); };
  268. };
  269. // a polygon in brush
  270. // Flags
  271. // flags 0-2 are used by CObjectPolygon, flags 3-31 are used by CBrushPolygon
  272. // OPOF_PORTAL // set if the polygon is a portal - used for CSG in CObject3D
  273. #define BPOF_DOUBLESIDED (1UL<< 3) // polygon is renderable from both sides
  274. #define BPOF_SHOOTTHRU (1UL<< 4) // physical ray-casts can pass through the polygon, even if it is not passable
  275. #define BPOF_TRANSPARENT (1UL<< 5) // render with alpha-testing and write z-buffer
  276. #define BPOF_RENDERASPORTAL (1UL<< 6) // internal used in rendering
  277. #define BPOF_STAIRS (1UL<< 7) // polygon is part of a staircase
  278. #define BPOF_SELECTED (1UL<< 8) // set if the polygon is selected
  279. #define BPOF_SELECTEDFORCSG (1UL<< 9) // set if the polygon is selected for CSG
  280. #define BPOF_WASPORTAL (1UL<<10) // set if it was portal before CSG
  281. #define BPOF_PASSABLE (1UL<<11) // set if not a physical barrier
  282. #define BPOF_DOESNOTCASTSHADOW (1UL<<12) // set to make a wall passable for light beams
  283. #define BPOF_WASBRUSHPOLYGON (1UL<<13) // this polygon was brush polygon before (not just created)
  284. #define BPOF_FULLBRIGHT (1UL<<14) // set to make a wall full-bright
  285. #define BPOF_TRANSLUCENT (1UL<<15) // set for translucent portals
  286. #define BPOF_HASDIRECTIONALLIGHT (1UL<<16) // set if polygon accepts directional lights
  287. #define BPOF_INVISIBLE (1UL<<17) // set if the polygon is ignored during rendering
  288. #define BPOF_DARKCORNERS (1UL<<18) // polygons will have dark corners (here was gouraud!!!!)
  289. #define BPOF_RENDERTRANSLUCENT (1UL<<19) // internal used in rendering
  290. #define BPOF_NOPLANEDIFFUSION (1UL<<20) // plane normal is ignored when shading
  291. #define BPOF_DETAILPOLYGON (1UL<<21) // not used for visibility determination
  292. #define BPOF_PORTAL (1UL<<22) // should behave like a portal (not same as OPOF_PORTAL)
  293. #define BPOF_ACCURATESHADOWS (1UL<<23) // shadows are calculated for each mip-map independently
  294. #define BPOF_HASDIRECTIONALAMBIENT (1UL<<24) // set if polygon accepts directional ambient
  295. #define BPOF_MARKEDLAYER (1UL<<25) // used in FindShadowLayers()
  296. #define BPOF_DYNAMICLIGHTSONLY (1UL<<26) // only dynamic lights used in shadow map
  297. #define BPOF_DOESNOTRECEIVESHADOW (1UL<<27) // has lightmap, but no shadows on it
  298. #define BPOF_NODYNAMICLIGHTS (1UL<<28) // dynamic lights do not influence it
  299. #define BPOF_INVALIDTRIANGLES (1UL<<29) // polygons could not be triangulated well
  300. #define BPOF_OCCLUDER (1UL<<30) // occluder polygon
  301. #define BPOF_MARKED_FOR_USE (1UL<<31) // used in triangularization when polygon vertex is moved
  302. #define BPOF_MASK_FOR_COPYING \
  303. (BPOF_PASSABLE|BPOF_DOESNOTCASTSHADOW|BPOF_FULLBRIGHT|BPOF_TRANSLUCENT|BPOF_TRANSPARENT|\
  304. BPOF_HASDIRECTIONALLIGHT|BPOF_INVISIBLE|BPOF_NOPLANEDIFFUSION|\
  305. BPOF_DETAILPOLYGON|BPOF_PORTAL|BPOF_ACCURATESHADOWS|BPOF_HASDIRECTIONALAMBIENT|\
  306. BPOF_DYNAMICLIGHTSONLY|BPOF_DOESNOTRECEIVESHADOW|BPOF_NODYNAMICLIGHTS|BPOF_DARKCORNERS|BPOF_OCCLUDER)
  307. // properties that are retained in conversions to/from CObjectPolygon
  308. struct CBrushPolygonProperties {
  309. UBYTE bpp_ubSurfaceType; // surface type on this polygon
  310. UBYTE bpp_ubIlluminationType; // type of illuminating polygon, 0 if not illuminating
  311. UBYTE bpp_ubShadowBlend; // type of texture blending used for shadow map
  312. UBYTE bpp_ubMirrorType; // mirror or warp
  313. UBYTE bpp_ubGradientType; // for gradiental shadows
  314. SBYTE bpp_sbShadowClusterSize; // size of shadow clusters (size=(1<<ub)*0.5m)
  315. UWORD bpp_uwPretenderDistance; // distance for pretender switching [m]
  316. /* Default constructor. */
  317. CBrushPolygonProperties(void) { memset(this, 0, sizeof(*this)); };
  318. };
  319. class ENGINE_API CBrushPolygon {
  320. public:
  321. // implementation:
  322. /* Calculate area of the polygon. */
  323. DOUBLE CalculateArea(void);
  324. /* Calculate bounding box of this polygon. */
  325. void CalculateBoundingBox(void);
  326. /* Create a BSP polygon from this polygon. */
  327. void CreateBSPPolygon(BSPPolygon<DOUBLE, 3> &bspo);
  328. void CreateBSPPolygonNonPrecise(BSPPolygon<DOUBLE, 3> &bspo);
  329. /* Create shadow map for the polygon. */
  330. void MakeShadowMap(CWorld *pwoWorld, BOOL bDoDirectionalLights);
  331. /* Initialize shadow map for the polygon. */
  332. void InitializeShadowMap(void);
  333. // discard all cached shading info for models
  334. void DiscardShadingInfos(void);
  335. // move edges from another polygon into this one
  336. void MovePolygonEdges(CBrushPolygon &bpoSource);
  337. /* Test if this polygon touches another one. */
  338. BOOL TouchesInSameSector(CBrushPolygon &bpoOther);
  339. BOOL TouchesInAnySector(CBrushPolygon &bpoOther);
  340. // make triangular representation of the polygon
  341. void Triangulate(void);
  342. public:
  343. // interface:
  344. CBrushPlane *bpo_pbplPlane; // plane of this polygon
  345. CStaticArray<CBrushPolygonEdge> bpo_abpePolygonEdges; // edges in this polygon
  346. CStaticArray<CBrushVertex *> bpo_apbvxTriangleVertices; // triangle vertices
  347. CStaticArray<INDEX> bpo_aiTriangleElements; // element indices inside vertex arrays
  348. CBrushPolygonTexture bpo_abptTextures[3]; // texture on this polygon
  349. COLOR bpo_colColor; // color of this polygon
  350. ULONG bpo_ulFlags; // flags
  351. COLOR bpo_colShadow; // color of shadow on this polygon
  352. CBrushShadowMap bpo_smShadowMap; // shadow map of this polygon
  353. CMappingDefinition bpo_mdShadow; // mapping of shadow on polygon
  354. CBrushPolygonProperties bpo_bppProperties; // additional properties
  355. class CScreenPolygon *bpo_pspoScreenPolygon; // used in rendering
  356. FLOATaabbox3D bpo_boxBoundingBox; // bounding box
  357. CBrushSector *bpo_pbscSector; // sector of this polygon
  358. CRelationSrc bpo_rsOtherSideSectors; // relation to sectors on other side of portal
  359. CListHead bpo_lhShadingInfos; // for linking shading infos of entities
  360. INDEX bpo_iInWorld; // index of the polygon in entire world
  361. /* Default constructor. */
  362. inline CBrushPolygon(void) : bpo_ulFlags(0) {};
  363. /* Clear the object. */
  364. void Clear(void);
  365. /* Destructor. */
  366. inline ~CBrushPolygon(void) { Clear(); };
  367. CBrushPolygon &CopyPolygon(CBrushPolygon &bp);
  368. /* Copy polygon within same sector. */
  369. void CopyFromSameSector(CBrushPolygon &bpoOriginal);
  370. /* Copy polygon properties */
  371. CBrushPolygon &CopyProperties(CBrushPolygon &bpoOther, BOOL bCopyMapping = TRUE);
  372. /* Copy polygon properties without texture */
  373. CBrushPolygon &CopyPropertiesWithoutTexture(CBrushPolygon &bpoOther);
  374. /* Copy polygon's textures */
  375. CBrushPolygon &CopyTextures(CBrushPolygon &bpoOther);
  376. // polygons may be selected
  377. IMPLEMENT_SELECTING(bpo_ulFlags)
  378. /* Select group of adjacent polygons with same color. */
  379. void SelectSimilarByColor(CSelection<CBrushPolygon, BPOF_SELECTED> &selbpoSimilar);
  380. /* Select group of adjacent polygons with same texture. */
  381. void SelectSimilarByTexture(CSelection<CBrushPolygon, BPOF_SELECTED> &selbpoSimilar, INDEX iTexture);
  382. /* Select all polygons in sector with same texture. */
  383. void SelectByTextureInSector(CSelection<CBrushPolygon, BPOF_SELECTED> &selbpoSimilar, INDEX iTexture);
  384. /* Select all polygons in sector with same color. */
  385. void SelectByColorInSector(CSelection<CBrushPolygon, BPOF_SELECTED> &selbpoSimilar);
  386. /* Discard shadows on the polygon. */
  387. void DiscardShadows(void);
  388. // find minimum distance of a given point from the polygon edges
  389. FLOAT GetDistanceFromEdges(const FLOAT3D &v);
  390. // get amount of memory used by this object
  391. SLONG GetUsedMemory(void);
  392. };
  393. // get pointer to embedding brush polygon
  394. inline CBrushPolygon *CBrushShadowMap::GetBrushPolygon(void) {
  395. return (CBrushPolygon *) ((UBYTE*)this-offsetof(CBrushPolygon, bpo_smShadowMap));
  396. }
  397. // selection of brush polygons
  398. typedef CSelection<CBrushPolygon, BPOF_SELECTED> CBrushPolygonSelection;
  399. // selection of brush polygons used for CSG
  400. typedef CSelection<CBrushPolygon, BPOF_SELECTEDFORCSG> CBrushPolygonSelectionForCSG;
  401. // sector flags
  402. #define BSCF_SELECTED (1L<<0) // set if the sector is selected
  403. #define BSCF_HIDDEN (1L<<1) // set if the sector is hidden (for editing)
  404. #define BSCF_SELECTEDFORCSG (1L<<2) // set if the sector is selected for CSG
  405. #define BSCF_OPENSECTOR (1L<<3) // set if the sector polygons are facing outwards
  406. #define BSCF_NEARTESTED (1L<<4) // already tested for near polygon
  407. #define BSCF_INVISIBLE (1L<<5) // active, but not visible
  408. #define BSCF_RAYTESTED (1L<<6) // already tested by ray
  409. #define BSCF_NEEDSCLIPPING (1L<<7) // set if its polygons needs clipping
  410. #define BSCB_CONTENTTYPE 24 // upper 8 bits are used for sector content type
  411. #define BSCB_FORCETYPE 16 // next 8 bits are used for sector gravity type
  412. #define BSCB_FOGTYPE 12 // 4 bits for fog
  413. #define BSCB_HAZETYPE 8 // 4 bits for haze
  414. #define BSCB2_ENVIRONMENTTYPE 0 // 8 bits for environment sound effects (EAX and similar)
  415. #define BSCF2_VISIBILITYINCLUDE (1<<8) // toggle include/exclude for visibility (exclude is default)
  416. // vis flags
  417. #define VISM_INCLUDEEXCLUDE (0x0000FFFF) // for visibility include/exclude
  418. #define VISM_DONTCLASSIFY (0xFFFF0000) // to disable classification in certain sectors
  419. // NOTE on how visibility tweaks are implemented
  420. // - low 16 bits determine visibility from current sector
  421. // if BSCF2_VISIBILITYINCLUDE is on, entity is visible from sector only if EntityVisTweaks&SectorVisFlags&VISM_INCLUDEEXCLUDE
  422. // if BSCF2_VISIBILITYINCLUDE is off, entity is visible from sector only if !(EntityVisTweaks&SectorVisFlags&VISM_INCLUDEEXCLUDE)
  423. // - high 16 bits limit entity classification to sectors
  424. // if EntityVisTweaks&SectorVisFlags&VISM_DONTCLASSIFY, entity is treated as if not classified to that sector
  425. // temporary flags
  426. #define BSCTF_PRELOADEDBSP (1L<<0) // bsp is loaded, no need to calculate it
  427. #define BSCTF_PRELOADEDLINKS (1L<<1) // portallinks are loaded, no need to calculate them
  428. // a sector in brush
  429. class ENGINE_API CBrushSector {
  430. public:
  431. // implementation:
  432. /* Fill an object sector from a sector in brush. */
  433. void ToObjectSector(CObjectSector &osc);
  434. /* Fill a brush sector from a sector in object3d. */
  435. void FromObjectSector_t(CObjectSector &osc); // throw char *
  436. // recalculate planes for polygons from their vertices
  437. void MakePlanesFromVertices();
  438. // update changed sector's data after dragging vertices or importing
  439. void UpdateSector(void);
  440. /* Calculate volume of the sector. */
  441. DOUBLE CalculateVolume(void);
  442. // make triangular representation of the polygons in the sector
  443. void Triangulate(void);
  444. public:
  445. // implementation:
  446. CStaticArray<CBrushVertex> bsc_abvxVertices; // vertices
  447. CStaticArray<CBrushEdge> bsc_abedEdges; // edges
  448. CStaticArray<CBrushPlane> bsc_abplPlanes; // planes
  449. CStaticArray<CBrushPolygon> bsc_abpoPolygons; // polygons
  450. CStaticArray<CWorkingVertex> bsc_awvxVertices; // working vertices
  451. CStaticArray<CWorkingPlane> bsc_awplPlanes; // working planes
  452. CStaticArray<CWorkingEdge> bsc_awedEdges; // working edges
  453. class CBrushMip *bsc_pbmBrushMip; // pointer to brush mip of this sector
  454. COLOR bsc_colColor; // color of this sector
  455. COLOR bsc_colAmbient; // ambient light for that sector
  456. ULONG bsc_ulFlags; // flags
  457. ULONG bsc_ulFlags2; // second set of flags
  458. ULONG bsc_ulTempFlags; // flags that are not saved
  459. ULONG bsc_ulVisFlags; // special visibility flags
  460. FLOATaabbox3D bsc_boxBoundingBox; // bounding box in absolute space
  461. FLOATaabbox3D bsc_boxRelative; // bounding box in relative space
  462. CListNode bsc_lnInActiveSectors; // node in sectors active in some operation (e.g. rendering)
  463. DOUBLEbsptree3D &bsc_bspBSPTree; // the local bsp tree of the sector
  464. CRelationDst bsc_rdOtherSidePortals; // relation to portals pointing to this sector
  465. CRelationSrc bsc_rsEntities; // relation to all entities in this sector
  466. CTString bsc_strName; // sector name
  467. INDEX bsc_iInWorld; // index of the sector in entire world
  468. CRelationLnk *bsc_prlLink; // for optimized link removal
  469. INDEX bsc_ispo0; // screen polygons used in rendering
  470. INDEX bsc_ctspo;
  471. INDEX bsc_ivvx0; // view vertices used in rendering
  472. /* Default constructor. */
  473. CBrushSector(void);
  474. ~CBrushSector(void);
  475. DECLARE_NOCOPYING(CBrushSector);
  476. /* Clear the object. */
  477. void Clear(void);
  478. /* Lock all arrays. */
  479. void LockAll(void);
  480. /* Unlock all arrays. */
  481. void UnlockAll(void);
  482. /* Update sector after moving vertices */
  483. void UpdateVertexChanges(void);
  484. // triangularize given polygon
  485. void TriangularizePolygon( CBrushPolygon *pbpo);
  486. /* Triangularize polygons contining vertices from selection */
  487. void TriangularizeForVertices( CBrushVertexSelection &selVertex);
  488. // Triangularize marked polygons
  489. void TriangularizeMarkedPolygons( void);
  490. // Subdivide given triangles
  491. void SubdivideTriangles( CBrushPolygonSelection &selPolygon);
  492. // Insert given vertex into triangle
  493. void InsertVertexIntoTriangle( CBrushPolygonSelection &selPolygon, FLOAT3D vVertex);
  494. // Retriple two triangles given trough selection
  495. BOOL IsReTripleAvailable( CBrushPolygonSelection &selPolygon);
  496. void ReTriple( CBrushPolygonSelection &selPolygon);
  497. /* Calculate bounding boxes of all polygons. */
  498. void CalculateBoundingBoxes(CSimpleProjection3D_DOUBLE &prRelativeToAbsolute);
  499. // sectors may be selected
  500. IMPLEMENT_SELECTING(bsc_ulFlags)
  501. // overrides from CSerial
  502. /* Read from stream. */
  503. void Read_t( CTStream *istrFile); // throw char *
  504. /* Write to stream. */
  505. void Write_t( CTStream *ostrFile); // throw char *
  506. /* Uncache lightmaps on all shadows on the sector. */
  507. void UncacheLightMaps(void);
  508. /* Find and remember all entities in this sector. */
  509. void FindEntitiesInSector(void);
  510. /* Get/set properties. */
  511. inline INDEX GetContentType(void) {
  512. return (bsc_ulFlags>>BSCB_CONTENTTYPE)&0xff;
  513. }
  514. void SetContentType(INDEX iNewContent)
  515. {
  516. iNewContent&=0xff;
  517. bsc_ulFlags &= ~(0xff<<BSCB_CONTENTTYPE);
  518. bsc_ulFlags |= (iNewContent<<BSCB_CONTENTTYPE);
  519. }
  520. INDEX GetForceType(void) {
  521. return (bsc_ulFlags>>BSCB_FORCETYPE)&0xff;
  522. }
  523. void SetForceType(INDEX iNewForce) {
  524. iNewForce&=0xff;
  525. bsc_ulFlags &= ~(0xff<<BSCB_FORCETYPE);
  526. bsc_ulFlags |= (iNewForce<<BSCB_FORCETYPE);
  527. }
  528. INDEX GetFogType(void) {
  529. return (bsc_ulFlags>>BSCB_FOGTYPE)&0xf;
  530. }
  531. void SetFogType(INDEX iNewForce) {
  532. iNewForce&=0xf;
  533. bsc_ulFlags &= ~(0xf<<BSCB_FOGTYPE);
  534. bsc_ulFlags |= (iNewForce<<BSCB_FOGTYPE);
  535. }
  536. INDEX GetHazeType(void) {
  537. return (bsc_ulFlags>>BSCB_HAZETYPE)&0xf;
  538. }
  539. void SetHazeType(INDEX iNewForce) {
  540. iNewForce&=0xf;
  541. bsc_ulFlags &= ~(0xf<<BSCB_HAZETYPE);
  542. bsc_ulFlags |= (iNewForce<<BSCB_HAZETYPE);
  543. }
  544. inline INDEX GetEnvironmentType(void) {
  545. return (bsc_ulFlags2>>BSCB2_ENVIRONMENTTYPE)&0xFF;
  546. }
  547. void SetEnvironmentType(INDEX iNewEnvironment)
  548. {
  549. iNewEnvironment&=0xFF;
  550. bsc_ulFlags2 &= ~(0xFF<<BSCB2_ENVIRONMENTTYPE);
  551. bsc_ulFlags2 |= (iNewEnvironment<<BSCB2_ENVIRONMENTTYPE);
  552. }
  553. // get amount of memory used by this object
  554. SLONG GetUsedMemory(void);
  555. };
  556. // selection of brush sectors
  557. typedef CSelection<CBrushSector, BSCF_SELECTED> CBrushSectorSelection;
  558. // selection of brush sectors used for CSG
  559. typedef CSelection<CBrushSector, BSCF_SELECTEDFORCSG> CBrushSectorSelectionForCSG;
  560. /*
  561. * One detail level of a brush.
  562. */
  563. class ENGINE_API CBrushMip {
  564. public:
  565. // implementation:
  566. CDynamicArray<CBrushSector> bm_abscSectors; // sectors
  567. CBrush3D *bm_pbrBrush; // pointer to brush
  568. /* Select all sectors within a range. */
  569. void SelectSectorsInRange(CBrushSectorSelectionForCSG &selbscInRange, FLOATaabbox3D boxRange);
  570. void SelectSectorsInRange(CBrushSectorSelection &selbscInRange, FLOATaabbox3D boxRange);
  571. /* Select all sectors in brush. */
  572. void SelectAllSectors(CBrushSectorSelectionForCSG &selbscAll);
  573. void SelectAllSectors(CBrushSectorSelection &selbscAll);
  574. /* Select open sector in brush. */
  575. void SelectOpenSector(CBrushSectorSelectionForCSG &selbscOpen);
  576. /* Select closed sectors in brush. */
  577. void SelectClosedSectors(CBrushSectorSelectionForCSG &selbscClosed);
  578. /* Fill a 3d object from a selection in a brush. */
  579. void ToObject3D(CObject3D &ob, CBrushSectorSelection &selbscToCopy);
  580. void ToObject3D(CObject3D &ob, CBrushSectorSelectionForCSG &selbscToCopy);
  581. /* Add an object3d to brush. (returns pointer to the first created sector) */
  582. CBrushSector *AddFromObject3D_t(CObject3D &ob); // throw char *
  583. /* Delete all sectors in a selection. */
  584. void DeleteSelectedSectors(CBrushSectorSelectionForCSG &selbscToDelete);
  585. /* Spread all brush mips after this one. */
  586. void SpreadFurtherMips(void);
  587. /* Reoptimize all sectors in the brush mip. */
  588. void Reoptimize(void);
  589. /* Find all portals that have no links and kill their portal flag. */
  590. void RemoveDummyPortals(BOOL bClearPortalFlags);
  591. public:
  592. // interface:
  593. CListNode bm_lnInBrush; // for linking in list of mip-brushes for a brush
  594. FLOAT bm_fMaxDistance; // distance after which this mip-brush is not displayed
  595. FLOATaabbox3D bm_boxBoundingBox; // bounding box of entire mip-brush in absolute space
  596. FLOATaabbox3D bm_boxRelative; // bounding box of entire mip-brush in relative space
  597. /* Constructor. */
  598. CBrushMip(void);
  599. /* Free all memory and leave empty brush mip. */
  600. void Clear(void);
  601. /* Fill a brush mip from 3d object. */
  602. void FromObject3D_t(CObject3D &ob); // throw char *
  603. /* Copy brush mip from another brush mip. */
  604. void Copy(CBrushMip &bmOther, FLOAT fStretch, BOOL bMirrorX);
  605. /* Set mip distance of this mip, spread all that are further. */
  606. void SetMipDistance(FLOAT fMipDistance);
  607. /* Get mip factor of this mip. */
  608. FLOAT GetMipDistance(void);
  609. /* Get mip index of this mip. */
  610. INDEX GetMipIndex(void);
  611. // get next brush mip
  612. CBrushMip *GetNext(void);
  613. // get previous brush mip
  614. CBrushMip *GetPrev(void);
  615. // check if this is the first mip in this brush
  616. inline BOOL IsFirstMip(void);
  617. // overrides from CSerial
  618. /* Read from stream. */
  619. void Read_new_t( CTStream *istrFile); // throw char *
  620. void Read_old_t( CTStream *istrFile); // throw char *
  621. /* Write to stream. */
  622. void Write_t( CTStream *ostrFile); // throw char *
  623. /* Update bounding box from bounding boxes of all sectors. */
  624. void UpdateBoundingBox(void);
  625. /* Calculate bounding boxes in all sectors. */
  626. void CalculateBoundingBoxes(CSimpleProjection3D_DOUBLE &prRelativeToAbsolute);
  627. };
  628. /*
  629. * Brush class -- a piece of level that can be moved independently
  630. */
  631. #define BRF_DRAWSELECTED (1L<<0) // internal marker for rendering selected brushes
  632. #define BRF_DRAWFIRSTMIP (1L<<1) // viewer is inside this brush
  633. class ENGINE_API CBrush3D : public CBrushBase {
  634. public:
  635. // implementation:
  636. CListNode br_lnInActiveBrushes; // for linking in list of active brushes in renderer
  637. CAnyProjection3D br_prProjection; // projection currently used by this brush
  638. CEntity *br_penEntity; // back pointer from brush to its entity
  639. class CFieldSettings *br_pfsFieldSettings;// field settings for field brushes
  640. ULONG br_ulFlags; // brush flags
  641. /* Wrapper for CObject3D::Optimize(), updates profiling information. */
  642. static void OptimizeObject3D(CObject3D &ob);
  643. /* Prepare a projection from brush space to absolute space. */
  644. void PrepareRelativeToAbsoluteProjection(CSimpleProjection3D_DOUBLE &prRelativeToAbsolute);
  645. /* Calculate bounding boxes in all brush mips. */
  646. void CalculateBoundingBoxes(void);
  647. void CalculateBoundingBoxesForOneMip(CBrushMip *pbmOnly); // for only one mip
  648. INDEX GetBrushType() { return CBrushBase::BT_BRUSH3D; } // this is brush not terrain
  649. public:
  650. // interface:
  651. CListHead br_lhBrushMips; // mip brushes in this brush
  652. // constructor
  653. CBrush3D(void);
  654. // destructor
  655. ~CBrush3D(void);
  656. /* Free all memory and leave empty brush. */
  657. void Clear(void);
  658. /* Fill a brush from 3d object. */
  659. void FromObject3D_t(CObject3D &ob); // throw char *
  660. void AddMipBrushFromObject3D_t(CObject3D &ob, FLOAT fSwitchDistance); // throw char *
  661. /* Copy brush from another brush with possible mirror and stretch. */
  662. void Copy(CBrush3D &brOther, FLOAT fStretch, BOOL bMirrorX);
  663. /* Delete a brush mip with given factor. */
  664. void DeleteBrushMip(CBrushMip *pbmToDelete);
  665. /* Create a new brush mip. */
  666. CBrushMip *NewBrushMipAfter(CBrushMip *pbm, BOOL bCopy);
  667. CBrushMip *NewBrushMipBefore(CBrushMip *pbm, BOOL bCopy);
  668. /* Get a brush mip for given mip-factor. */
  669. CBrushMip *GetBrushMipByDistance(FLOAT fDistance);
  670. /* Get a brush mip by its given index. */
  671. CBrushMip *GetBrushMipByIndex(INDEX iMip);
  672. // get first brush mip
  673. CBrushMip *GetFirstMip(void);
  674. // get last brush mip
  675. CBrushMip *GetLastMip(void);
  676. // switch from zoning to non-zoning
  677. void SwitchToNonZoning(void);
  678. // switch from non-zoning to zoning
  679. void SwitchToZoning(void);
  680. // overrides from CSerial
  681. /* Read from stream. */
  682. void Read_t( CTStream *istrFile); // throw char *
  683. void Read_new_t( CTStream *istrFile); // throw char *
  684. void Read_old_t( CTStream *istrFile); // throw char *
  685. /* Write to stream. */
  686. void Write_t( CTStream *ostrFile); // throw char *
  687. };
  688. // check if this is the first mip in this brush
  689. inline BOOL CBrushMip::IsFirstMip(void) {
  690. return &bm_pbrBrush->br_lhBrushMips.IterationHead() == &bm_lnInBrush;
  691. };
  692. #endif /* include-once check. */