winding.h

Go to the documentation of this file.
00001 /*
00002  Copyright (C) 1999-2006 Id Software, Inc. and contributors.
00003  For a list of contributors, see the accompanying CONTRIBUTORS file.
00004 
00005  This file is part of GtkRadiant.
00006 
00007  GtkRadiant is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU General Public License as published by
00009  the Free Software Foundation; either version 2 of the License, or
00010  (at your option) any later version.
00011 
00012  GtkRadiant is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU General Public License for more details.
00016 
00017  You should have received a copy of the GNU General Public License
00018  along with GtkRadiant; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  */
00021 
00022 #if !defined(INCLUDED_WINDING_H)
00023 #define INCLUDED_WINDING_H
00024 
00025 #include "debugging/debugging.h"
00026 #include "shared.h"
00027 
00028 #include <vector>
00029 
00030 #include "math/Vector2.h"
00031 #include "math/Vector3.h"
00032 #include "container/array.h"
00033 
00034 enum ProjectionAxis
00035 {
00036     eProjectionAxisX = 0, eProjectionAxisY = 1, eProjectionAxisZ = 2,
00037 };
00038 
00039 const float ProjectionAxisEpsilon = static_cast<float> (0.0001);
00040 
00041 inline bool projectionaxis_better (float axis, float other)
00042 {
00043     return fabs(axis) > fabs(other) + ProjectionAxisEpsilon;
00044 }
00045 
00047 inline ProjectionAxis projectionaxis_for_normal (const Vector3& normal)
00048 {
00049     return (projectionaxis_better(normal[eProjectionAxisY], normal[eProjectionAxisX])) ? (projectionaxis_better(
00050             normal[eProjectionAxisY], normal[eProjectionAxisZ])) ? eProjectionAxisY : eProjectionAxisZ
00051             : (projectionaxis_better(normal[eProjectionAxisX], normal[eProjectionAxisZ])) ? eProjectionAxisX
00052                     : eProjectionAxisZ;
00053 }
00054 
00055 struct indexremap_t
00056 {
00057         indexremap_t (std::size_t _x, std::size_t _y, std::size_t _z) :
00058             x(_x), y(_y), z(_z)
00059         {
00060         }
00061         std::size_t x, y, z;
00062 };
00063 
00064 inline indexremap_t indexremap_for_projectionaxis (const ProjectionAxis axis)
00065 {
00066     switch (axis) {
00067     case eProjectionAxisX:
00068         return indexremap_t(1, 2, 0);
00069     case eProjectionAxisY:
00070         return indexremap_t(2, 0, 1);
00071     default:
00072         return indexremap_t(0, 1, 2);
00073     }
00074 }
00075 
00076 enum PlaneClassification
00077 {
00078     ePlaneFront = 0, ePlaneBack = 1, ePlaneOn = 2,
00079 };
00080 
00081 #define MAX_POINTS_ON_WINDING 64
00082 const std::size_t c_brush_maxFaces = 1024;
00083 
00084 class WindingVertex
00085 {
00086     public:
00087         Vector3 vertex;
00088         Vector2 texcoord;
00089         Vector3 tangent;
00090         Vector3 bitangent;
00091         std::size_t adjacent;
00092 };
00093 
00094 struct Winding
00095 {
00096         typedef Array<WindingVertex> container_type;
00097 
00098         std::size_t numpoints;
00099         container_type points;
00100 
00101         typedef container_type::iterator iterator;
00102         typedef container_type::const_iterator const_iterator;
00103 
00104         Winding () :
00105             numpoints(0)
00106         {
00107         }
00108         Winding (std::size_t size) :
00109             numpoints(0), points(size)
00110         {
00111         }
00112         void resize (std::size_t size)
00113         {
00114             points.resize(size);
00115             numpoints = 0;
00116         }
00117 
00118         iterator begin ()
00119         {
00120             return points.begin();
00121         }
00122         const_iterator begin () const
00123         {
00124             return points.begin();
00125         }
00126         iterator end ()
00127         {
00128             return points.begin() + numpoints;
00129         }
00130         const_iterator end () const
00131         {
00132             return points.begin() + numpoints;
00133         }
00134 
00135         WindingVertex& operator[] (std::size_t index)
00136         {
00137             ASSERT_MESSAGE(index < points.size(), "winding: index out of bounds");
00138             return points[index];
00139         }
00140         const WindingVertex& operator[] (std::size_t index) const
00141         {
00142             ASSERT_MESSAGE(index < points.size(), "winding: index out of bounds");
00143             return points[index];
00144         }
00145 
00146         void push_back (const WindingVertex& point)
00147         {
00148             points[numpoints] = point;
00149             ++numpoints;
00150         }
00151         void erase (iterator point)
00152         {
00153             for (iterator i = point + 1; i != end(); point = i, ++i) {
00154                 *point = *i;
00155             }
00156             --numpoints;
00157         }
00158 };
00159 
00160 typedef BasicVector3<double> DoubleVector3;
00161 
00162 class DoubleLine
00163 {
00164     public:
00165         DoubleVector3 origin;
00166         DoubleVector3 direction;
00167 };
00168 
00169 class FixedWindingVertex
00170 {
00171     public:
00172         DoubleVector3 vertex;
00173         DoubleLine edge;
00174         std::size_t adjacent;
00175 
00176         FixedWindingVertex (const DoubleVector3& vertex_, const DoubleLine& edge_, std::size_t adjacent_) :
00177             vertex(vertex_), edge(edge_), adjacent(adjacent_)
00178         {
00179         }
00180 };
00181 
00182 struct FixedWinding
00183 {
00184         typedef std::vector<FixedWindingVertex> Points;
00185         Points points;
00186 
00187         FixedWinding ()
00188         {
00189             points.reserve(MAX_POINTS_ON_WINDING);
00190         }
00191 
00192         FixedWindingVertex& front ()
00193         {
00194             return points.front();
00195         }
00196         const FixedWindingVertex& front () const
00197         {
00198             return points.front();
00199         }
00200         FixedWindingVertex& back ()
00201         {
00202             return points.back();
00203         }
00204         const FixedWindingVertex& back () const
00205         {
00206             return points.back();
00207         }
00208 
00209         void clear ()
00210         {
00211             points.clear();
00212         }
00213 
00214         void push_back (const FixedWindingVertex& point)
00215         {
00216             points.push_back(point);
00217         }
00218         std::size_t size () const
00219         {
00220             return points.size();
00221         }
00222 
00223         FixedWindingVertex& operator[] (std::size_t index)
00224         {
00225             //ASSERT_MESSAGE(index < MAX_POINTS_ON_WINDING, "winding: index out of bounds");
00226             return points[index];
00227         }
00228         const FixedWindingVertex& operator[] (std::size_t index) const
00229         {
00230             //ASSERT_MESSAGE(index < MAX_POINTS_ON_WINDING, "winding: index out of bounds");
00231             return points[index];
00232         }
00233 
00234 };
00235 
00236 inline void Winding_forFixedWinding (Winding& winding, const FixedWinding& fixed)
00237 {
00238     winding.resize(fixed.size());
00239     winding.numpoints = fixed.size();
00240     for (std::size_t i = 0; i < fixed.size(); ++i) {
00241         winding[i].vertex[0] = static_cast<float> (fixed[i].vertex[0]);
00242         winding[i].vertex[1] = static_cast<float> (fixed[i].vertex[1]);
00243         winding[i].vertex[2] = static_cast<float> (fixed[i].vertex[2]);
00244         winding[i].adjacent = fixed[i].adjacent;
00245     }
00246 }
00247 
00248 inline std::size_t Winding_wrap (const Winding& winding, std::size_t i)
00249 {
00250     ASSERT_MESSAGE(winding.numpoints != 0, "Winding_wrap: empty winding");
00251     return i % winding.numpoints;
00252 }
00253 
00254 inline std::size_t Winding_next (const Winding& winding, std::size_t i)
00255 {
00256     return Winding_wrap(winding, ++i);
00257 }
00258 
00259 class Plane3;
00260 
00261 void Winding_createInfinite (FixedWinding& w, const Plane3& plane, double infinity);
00262 
00265 inline bool Edge_isDegenerate (const Vector3& x, const Vector3& y)
00266 {
00267     return (y - x).getLengthSquared() < (ON_EPSILON * ON_EPSILON);
00268 }
00269 
00270 void Winding_Clip (const FixedWinding& winding, const Plane3& plane, const Plane3& clipPlane, std::size_t adjacent,
00271         FixedWinding& clipped);
00272 
00273 struct BrushSplitType
00274 {
00275         BrushSplitType ()
00276         {
00277             counts[0] = 0;
00278             counts[1] = 0;
00279             counts[2] = 0;
00280         }
00281         BrushSplitType& operator+= (const BrushSplitType& other)
00282         {
00283             counts[0] += other.counts[0];
00284             counts[1] += other.counts[1];
00285             counts[2] += other.counts[2];
00286             return *this;
00287         }
00288         std::size_t counts[3];
00289 };
00290 
00291 BrushSplitType Winding_ClassifyPlane (const Winding& w, const Plane3& plane);
00292 
00293 bool Winding_PlanesConcave (const Winding& w1, const Winding& w2, const Plane3& plane1, const Plane3& plane2);
00294 bool Winding_TestPlane (const Winding& w, const Plane3& plane, bool flipped);
00295 
00296 std::size_t Winding_FindAdjacent (const Winding& w, std::size_t face);
00297 
00298 std::size_t Winding_Opposite (const Winding& w, const std::size_t index, const std::size_t other);
00299 std::size_t Winding_Opposite (const Winding& w, std::size_t index);
00300 
00301 void Winding_Centroid (const Winding& w, const Plane3& plane, Vector3& centroid);
00302 
00303 inline void Winding_printConnectivity (Winding& winding)
00304 {
00305     for (Winding::iterator i = winding.begin(); i != winding.end(); ++i) {
00306         std::size_t vertexIndex = std::distance(winding.begin(), i);
00307         globalOutputStream() << "vertex: " << Unsigned(vertexIndex) << " adjacent: " << Unsigned((*i).adjacent) << "\n";
00308     }
00309 }
00310 
00311 #endif

Generated by  doxygen 1.6.2