/* Copyright (c) 2002-2012 Croteam Ltd. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef SE_INCL_BRUSH_H #define SE_INCL_BRUSH_H #ifdef PRAGMA_ONCE #pragma once #endif #include #include #include #include #include #include #include #include #include #include #include #include #include // a vertex in brush #define BVXF_DRAWNINWIREFRAME (1L<<0) // vertex is already drawn in wireframe #define BVXF_SELECTED (1L<<1) // vertex is selected class ENGINE_API CBrushVertex { public: class CWorkingVertex *bvx_pwvxWorking; // used for rendering and ray casting FLOAT3D bvx_vAbsolute; FLOAT3D bvx_vRelative; // relative coordinates used for collision DOUBLE3D bvx_vdPreciseRelative; // precise relative coordinates used for editing DOUBLE3D *bvx_pvdPreciseAbsolute; // precise vertex coordinates in absolute space ULONG bvx_ulFlags; // flags CBrushSector *bvx_pbscSector; // back-pointer to sector /* Default constructor. */ inline CBrushVertex(void) : bvx_pwvxWorking(NULL), bvx_ulFlags(0) {}; /* Clear the object. */ inline void Clear(void) {}; // vertices may be selected IMPLEMENT_SELECTING(bvx_ulFlags) // set new absolute position for the vertex void SetAbsolutePosition(const DOUBLE3D &vAbsolute); // get amount of memory used by this object inline SLONG GetUsedMemory(void) { return sizeof(CBrushVertex); }; }; // selection of brush vertices typedef CSelection CBrushVertexSelection; // a plane in brush class ENGINE_API CBrushPlane { public: class CWorkingPlane *bpl_pwplWorking; // use for rendering and ray casting FLOATplane3D bpl_plAbsolute; FLOATplane3D bpl_plRelative; // relative coordinates used for collision DOUBLEplane3D *bpl_ppldPreciseAbsolute; // precise relative plane coordinates in absolute space DOUBLEplane3D bpl_pldPreciseRelative; // precise coordinates used for editing INDEX bpl_iPlaneMajorAxis1; // major axes of the plane in apsolute space INDEX bpl_iPlaneMajorAxis2; /* Default constructor. */ inline CBrushPlane(void) : bpl_pwplWorking(NULL) {}; /* Clear the object. */ inline void Clear(void) {}; // get amount of memory used by this object inline SLONG GetUsedMemory(void) { return sizeof(CBrushPlane); }; }; // an edge in brush class ENGINE_API CBrushEdge { public: CBrushVertex *bed_pbvxVertex0; // start vertex CBrushVertex *bed_pbvxVertex1; // end vertex CWorkingEdge *bed_pwedWorking; // pointer to screen edge if active in rendering /* Default constructor. */ inline CBrushEdge(void) : bed_pwedWorking(NULL) {}; /* Constructor with two vertices. */ inline CBrushEdge(CBrushVertex *pbvx0, CBrushVertex *pbvx1) : bed_pwedWorking(NULL), bed_pbvxVertex0(pbvx0), bed_pbvxVertex1(pbvx1) {}; /* Clear the object. */ inline void Clear(void) {}; /* Test if this edge touches another one. */ BOOL TouchesInSameSector(CBrushEdge &bedOther); BOOL TouchesInAnySector(CBrushEdge &bedOther); // get amount of memory used by this object inline SLONG GetUsedMemory(void) { return sizeof(CBrushEdge); }; }; // a reference to edge used in brush polygon class ENGINE_API CBrushPolygonEdge { public: CBrushEdge *bpe_pbedEdge; // pointer to the edge BOOL bpe_bReverse; // true if the vertex0 and vertex1 must be swapped /* Clear the object. */ inline void Clear(void) {}; /* Get coordinates of the end vertices. */ inline void GetVertices(CBrushVertex *&pbvx0, CBrushVertex *&pbvx1) { if (bpe_bReverse) { pbvx0 = bpe_pbedEdge->bed_pbvxVertex1; pbvx1 = bpe_pbedEdge->bed_pbvxVertex0; } else { pbvx0 = bpe_pbedEdge->bed_pbvxVertex0; pbvx1 = bpe_pbedEdge->bed_pbvxVertex1; } } inline void GetVertexCoordinatesAbsolute(FLOAT3D &v0, FLOAT3D &v1) { if (bpe_bReverse) { v0 = bpe_pbedEdge->bed_pbvxVertex1->bvx_vAbsolute; v1 = bpe_pbedEdge->bed_pbvxVertex0->bvx_vAbsolute; } else { v0 = bpe_pbedEdge->bed_pbvxVertex0->bvx_vAbsolute; v1 = bpe_pbedEdge->bed_pbvxVertex1->bvx_vAbsolute; } }; inline void GetVertexCoordinatesRelative(FLOAT3D &v0, FLOAT3D &v1) { if (bpe_bReverse) { v0 = bpe_pbedEdge->bed_pbvxVertex1->bvx_vRelative; v1 = bpe_pbedEdge->bed_pbvxVertex0->bvx_vRelative; } else { v0 = bpe_pbedEdge->bed_pbvxVertex0->bvx_vRelative; v1 = bpe_pbedEdge->bed_pbvxVertex1->bvx_vRelative; } }; inline void GetVertexCoordinatesPreciseRelative(DOUBLE3D &v0, DOUBLE3D &v1) { if (bpe_bReverse) { v0 = bpe_pbedEdge->bed_pbvxVertex1->bvx_vdPreciseRelative; v1 = bpe_pbedEdge->bed_pbvxVertex0->bvx_vdPreciseRelative; } else { v0 = bpe_pbedEdge->bed_pbvxVertex0->bvx_vdPreciseRelative; v1 = bpe_pbedEdge->bed_pbvxVertex1->bvx_vdPreciseRelative; } }; inline void GetVertexCoordinatesPreciseAbsolute(DOUBLE3D &v0, DOUBLE3D &v1) { if (bpe_bReverse) { v0 = *bpe_pbedEdge->bed_pbvxVertex1->bvx_pvdPreciseAbsolute; v1 = *bpe_pbedEdge->bed_pbvxVertex0->bvx_pvdPreciseAbsolute; } else { v0 = *bpe_pbedEdge->bed_pbvxVertex0->bvx_pvdPreciseAbsolute; v1 = *bpe_pbedEdge->bed_pbvxVertex1->bvx_pvdPreciseAbsolute; } }; }; // one layer on brush shadow map (cross link between brush shadow map and light source) #define BSLF_CALCULATED (1L<<0) #define BSLF_RECTANGLE (1L<<1) // new version of layer with only influenced rectangle #define BSLF_ALLDARK (1L<<2) // polygon is not lighted by the light at all #define BSLF_ALLLIGHT (1L<<3) // whole polygon is lighted by the light (there are no shadows) class ENGINE_API CBrushShadowLayer { public: // implementation: ULONG bsl_ulFlags; // flags CListNode bsl_lnInShadowMap; // node in list of all layers of a shadow map CListNode bsl_lnInLightSource; // node in list of all layers of a light source class CBrushShadowMap *bsl_pbsmShadowMap; // the shadow map class CLightSource *bsl_plsLightSource; // the light source PIX bsl_pixMinU; // rectangle where the light influences the polygon PIX bsl_pixMinV; PIX bsl_pixSizeU; PIX bsl_pixSizeV; SLONG bsl_slSizeInPixels; // size of bit mask in pixels (with all mip-maps) UBYTE *bsl_pubLayer; // bit mask set where the polygon is lighted COLOR bsl_colLastAnim; // last animating color cached // interface: CBrushShadowLayer(); ~CBrushShadowLayer(void); // discard shadows but keep the layer void DiscardShadows(void); // get shadow/light percentage at given coordinates in shadow layer FLOAT GetLightStrength(PIX pixU, PIX pixV, FLOAT fLt, FLOAT fUp); // get amount of memory used by this object SLONG GetUsedMemory(void); }; class ENGINE_API CBrushShadowMap : public CShadowMap { public: // implementation: // for linking in list of all shadow maps that need calculation CListNode bsm_lnInUncalculatedShadowMaps; CListHead bsm_lhLayers; // list of all layers of this shadow map UBYTE *bsm_pubPolygonMask; // bit packed polygon mask // get pointer to embedding brush polygon inline CBrushPolygon *GetBrushPolygon(void); // overrides from CShadowMap: // mix all layers into cached shadow map virtual void MixLayers(INDEX iFirstMip, INDEX iLastMip, BOOL bDynamic=FALSE); // iFirstMip>(CTStream &strm, CBrushPolygonProperties &cbpp) { strm>>cbpp.bpp_ubSurfaceType; strm>>cbpp.bpp_ubIlluminationType; strm>>cbpp.bpp_ubShadowBlend; strm>>cbpp.bpp_ubMirrorType; strm>>cbpp.bpp_ubGradientType; strm>>cbpp.bpp_sbShadowClusterSize; strm>>cbpp.bpp_uwPretenderDistance; return strm; } friend __forceinline CTStream &operator<<(CTStream &strm, const CBrushPolygonProperties &cbpp) { strm< &bspo); void CreateBSPPolygonNonPrecise(BSPPolygon &bspo); /* Create shadow map for the polygon. */ void MakeShadowMap(CWorld *pwoWorld, BOOL bDoDirectionalLights); /* Initialize shadow map for the polygon. */ void InitializeShadowMap(void); // discard all cached shading info for models void DiscardShadingInfos(void); // move edges from another polygon into this one void MovePolygonEdges(CBrushPolygon &bpoSource); /* Test if this polygon touches another one. */ BOOL TouchesInSameSector(CBrushPolygon &bpoOther); BOOL TouchesInAnySector(CBrushPolygon &bpoOther); // make triangular representation of the polygon void Triangulate(void); public: // interface: CBrushPlane *bpo_pbplPlane; // plane of this polygon CStaticArray bpo_abpePolygonEdges; // edges in this polygon CStaticArray bpo_apbvxTriangleVertices; // triangle vertices CStaticArray bpo_aiTriangleElements; // element indices inside vertex arrays CBrushPolygonTexture bpo_abptTextures[3]; // texture on this polygon COLOR bpo_colColor; // color of this polygon ULONG bpo_ulFlags; // flags COLOR bpo_colShadow; // color of shadow on this polygon CBrushShadowMap bpo_smShadowMap; // shadow map of this polygon CMappingDefinition bpo_mdShadow; // mapping of shadow on polygon CBrushPolygonProperties bpo_bppProperties; // additional properties class CScreenPolygon *bpo_pspoScreenPolygon; // used in rendering FLOATaabbox3D bpo_boxBoundingBox; // bounding box CBrushSector *bpo_pbscSector; // sector of this polygon CRelationSrc bpo_rsOtherSideSectors; // relation to sectors on other side of portal CListHead bpo_lhShadingInfos; // for linking shading infos of entities INDEX bpo_iInWorld; // index of the polygon in entire world /* Default constructor. */ inline CBrushPolygon(void) : bpo_ulFlags(0) {}; /* Clear the object. */ void Clear(void); /* Destructor. */ inline ~CBrushPolygon(void) { Clear(); }; CBrushPolygon &CopyPolygon(CBrushPolygon &bp); /* Copy polygon within same sector. */ void CopyFromSameSector(CBrushPolygon &bpoOriginal); /* Copy polygon properties */ CBrushPolygon &CopyProperties(CBrushPolygon &bpoOther, BOOL bCopyMapping = TRUE); /* Copy polygon properties without texture */ CBrushPolygon &CopyPropertiesWithoutTexture(CBrushPolygon &bpoOther); /* Copy polygon's textures */ CBrushPolygon &CopyTextures(CBrushPolygon &bpoOther); // polygons may be selected IMPLEMENT_SELECTING(bpo_ulFlags) /* Select group of adjacent polygons with same color. */ void SelectSimilarByColor(CSelection &selbpoSimilar); /* Select group of adjacent polygons with same texture. */ void SelectSimilarByTexture(CSelection &selbpoSimilar, INDEX iTexture); /* Select all polygons in sector with same texture. */ void SelectByTextureInSector(CSelection &selbpoSimilar, INDEX iTexture); /* Select all polygons in sector with same color. */ void SelectByColorInSector(CSelection &selbpoSimilar); /* Discard shadows on the polygon. */ void DiscardShadows(void); // find minimum distance of a given point from the polygon edges FLOAT GetDistanceFromEdges(const FLOAT3D &v); // get amount of memory used by this object SLONG GetUsedMemory(void); }; // get pointer to embedding brush polygon inline CBrushPolygon *CBrushShadowMap::GetBrushPolygon(void) { return (CBrushPolygon *) ((UBYTE*)this-_offsetof(CBrushPolygon, bpo_smShadowMap)); return(NULL); } // selection of brush polygons typedef CSelection CBrushPolygonSelection; // selection of brush polygons used for CSG typedef CSelection CBrushPolygonSelectionForCSG; // sector flags #define BSCF_SELECTED (1L<<0) // set if the sector is selected #define BSCF_HIDDEN (1L<<1) // set if the sector is hidden (for editing) #define BSCF_SELECTEDFORCSG (1L<<2) // set if the sector is selected for CSG #define BSCF_OPENSECTOR (1L<<3) // set if the sector polygons are facing outwards #define BSCF_NEARTESTED (1L<<4) // already tested for near polygon #define BSCF_INVISIBLE (1L<<5) // active, but not visible #define BSCF_RAYTESTED (1L<<6) // already tested by ray #define BSCF_NEEDSCLIPPING (1L<<7) // set if its polygons needs clipping #define BSCB_CONTENTTYPE 24 // upper 8 bits are used for sector content type #define BSCB_FORCETYPE 16 // next 8 bits are used for sector gravity type #define BSCB_FOGTYPE 12 // 4 bits for fog #define BSCB_HAZETYPE 8 // 4 bits for haze #define BSCB2_ENVIRONMENTTYPE 0 // 8 bits for environment sound effects (EAX and similar) #define BSCF2_VISIBILITYINCLUDE (1<<8) // toggle include/exclude for visibility (exclude is default) // vis flags #define VISM_INCLUDEEXCLUDE (0x0000FFFF) // for visibility include/exclude #define VISM_DONTCLASSIFY (0xFFFF0000) // to disable classification in certain sectors // NOTE on how visibility tweaks are implemented // - low 16 bits determine visibility from current sector // if BSCF2_VISIBILITYINCLUDE is on, entity is visible from sector only if EntityVisTweaks&SectorVisFlags&VISM_INCLUDEEXCLUDE // if BSCF2_VISIBILITYINCLUDE is off, entity is visible from sector only if !(EntityVisTweaks&SectorVisFlags&VISM_INCLUDEEXCLUDE) // - high 16 bits limit entity classification to sectors // if EntityVisTweaks&SectorVisFlags&VISM_DONTCLASSIFY, entity is treated as if not classified to that sector // temporary flags #define BSCTF_PRELOADEDBSP (1L<<0) // bsp is loaded, no need to calculate it #define BSCTF_PRELOADEDLINKS (1L<<1) // portallinks are loaded, no need to calculate them // a sector in brush class ENGINE_API CBrushSector { public: // implementation: /* Fill an object sector from a sector in brush. */ void ToObjectSector(CObjectSector &osc); /* Fill a brush sector from a sector in object3d. */ void FromObjectSector_t(CObjectSector &osc); // throw char * // recalculate planes for polygons from their vertices void MakePlanesFromVertices(); // update changed sector's data after dragging vertices or importing void UpdateSector(void); /* Calculate volume of the sector. */ DOUBLE CalculateVolume(void); // make triangular representation of the polygons in the sector void Triangulate(void); public: // implementation: CStaticArray bsc_abvxVertices; // vertices CStaticArray bsc_abedEdges; // edges CStaticArray bsc_abplPlanes; // planes CStaticArray bsc_abpoPolygons; // polygons CStaticArray bsc_awvxVertices; // working vertices CStaticArray bsc_awplPlanes; // working planes CStaticArray bsc_awedEdges; // working edges class CBrushMip *bsc_pbmBrushMip; // pointer to brush mip of this sector COLOR bsc_colColor; // color of this sector COLOR bsc_colAmbient; // ambient light for that sector ULONG bsc_ulFlags; // flags ULONG bsc_ulFlags2; // second set of flags ULONG bsc_ulTempFlags; // flags that are not saved ULONG bsc_ulVisFlags; // special visibility flags FLOATaabbox3D bsc_boxBoundingBox; // bounding box in absolute space FLOATaabbox3D bsc_boxRelative; // bounding box in relative space CListNode bsc_lnInActiveSectors; // node in sectors active in some operation (e.g. rendering) DOUBLEbsptree3D &bsc_bspBSPTree; // the local bsp tree of the sector CRelationDst bsc_rdOtherSidePortals; // relation to portals pointing to this sector CRelationSrc bsc_rsEntities; // relation to all entities in this sector CTString bsc_strName; // sector name INDEX bsc_iInWorld; // index of the sector in entire world CRelationLnk *bsc_prlLink; // for optimized link removal INDEX bsc_ispo0; // screen polygons used in rendering INDEX bsc_ctspo; INDEX bsc_ivvx0; // view vertices used in rendering /* Default constructor. */ CBrushSector(void); ~CBrushSector(void); DECLARE_NOCOPYING(CBrushSector); /* Clear the object. */ void Clear(void); /* Lock all arrays. */ void LockAll(void); /* Unlock all arrays. */ void UnlockAll(void); /* Update sector after moving vertices */ void UpdateVertexChanges(void); // triangularize given polygon void TriangularizePolygon( CBrushPolygon *pbpo); /* Triangularize polygons contining vertices from selection */ void TriangularizeForVertices( CBrushVertexSelection &selVertex); // Triangularize marked polygons void TriangularizeMarkedPolygons( void); // Subdivide given triangles void SubdivideTriangles( CBrushPolygonSelection &selPolygon); // Insert given vertex into triangle void InsertVertexIntoTriangle( CBrushPolygonSelection &selPolygon, FLOAT3D vVertex); // Retriple two triangles given trough selection BOOL IsReTripleAvailable( CBrushPolygonSelection &selPolygon); void ReTriple( CBrushPolygonSelection &selPolygon); /* Calculate bounding boxes of all polygons. */ void CalculateBoundingBoxes(CSimpleProjection3D_DOUBLE &prRelativeToAbsolute); // sectors may be selected IMPLEMENT_SELECTING(bsc_ulFlags) // overrides from CSerial /* Read from stream. */ void Read_t( CTStream *istrFile); // throw char * /* Write to stream. */ void Write_t( CTStream *ostrFile); // throw char * /* Uncache lightmaps on all shadows on the sector. */ void UncacheLightMaps(void); /* Find and remember all entities in this sector. */ void FindEntitiesInSector(void); /* Get/set properties. */ inline INDEX GetContentType(void) { return (bsc_ulFlags>>BSCB_CONTENTTYPE)&0xff; } void SetContentType(INDEX iNewContent) { iNewContent&=0xff; bsc_ulFlags &= ~(0xff<>BSCB_FORCETYPE)&0xff; } void SetForceType(INDEX iNewForce) { iNewForce&=0xff; bsc_ulFlags &= ~(0xff<>BSCB_FOGTYPE)&0xf; } void SetFogType(INDEX iNewForce) { iNewForce&=0xf; bsc_ulFlags &= ~(0xf<>BSCB_HAZETYPE)&0xf; } void SetHazeType(INDEX iNewForce) { iNewForce&=0xf; bsc_ulFlags &= ~(0xf<>BSCB2_ENVIRONMENTTYPE)&0xFF; } void SetEnvironmentType(INDEX iNewEnvironment) { iNewEnvironment&=0xFF; bsc_ulFlags2 &= ~(0xFF< CBrushSectorSelection; // selection of brush sectors used for CSG typedef CSelection CBrushSectorSelectionForCSG; /* * One detail level of a brush. */ class ENGINE_API CBrushMip { public: // implementation: CDynamicArray bm_abscSectors; // sectors CBrush3D *bm_pbrBrush; // pointer to brush /* Select all sectors within a range. */ void SelectSectorsInRange(CBrushSectorSelectionForCSG &selbscInRange, FLOATaabbox3D boxRange); void SelectSectorsInRange(CBrushSectorSelection &selbscInRange, FLOATaabbox3D boxRange); /* Select all sectors in brush. */ void SelectAllSectors(CBrushSectorSelectionForCSG &selbscAll); void SelectAllSectors(CBrushSectorSelection &selbscAll); /* Select open sector in brush. */ void SelectOpenSector(CBrushSectorSelectionForCSG &selbscOpen); /* Select closed sectors in brush. */ void SelectClosedSectors(CBrushSectorSelectionForCSG &selbscClosed); /* Fill a 3d object from a selection in a brush. */ void ToObject3D(CObject3D &ob, CBrushSectorSelection &selbscToCopy); void ToObject3D(CObject3D &ob, CBrushSectorSelectionForCSG &selbscToCopy); /* Add an object3d to brush. (returns pointer to the first created sector) */ CBrushSector *AddFromObject3D_t(CObject3D &ob); // throw char * /* Delete all sectors in a selection. */ void DeleteSelectedSectors(CBrushSectorSelectionForCSG &selbscToDelete); /* Spread all brush mips after this one. */ void SpreadFurtherMips(void); /* Reoptimize all sectors in the brush mip. */ void Reoptimize(void); /* Find all portals that have no links and kill their portal flag. */ void RemoveDummyPortals(BOOL bClearPortalFlags); public: // interface: CListNode bm_lnInBrush; // for linking in list of mip-brushes for a brush FLOAT bm_fMaxDistance; // distance after which this mip-brush is not displayed FLOATaabbox3D bm_boxBoundingBox; // bounding box of entire mip-brush in absolute space FLOATaabbox3D bm_boxRelative; // bounding box of entire mip-brush in relative space /* Constructor. */ CBrushMip(void); /* Free all memory and leave empty brush mip. */ void Clear(void); /* Fill a brush mip from 3d object. */ void FromObject3D_t(CObject3D &ob); // throw char * /* Copy brush mip from another brush mip. */ void Copy(CBrushMip &bmOther, FLOAT fStretch, BOOL bMirrorX); /* Set mip distance of this mip, spread all that are further. */ void SetMipDistance(FLOAT fMipDistance); /* Get mip factor of this mip. */ FLOAT GetMipDistance(void); /* Get mip index of this mip. */ INDEX GetMipIndex(void); // get next brush mip CBrushMip *GetNext(void); // get previous brush mip CBrushMip *GetPrev(void); // check if this is the first mip in this brush inline BOOL IsFirstMip(void); // overrides from CSerial /* Read from stream. */ void Read_new_t( CTStream *istrFile); // throw char * void Read_old_t( CTStream *istrFile); // throw char * /* Write to stream. */ void Write_t( CTStream *ostrFile); // throw char * /* Update bounding box from bounding boxes of all sectors. */ void UpdateBoundingBox(void); /* Calculate bounding boxes in all sectors. */ void CalculateBoundingBoxes(CSimpleProjection3D_DOUBLE &prRelativeToAbsolute); }; /* * Brush class -- a piece of level that can be moved independently */ #define BRF_DRAWSELECTED (1L<<0) // internal marker for rendering selected brushes #define BRF_DRAWFIRSTMIP (1L<<1) // viewer is inside this brush class ENGINE_API CBrush3D : public CBrushBase { public: // implementation: CListNode br_lnInActiveBrushes; // for linking in list of active brushes in renderer CAnyProjection3D br_prProjection; // projection currently used by this brush CEntity *br_penEntity; // back pointer from brush to its entity class CFieldSettings *br_pfsFieldSettings;// field settings for field brushes ULONG br_ulFlags; // brush flags /* Wrapper for CObject3D::Optimize(), updates profiling information. */ static void OptimizeObject3D(CObject3D &ob); /* Prepare a projection from brush space to absolute space. */ void PrepareRelativeToAbsoluteProjection(CSimpleProjection3D_DOUBLE &prRelativeToAbsolute); /* Calculate bounding boxes in all brush mips. */ void CalculateBoundingBoxes(void); void CalculateBoundingBoxesForOneMip(CBrushMip *pbmOnly); // for only one mip INDEX GetBrushType() { return CBrushBase::BT_BRUSH3D; } // this is brush not terrain public: // interface: CListHead br_lhBrushMips; // mip brushes in this brush // constructor CBrush3D(void); // destructor ~CBrush3D(void); /* Free all memory and leave empty brush. */ void Clear(void); /* Fill a brush from 3d object. */ void FromObject3D_t(CObject3D &ob); // throw char * void AddMipBrushFromObject3D_t(CObject3D &ob, FLOAT fSwitchDistance); // throw char * /* Copy brush from another brush with possible mirror and stretch. */ void Copy(CBrush3D &brOther, FLOAT fStretch, BOOL bMirrorX); /* Delete a brush mip with given factor. */ void DeleteBrushMip(CBrushMip *pbmToDelete); /* Create a new brush mip. */ CBrushMip *NewBrushMipAfter(CBrushMip *pbm, BOOL bCopy); CBrushMip *NewBrushMipBefore(CBrushMip *pbm, BOOL bCopy); /* Get a brush mip for given mip-factor. */ CBrushMip *GetBrushMipByDistance(FLOAT fDistance); /* Get a brush mip by its given index. */ CBrushMip *GetBrushMipByIndex(INDEX iMip); // get first brush mip CBrushMip *GetFirstMip(void); // get last brush mip CBrushMip *GetLastMip(void); // switch from zoning to non-zoning void SwitchToNonZoning(void); // switch from non-zoning to zoning void SwitchToZoning(void); // overrides from CSerial /* Read from stream. */ void Read_t( CTStream *istrFile); // throw char * void Read_new_t( CTStream *istrFile); // throw char * void Read_old_t( CTStream *istrFile); // throw char * /* Write to stream. */ void Write_t( CTStream *ostrFile); // throw char * }; // check if this is the first mip in this brush inline BOOL CBrushMip::IsFirstMip(void) { return &bm_pbrBrush->br_lhBrushMips.IterationHead() == &bm_lnInBrush; }; #endif /* include-once check. */