/* =========================================================================== Doom 3 GPL Source Code Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code"). Doom 3 Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Doom 3 Source Code 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 Doom 3 Source Code. If not, see . In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ #ifndef __BRUSH_H__ #define __BRUSH_H__ #include "idlib/containers/PlaneSet.h" #include "idlib/geometry/Winding.h" /* =============================================================================== Brushes =============================================================================== */ #define BRUSH_PLANESIDE_FRONT 1 #define BRUSH_PLANESIDE_BACK 2 #define BRUSH_PLANESIDE_BOTH ( BRUSH_PLANESIDE_FRONT | BRUSH_PLANESIDE_BACK ) #define BRUSH_PLANESIDE_FACING 4 class idBrush; class idBrushList; void DisplayRealTimeString( const char *string, ... ) id_attribute((format(printf,1,2))); //=============================================================== // // idBrushSide // //=============================================================== #define SFL_SPLIT 0x0001 #define SFL_BEVEL 0x0002 #define SFL_USED_SPLITTER 0x0004 #define SFL_TESTED_SPLITTER 0x0008 class idBrushSide { friend class idBrush; public: idBrushSide( void ); idBrushSide( const idPlane &plane, int planeNum ); ~idBrushSide( void ); int GetFlags( void ) const { return flags; } void SetFlag( int flag ) { flags |= flag; } void RemoveFlag( int flag ) { flags &= ~flag; } const idPlane & GetPlane( void ) const { return plane; } void SetPlaneNum( int num ) { planeNum = num; } int GetPlaneNum( void ) { return planeNum; } const idWinding * GetWinding( void ) const { return winding; } idBrushSide * Copy( void ) const; int Split( const idPlane &splitPlane, idBrushSide **front, idBrushSide **back ) const; private: int flags; int planeNum; idPlane plane; idWinding * winding; }; //=============================================================== // // idBrush // //=============================================================== #define BFL_NO_VALID_SPLITTERS 0x0001 class idBrush { friend class idBrushList; public: idBrush( void ); ~idBrush( void ); int GetFlags( void ) const { return flags; } void SetFlag( int flag ) { flags |= flag; } void RemoveFlag( int flag ) { flags &= ~flag; } void SetEntityNum( int num ) { entityNum = num; } void SetPrimitiveNum( int num ) { primitiveNum = num; } void SetContents( int contents ) { this->contents = contents; } int GetContents( void ) const { return contents; } const idBounds & GetBounds( void ) const { return bounds; } float GetVolume( void ) const; int GetNumSides( void ) const { return sides.Num(); } idBrushSide * GetSide( int i ) const { return sides[i]; } void SetPlaneSide( int s ) { planeSide = s; } void SavePlaneSide( void ) { savedPlaneSide = planeSide; } int GetSavedPlaneSide( void ) const { return savedPlaneSide; } bool FromSides( idList &sideList ); bool FromWinding( const idWinding &w, const idPlane &windingPlane ); bool FromBounds( const idBounds &bounds ); void Transform( const idVec3 &origin, const idMat3 &axis ); idBrush * Copy( void ) const; bool TryMerge( const idBrush *brush, const idPlaneSet &planeList ); // returns true if the brushes did intersect bool Subtract( const idBrush *b, idBrushList &list ) const; // split the brush into a front and back brush int Split( const idPlane &plane, int planeNum, idBrush **front, idBrush **back ) const; // expand the brush for an axial bounding box void ExpandForAxialBox( const idBounds &bounds ); // next brush in list idBrush * Next( void ) const { return next; } private: mutable idBrush * next; // next brush in list int entityNum; // entity number in editor int primitiveNum; // primitive number in editor int flags; // brush flags bool windingsValid; // set when side windings are valid int contents; // contents of brush int planeSide; // side of a plane this brush is on int savedPlaneSide; // saved plane side idBounds bounds; // brush bounds idList sides; // list with sides private: bool CreateWindings( void ); void BoundBrush( const idBrush *original = NULL ); void AddBevelsForAxialBox( void ); bool RemoveSidesWithoutWinding( void ); }; //=============================================================== // // idBrushList // //=============================================================== class idBrushList { public: idBrushList( void ); ~idBrushList( void ); int Num( void ) const { return numBrushes; } int NumSides( void ) const { return numBrushSides; } idBrush * Head( void ) const { return head; } idBrush * Tail( void ) const { return tail; } void Clear( void ) { head = tail = NULL; numBrushes = 0; } bool IsEmpty( void ) const { return (numBrushes == 0); } idBounds GetBounds( void ) const; // add brush to the tail of the list void AddToTail( idBrush *brush ); // add list to the tail of the list void AddToTail( idBrushList &list ); // add brush to the front of the list void AddToFront( idBrush *brush ); // add list to the front of the list void AddToFront( idBrushList &list ); // remove the brush from the list void Remove( idBrush *brush ); // remove the brush from the list and delete the brush void Delete( idBrush *brush); // returns a copy of the brush list idBrushList * Copy( void ) const; // delete all brushes in the list void Free( void ); // split the brushes in the list into two lists void Split( const idPlane &plane, int planeNum, idBrushList &frontList, idBrushList &backList, bool useBrushSavedPlaneSide = false ); // chop away all brush overlap void Chop( bool (*ChopAllowed)( idBrush *b1, idBrush *b2 ) ); // merge brushes void Merge( bool (*MergeAllowed)( idBrush *b1, idBrush *b2 ) ); // set the given flag on all brush sides facing the plane void SetFlagOnFacingBrushSides( const idPlane &plane, int flag ); // get a list with planes for all brushes in the list void CreatePlaneList( idPlaneSet &planeList ) const; // write a brush map with the brushes in the list void WriteBrushMap( const idStr &fileName, const idStr &ext ) const; private: idBrush * head; idBrush * tail; int numBrushes; int numBrushSides; }; //=============================================================== // // idBrushMap // //=============================================================== class idBrushMap { public: idBrushMap( const idStr &fileName, const idStr &ext ); ~idBrushMap( void ); void SetTexture( const idStr &textureName ) { texture = textureName; } void WriteBrush( const idBrush *brush ); void WriteBrushList( const idBrushList &brushList ); private: idFile * fp; idStr texture; int brushCount; }; #endif /* !__BRUSH_H__ */