00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00226 return points[index];
00227 }
00228 const FixedWindingVertex& operator[] (std::size_t index) const
00229 {
00230
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