aboutsummaryrefslogtreecommitdiff
path: root/tool_src/BspLib/Polygon.h
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2026-08-24 11:16:07 +0200
committerFelix Morgner <felix.morgner@gmail.com>2026-08-24 11:16:07 +0200
commitc068f22329d5cc722622a2183bbb22eef2093df7 (patch)
tree12d56c1aede67988a55e241364606bfbb4dba933 /tool_src/BspLib/Polygon.h
downloadopenparsec-main.tar.xz
openparsec-main.zip
initial importHEADmain
Diffstat (limited to 'tool_src/BspLib/Polygon.h')
-rw-r--r--tool_src/BspLib/Polygon.h280
1 files changed, 280 insertions, 0 deletions
diff --git a/tool_src/BspLib/Polygon.h b/tool_src/BspLib/Polygon.h
new file mode 100644
index 0000000..d83de32
--- /dev/null
+++ b/tool_src/BspLib/Polygon.h
@@ -0,0 +1,280 @@
+//-----------------------------------------------------------------------------
+// BSPLIB HEADER: Polygon.h
+//
+// Copyright (c) 1996-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+#ifndef _POLYGON_H_
+#define _POLYGON_H_
+
+// bsplib header files
+#include "BspLibDefs.h"
+#include "Chunk.h"
+#include "Face.h"
+#include "Plane.h"
+#include "SystemIO.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+class BoundingBox;
+
+
+// vertex index (element of vertex index list) --------------------------------
+//
+class VIndx {
+
+public:
+ VIndx( int indx = -1, VIndx *next = NULL ) { vertindx = indx; nextvertindx = next; }
+ ~VIndx() { delete nextvertindx; }
+
+ int getIndx() const { return vertindx; }
+ void setIndx( int indx ) { vertindx = indx; }
+
+ VIndx* getNext() const { return nextvertindx; }
+ void setNext( VIndx *next ) { nextvertindx = next; }
+
+private:
+ int vertindx; // -1 means end of list, regardless of nextvertindx
+ VIndx* nextvertindx; // pointer to next VIndx in singly linked list
+};
+
+
+class BSPNode;
+class BspObject;
+
+
+// single polygon (element of polygon list) -----------------------------------
+//
+class Polygon : public virtual SystemIO {
+
+ friend class PolygonListRep;
+
+ void Error() const;
+
+ // possible classifications of polygon with respect to splitting plane
+ enum {
+ POLY_IN_FRONT_SUBSPACE,
+ POLY_IN_BACK_SUBSPACE,
+ POLY_STRADDLES_SPLITTER,
+ POLY_IN_SAME_PLANE,
+ };
+
+ // frontsubspace/backsubspace identifiers
+ enum {
+ FRONT_SUBSPACE = 1,
+ BACK_SUBSPACE = -1
+ };
+
+public:
+
+ // splitter selection criteria
+ enum {
+ SPLITTERCRIT_FIRST_POLY = 0x0000, // always choose first polygon in list
+ SPLITTERCRIT_SAMPLE_FIRST_N = 0x0101, // test first n polygons in list
+ SPLITTERCRIT_SAMPLE_ALL = 0x0002, // test entire list and choose best
+ SPLITTERCRIT_RANDOM_SAMPLE = 0x0103, // sample n polygons randomly
+ SPLITTERCRITMASK_SAMPLESIZ = 0x0100, // flagmask if samplesize (n) needed
+ };
+
+ // message flags
+ enum {
+ MESSAGE_SPLITTING_POLYGON = 0x0001,
+ MESSAGE_STARTVERTEX_IN_SPLITTER_PLANE = 0x0002,
+ MESSAGE_VERTEX_IN_SPLITTER_PLANE = 0x0004,
+ MESSAGE_NEW_SPLITVERTEX = 0x0008,
+ MESSAGE_REUSING_SPLITVERTEX = 0x0010,
+ MESSAGE_TRACEVERTEX_INSERTED = 0x0020,
+ MESSAGE_SPLITTING_QUADRILATERAL = 0x0040,
+ MESSAGE_INVOCATION = 0x0080,
+ MESSAGE_CHECKING_POLYGON_PLANES = 0x0100,
+ MESSAGEMASK_DISPLAY_ALL = 0xffff
+ };
+
+public:
+ Polygon( BspObject *bobj, int pno = 0, int fno = 0, Polygon *next = NULL, int num = 1 );
+ ~Polygon() { delete vertindxs; delete nextpolygon; }
+
+ Polygon* NewPolygon(); // create new polygon with sequential id as head of list
+ Polygon* InsertPolygon( Polygon *poly ); // insert existing polygon as head of list
+ Polygon* DeleteHead(); // delete this, return rest of list (DANGEROUS!)
+ Polygon* FindPolygon( int id ); // return polygon in list having specified id
+ int SumVertexNumsEntireList(); // sum up vertex numbers for all polygons of list
+
+ void PrependNewVIndx( int indx ); // create new VIndx and prepend it to list (vertindxs)
+ void AppendNewVIndx( int indx = -1 ); // create new VIndx and append it to list (vertindxs)
+ void AppendVIndx( VIndx *vindx ); // append existing VIndx to list (vertindxs)
+ VIndx* UnlinkLastVIndx(); // return last VIndx in list after unlinking it
+
+ void CalcPlaneNormals(); // calc normals for all polygons in list
+ void CheckEdges(); // check edges for contained vertices (scans list!)
+ Polygon* CheckPlanesAndMappings(); // check planes and mappings of all polygons in list
+
+ // calculate bounding box encompassing all polygons in list
+ void CalcBoundingBox( BoundingBox* &boundingbox );
+
+ // classify polygon with respect to this polygon
+ int CheckIntersection( Polygon *testpoly );
+ // check if other polygon's normal is contained in this one's positive halfspace (predicate)
+ int NormalDirectionSimilar( Polygon *testpoly );
+ // split other polygon along this polygon; insert split pieces into their respective halfspaces
+ void SplitPolygon( Polygon *poly, Polygon* &frontsubspace, Polygon* &backsubspace );
+ // partition space encompassing entire polygon list; return created BSP tree's root
+ BSPNode* PartitionSpace();
+
+ // correct numberings (polygon-id, face-id, and vertex indexes) to new base
+ void CorrectBase( BspObject *newbaseobj, int vertexindxbase, int faceidbase, int polygonidbase );
+ void CorrectBaseByTable( BspObject *newbaseobj, int *vtxindxmap, int faceidbase, int polygonidbase );
+
+ int getId() const { return polygonno; }
+ void setId( int pno ) { polygonno = pno; }
+
+ int getFaceId() const { return faceno; }
+ void setFaceId( int fno ) { faceno = fno; }
+
+ int getNumPolygons() const { return numpolygons; }
+ void setNumPolygons( int len ) { numpolygons = len; }
+
+ Polygon* getNext() const { return nextpolygon; }
+ void setNext( Polygon *next ) { nextpolygon = next; }
+
+ int getNumVertices() const { return numvertindxs; }
+
+ VIndx* getVList() const { return vertindxs; }
+ BspObject* getBaseObject() const { return baseobject; }
+
+ VertexChunk& getVertexList();
+ FaceChunk& getFaceList();
+
+ int HasArea() const;
+
+ int getFirstVertexIndx() const;
+ int getSecondVertexIndx() const;
+ int getThirdVertexIndx() const;
+
+ Vertex3 getFirstVertex() const;
+ Vertex3 getSecondVertex() const;
+ Vertex3 getThirdVertex() const;
+
+ Plane getPlane() const { return ((Polygon *const)this)->getFaceList()[ faceno ].getPlane(); }
+ Vector3 getPlaneNormal() const { return ((Polygon *const)this)->getFaceList()[ faceno ].getPlaneNormal(); }
+
+ void FillVertexIndexArray( dword *arr ) const; // write list of vertices into array
+ void WriteVertexList( FILE *fp, int cr ) const; // write list of vertices to file
+ void WritePolyList( FILE *fp ) const; // write list of polygon ids to file
+
+ int CalcSplitterTestProbability();
+
+public:
+ static int getSplitterSelection() { return splitter_crit; }
+ static void setSplitterSelection( int criterion ) { splitter_crit = criterion; }
+
+ static int getSampleSize() { return sample_size; }
+ static void setSampleSize( int siz ) { sample_size = siz; }
+
+ static int getTriangulationFlag() { return triangulate_all; }
+ static void setTriangulationFlag( int flag ) { triangulate_all = flag; }
+
+ static int getNormalizeVectorsFlag() { return normalize_vectors; }
+ static void setNormalizeVectorsFlag( int flag ) { normalize_vectors = flag; }
+
+ static int getDisplayMessagesFlag() { return display_messages; }
+ static void setDisplayMessagesFlag( int flag ) { display_messages = flag; }
+
+ static void ResetCallCount() { partition_callcount = 0; }
+
+private:
+ static int splitter_crit; // splitter selection criterion to use
+ static int sample_size; // sample size for splitter sampling
+ static int triangulate_all; // triangulate polygons with more than three vertices
+ static int normalize_vectors; // always normalize direction vectors
+ static int display_messages; // display a message every time PartitionSpace() is invoked
+ static int partition_callcount;// call counter for PartitionSpace()
+ static int test_probability; // probability to test single polygon if SPLITTERCRIT_RANDOM_SAMPLE
+ static char str_scratchpad[]; // string scratch pad
+
+private:
+ int polygonno; // global number of this polygon
+ int faceno; // global number of face this polygon is contained in
+ int numpolygons; // length of singly linked polygon list
+ int numvertindxs; // number of entries in vertex index list attached to this polygon
+ VIndx* vertindxs; // pointer to first VIndx
+ VIndx* vindxinsertpos; // pointer to last VIndx (NULL means insert-position is at head)
+ BspObject* baseobject; // pointer to object this polygon belongs to
+ Polygon* nextpolygon; // pointer to next polygon in list
+};
+
+// determine if the polygon has area ------------------------------------------
+inline int Polygon::HasArea() const
+{
+ // collinear vertices are not checked here, the polygon need only have
+ // at least three vertices to count as having area!
+ return ( vertindxs && vertindxs->getNext() && vertindxs->getNext()->getNext() );
+}
+
+// get first vertex of polygon ------------------------------------------------
+inline int Polygon::getFirstVertexIndx() const
+{
+ CHECK_DEREFERENCING(
+ if ( vertindxs == NULL )
+ Error();
+ );
+ return vertindxs->getIndx();
+}
+inline Vertex3 Polygon::getFirstVertex() const
+{
+ CHECK_DEREFERENCING(
+ if ( vertindxs == NULL )
+ Error();
+ );
+ return ((Polygon *const)this)->getVertexList()[ vertindxs->getIndx() ];
+}
+
+// get second vertex of polygon -----------------------------------------------
+inline int Polygon::getSecondVertexIndx() const
+{
+ CHECK_DEREFERENCING(
+ if ( ( vertindxs == NULL ) || ( vertindxs->getNext() == NULL ) )
+ Error();
+ );
+ return vertindxs->getNext()->getIndx();
+}
+inline Vertex3 Polygon::getSecondVertex() const
+{
+ CHECK_DEREFERENCING(
+ if ( ( vertindxs == NULL ) || ( vertindxs->getNext() == NULL ) )
+ Error();
+ );
+ return ((Polygon *const)this)->getVertexList()[ vertindxs->getNext()->getIndx() ];
+}
+
+// get third vertex of polygon ------------------------------------------------
+inline int Polygon::getThirdVertexIndx() const
+{
+ CHECK_DEREFERENCING(
+ if ( ( vertindxs == NULL ) ||
+ ( vertindxs->getNext() == NULL ) ||
+ ( vertindxs->getNext()->getNext() == NULL ) )
+ Error();
+ );
+ return vertindxs->getNext()->getNext()->getIndx();
+}
+inline Vertex3 Polygon::getThirdVertex() const
+{
+ CHECK_DEREFERENCING(
+ if ( ( vertindxs == NULL ) ||
+ ( vertindxs->getNext() == NULL ) ||
+ ( vertindxs->getNext()->getNext() == NULL ) )
+ Error();
+ );
+ return ((Polygon *const)this)->getVertexList()[ vertindxs->getNext()->getNext()->getIndx() ];
+}
+
+
+BSPLIB_NAMESPACE_END
+
+
+#endif // _POLYGON_H_
+