/* 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_BSP_INTERNAL_H #define SE_INCL_BSP_INTERNAL_H #ifdef PRAGMA_ONCE #pragma once #endif extern FLOAT mth_fCSGEpsilon; /* * Type used to identify BSP-node locations */ enum BSPNodeLocation { BNL_ILLEGAL=0, // for illegal value BNL_INSIDE, // inside leaf node BNL_OUTSIDE, // outside leaf node BNL_BRANCH, // branch node, unspecified location }; /* * Template class for BSP vertex */ template class BSPVertex : public Vector { public: /* Default constructor. */ inline BSPVertex(void) {}; /* Assignment operator with coordinates only. */ inline BSPVertex &operator=(const Vector &vCoordinates); }; /* * Template class for BSP vertex container */ template class BSPVertexContainer { public: INDEX bvc_iMaxAxis; // index of largest axis of direction Type bvc_tMaxAxisSign; // sign of largest axis of direction CStaticStackArray > bvc_aVertices; // array of vertices public: Vector bvc_vDirection; // direction of the split line /* Default constructor. */ BSPVertexContainer(void); /* Initialize for a direction. */ void Initialize(const Vector &vDirection); /* Uninitialize. */ void Uninitialize(void); /* Check if this container is in an unusable state (polygon coplanar with the splitter).*/ inline BOOL IsPlannar(void) { return bvc_iMaxAxis==0; }; /* Add a new vertex. */ inline void AddVertex(const Vector &vPoint); /* Sort vertices in this container along the largest axis of container direction. */ void Sort(void); /* Elliminate paired vertices. */ void ElliminatePairedVertices(void); /* Create edges from vertices in one container -- must be sorted before. */ void CreateEdges(CDynamicArray > &abedAll, size_t ulEdgeTag); }; /* * Template class for BSP edge */ template class BSPEdge { public: Vector bed_vVertex0; // edge vertices Vector bed_vVertex1; size_t bed_ulEdgeTag; // tags for BSPs with tagged edges/planes /* Default constructor. */ inline BSPEdge(void) {}; /* Constructor with two vectors. */ inline BSPEdge(const Vector &vVertex0, const Vector &vVertex1, size_t ulTag) : bed_vVertex0(vVertex0), bed_vVertex1(vVertex1), bed_ulEdgeTag(ulTag) {} /* Clear the object. */ inline void Clear(void) {}; // remove all edges marked for removal static void RemoveMarkedBSPEdges(CDynamicArray > &abed); // optimize a polygon made out of BSP edges using tag information static void OptimizeBSPEdges(CDynamicArray > &abed); }; /* * Template class for polygons used in creating BSP-trees */ template class BSPPolygon : public Plane { public: CDynamicArray > bpo_abedPolygonEdges; // array of edges in the polygon size_t bpo_ulPlaneTag; // tags for BSPs with tagged planes (-1 for no tag) /* Add an edge to the polygon. */ inline void AddEdge(const Vector &vPoint0, const Vector &vPoint1, size_t ulTag); /* Default constructor. */ inline BSPPolygon(void) : bpo_ulPlaneTag(-1) {}; /* Constructor with array of edges and plane. */ inline BSPPolygon( Plane &plPlane, CDynamicArray > abedPolygonEdges, size_t ulPlaneTag) : Plane(plPlane) , bpo_abedPolygonEdges(abedPolygonEdges) , bpo_ulPlaneTag(ulPlaneTag) {}; /* Clear the object. */ inline void Clear(void) {bpo_abedPolygonEdges.Clear();}; }; template class BSPLine { public: Type bl_tMin; Type bl_tMax; }; /* * Template class for BSP-tree node of arbitrary dimensions and arbitrary type of members */ template class BSPNode : public Plane { // split plane public: enum BSPNodeLocation bn_bnlLocation; // location of bsp node BSPNode *bn_pbnFront; // pointer to child node in front of split plane BSPNode *bn_pbnBack; // pointer to child node behind split plane size_t bn_ulPlaneTag; // tags for BSPs with tagged planes (-1 for no tag) public: /* Defualt constructor (for arrays only). */ inline BSPNode(void) {}; /* Constructor for a leaf node. */ inline BSPNode(enum BSPNodeLocation bnl); /* Constructor for a branch node. */ inline BSPNode(const Plane &plSplitPlane, size_t ulPlaneTag, BSPNode &bnFront, BSPNode &bnBack); /* Constructor for cloning a bsp (sub)tree. */ BSPNode(BSPNode &bnRoot); /* Recursive destructor. */ void DeleteBSPNodeRecursively(void); // find minimum/maximum parameters of points on a line that are inside - recursive void FindLineMinMax(BSPLine &bl, const Vector &v0, const Vector &v1, Type t0, Type t1); /* Test if a sphere is inside, outside, or intersecting. (Just a trivial rejection test) */ FLOAT TestSphere(const Vector &vSphereCenter, Type tSphereRadius) const; /* Test if a box is inside, outside, or intersecting. (Just a trivial rejection test) */ FLOAT TestBox(const OBBox &box) const; }; /* * Template class that performs polygon cuts using BSP-tree */ template class BSPCutter { public: /* Split an edge with a plane. */ static inline void SplitEdge(const Vector &vPoint0, const Vector &vPoint1, size_t ulEdgeTag, const Plane &plSplitPlane, BSPPolygon &abedFront, BSPPolygon &abedBack, BSPVertexContainer &bvcFront, BSPVertexContainer &bvcBack); /* Cut a polygon with a BSP tree. */ void CutPolygon(BSPPolygon &bpoPolygon, BSPNode &bn); public: CDynamicArray > bc_abedInside; // edges of inside part of polygon CDynamicArray > bc_abedOutside; // edges of outside part of polygon CDynamicArray > bc_abedBorderInside; // edges of border part of polygon facing inwards CDynamicArray > bc_abedBorderOutside;// edges of border part of polygon facing outwards /* Split a polygon with a plane. */ static inline BOOL SplitPolygon(BSPPolygon &bpoPolygon, const Plane &plPlane, size_t ulPlaneTag, BSPPolygon &bpoFront, BSPPolygon &bpoBack); /* Constructor for splitting a polygon with a BSP tree. */ BSPCutter(BSPPolygon &bpoPolygon, BSPNode &bnRoot); /* Destructor. */ ~BSPCutter(void); }; #endif /* include-once check. */