00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef __SGL_INTERSECT_HPP
00026 #define __SGL_INTERSECT_HPP
00027
00028 #include <sgl.h>
00029 #include <sglSegment.hpp>
00030 #include <sglBound.hpp>
00031 #include <sglProbe.hpp>
00032 #include <sglGeoSetDataPtr.hpp>
00033 #include <sglBoxBound.hpp>
00034 #include <deque>
00035
00036 class sglGeode;
00037 class sglDrawable;
00038 class sglNode;
00039
00040
00041
00042 template <class T>
00043 class SGL_DLL_API sglIntersect : public sglProbeTemplate<T>
00044 {
00045 public:
00046 class SGL_DLL_API IntersectResult : public sglProbeTemplate<T>::ProbeResult
00047 {
00048 public:
00049 sglBound::IntersectResultEnum m_result;
00050 sglSegment<T> m_segment;
00051 sglVec3f m_normal;
00052 deque<sglNode*> m_path;
00053
00054 public:
00055 IntersectResult() :
00056 sglProbeTemplate<T>::ProbeResult(),
00057 m_result(sglBound::eOUTSIDE),
00058 m_segment(sglVec3<T>(0,0,0),
00059 sglVec3<T>(0,0,0)),
00060 m_normal(0.f, 0.f, 0.f),
00061 m_path()
00062 {}
00063 virtual ~IntersectResult() { m_path.clear(); }
00064
00065 virtual void reset()
00066 {
00067 m_result = sglBound::eOUTSIDE;
00068 m_segment.setPos(sglVec3<T>(0,0,0));
00069 m_segment.setDir(sglVec3<T>(0,0,0));
00070 m_segment.setLen(0);
00071 m_normal.set(0.f, 0.f, 0.f);
00072 m_path.clear();
00073 resetInternal();
00074 }
00075 };
00076
00077 public:
00078 sglIntersect();
00079 ~sglIntersect();
00080
00081 virtual void reset();
00082
00083 void setSegment(const sglSegment<T> &segment)
00084 { m_result.m_segment = segment; }
00085 const sglSegment<T>& getSegment() const
00086 { return m_result.m_segment; }
00087
00088 void setResultEnum(sglBound::IntersectResultEnum result)
00089 { m_result.m_result = result; }
00090 sglBound::IntersectResultEnum getResultEnum() const
00091 { return m_result.m_result; }
00092
00098 deque<sglNode*>& getPath() { return m_result.m_path; }
00099
00100
00101 void setGeode(sglGeode *geode) { m_result.m_geode = geode; }
00102 const sglGeode *getGeode() const { return m_result.m_geode; }
00103
00104 void setGeometry(sglDrawable *geometry) { m_result.m_geometry = geometry; }
00105 const sglDrawable *getGeometry() const { return m_result.m_geometry; }
00106
00110 void setTransformMatrix(const sglMat4<T> &mat) { m_result.m_xform = mat; }
00111 const sglMat4<T> &getTransformMatrix() const { return m_result.m_xform; }
00112
00113
00114
00118 void setNormal(const sglVec3f &normal) { m_result.m_normal = normal; }
00119 const sglVec3f &getNormal() const { return m_result.m_normal; }
00120
00121
00122 template <class S>
00123 void translate(S x, S y, S z) { m_result.m_segment.translate(x, y, z); }
00124
00125 template <class S>
00126 void scale(S scale) { m_result.m_segment.scale(scale); }
00127
00128 template <class S>
00129 void mul(const sglMat4<S> &mat) { m_result.m_segment.mul(mat); }
00130
00131 void intersectTriangle(sglSegment<T> &seg,
00132 const sglVec3<T> &vertex0,
00133 const sglVec3<T> &vertex1,
00134 const sglVec3<T> &vertex2,
00135 sglBound::IntersectResultEnum &result);
00136
00137 const IntersectResult &getResult() const { return m_result; }
00138
00139
00141
00142 void pushScale(S scale,
00143 S inv_scale,
00144 sglSegment<T> &old_segment,
00145 sglMat4<T> &old_matrix,
00146 sglFrustum<T> &old_view_frustum)
00147 {
00148 if (m_mode & (eTRANSFORM|eUNSCALE_VIEW|eUNPROJECT_VIEW|
00149 eLOD_VIEW|eBILLBOARD_VIEW))
00150 {
00151
00152 old_matrix = m_modelview_matrix;
00153
00154
00155 m_modelview_matrix.scale(old_matrix, scale, scale, scale);
00156
00157
00158 if (m_mode & eUNPROJECT_VIEW)
00159 {
00160 old_view_frustum = m_current_view_frustum;
00161 m_current_view_frustum.scale(old_view_frustum, inv_scale);
00162 }
00163 }
00164
00165
00166
00167 old_segment = m_result.m_segment;
00168
00169
00170 m_result.m_segment.scale(inv_scale);
00171 }
00172
00174 template <class S>
00175 void pushTranslate(S tx, S ty, S tz,
00176 sglSegment<T> &old_segment,
00177 sglMat4<T> &old_matrix,
00178 sglFrustum<T> &old_view_frustum)
00179 {
00180 if (m_mode & (eTRANSFORM|eUNSCALE_VIEW|eUNPROJECT_VIEW|
00181 eLOD_VIEW|eBILLBOARD_VIEW))
00182 {
00183
00184 old_matrix = m_modelview_matrix;
00185
00186
00187 m_modelview_matrix.translate(old_matrix, tx, ty, tz);
00188
00189
00190 if (m_mode & eUNPROJECT_VIEW)
00191 {
00192 old_view_frustum = m_current_view_frustum;
00193 m_current_view_frustum.translate(old_view_frustum,
00194 -tx, -ty, -tz);
00195 }
00196 }
00197
00198
00199
00200 old_segment = m_result.m_segment;
00201
00202
00203 m_result.m_segment.translate(-tx, -ty, -tz);
00204 }
00205
00207 template <class S>
00208 void pushTransform(const sglMat4<S> &xform,
00209 const sglMat4<S> &inv_xform,
00210 sglSegment<T> &old_segment,
00211 sglMat4<T> &old_matrix,
00212 sglFrustum<T> &old_view_frustum)
00213 {
00214 if (m_mode & (eTRANSFORM|eUNSCALE_VIEW|eUNPROJECT_VIEW|
00215 eLOD_VIEW|eBILLBOARD_VIEW))
00216 {
00217
00218 old_matrix = m_modelview_matrix;
00219
00220
00221 m_modelview_matrix.mul(xform, old_matrix);
00222
00223
00224 if (m_mode & eUNPROJECT_VIEW)
00225 {
00226 old_view_frustum = m_current_view_frustum;
00227 m_current_view_frustum.mul(old_view_frustum, inv_xform);
00228 }
00229 }
00230
00231
00232
00233 old_segment = m_result.m_segment;
00234
00235
00236 m_result.m_segment.mul(inv_xform);
00237 }
00238
00239
00240 void pop(sglSegment<T> &old_segment,
00241 sglMat4<T> &old_matrix,
00242 sglFrustum<T> &old_view_frustum)
00243 {
00244 m_result.m_segment = old_segment;
00245
00246 if (m_mode & (eTRANSFORM|eUNSCALE_VIEW|eUNPROJECT_VIEW|
00247 eLOD_VIEW|eBILLBOARD_VIEW))
00248 {
00249 m_modelview_matrix = old_matrix;
00250
00251
00252 if (m_mode & eUNPROJECT_VIEW)
00253 {
00254 m_current_view_frustum = old_view_frustum;
00255 }
00256 }
00257 }
00258
00259 typedef void (*IntersectTriangleFunc)(
00260 sglIntersect<T> &segset,
00261 sglSegment<T> &seg,
00262 const void *vtx0, const void *vtx1, const void *vtx2,
00263 sglBound::IntersectResultEnum &result);
00264
00265
00266 static IntersectTriangleFunc getIntersectTriangleFunc(int vertex_type)
00267 { return s_isect_tri_func_table[vertex_type]; }
00268
00269 sglBound::IntersectResultEnum intersectIndexedTriangleSet(
00270 const sglBoxBound &bbox,
00271 const sglVertexPtr &vertices,
00272 const sglIndexPtr &index,
00273 unsigned int num_prims);
00274
00275 sglBound::IntersectResultEnum intersectIndexedTriangleStripSet(
00276 const sglBoxBound &bbox,
00277 const sglVertexPtr &vertices,
00278 const sglIndexPtr &index,
00279 const sglIndexPtr &lengths,
00280 unsigned int num_prims);
00281
00282 sglBound::IntersectResultEnum intersectIndexedTriangleFanSet(
00283 const sglBoxBound &bbox,
00284 const sglVertexPtr &vertices,
00285 const sglIndexPtr &index,
00286 const sglIndexPtr &lengths,
00287 unsigned int num_prims);
00288
00289 sglBound::IntersectResultEnum intersectIndexedQuadSet(
00290 const sglBoxBound &bbox,
00291 const sglVertexPtr &vertices,
00292 const sglIndexPtr &index,
00293 unsigned int num_prims);
00294
00295 sglBound::IntersectResultEnum intersectIndexedQuadStripSet(
00296 const sglBoxBound &bbox,
00297 const sglVertexPtr &vertices,
00298 const sglIndexPtr &index,
00299 const sglIndexPtr &lengths,
00300 unsigned int num_prims);
00301
00302 private:
00303 sglIntersect(const sglIntersect &);
00304 sglIntersect &operator=(const sglIntersect &);
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 static void intersectTriangle2s(
00320 sglIntersect<T> &segset,
00321 sglSegment<T> &seg,
00322 const void *vtx0, const void *vtx1, const void *vtx2,
00323 sglBound::IntersectResultEnum &result);
00324 static void intersectTriangle2i(
00325 sglIntersect<T> &segset,
00326 sglSegment<T> &seg,
00327 const void *vtx0, const void *vtx1, const void *vtx2,
00328 sglBound::IntersectResultEnum &result);
00329 static void intersectTriangle2f(
00330 sglIntersect<T> &segset,
00331 sglSegment<T> &seg,
00332 const void *vtx0, const void *vtx1, const void *vtx2,
00333 sglBound::IntersectResultEnum &result);
00334 static void intersectTriangle2d(
00335 sglIntersect<T> &segset,
00336 sglSegment<T> &seg,
00337 const void *vtx0, const void *vtx1, const void *vtx2,
00338 sglBound::IntersectResultEnum &result);
00339 static void intersectTriangle3s(
00340 sglIntersect<T> &segset,
00341 sglSegment<T> &seg,
00342 const void *vtx0, const void *vtx1, const void *vtx2,
00343 sglBound::IntersectResultEnum &result);
00344 static void intersectTriangle3i(
00345 sglIntersect<T> &segset,
00346 sglSegment<T> &seg,
00347 const void *vtx0, const void *vtx1, const void *vtx2,
00348 sglBound::IntersectResultEnum &result);
00349 static void intersectTriangle3f(
00350 sglIntersect<T> &segset,
00351 sglSegment<T> &seg,
00352 const void *vtx0, const void *vtx1, const void *vtx2,
00353 sglBound::IntersectResultEnum &result);
00354 static void intersectTriangle3d(
00355 sglIntersect<T> &segset,
00356 sglSegment<T> &seg,
00357 const void *vtx0, const void *vtx1, const void *vtx2,
00358 sglBound::IntersectResultEnum &result);
00359 static void intersectTriangle4s(
00360 sglIntersect<T> &segset,
00361 sglSegment<T> &seg,
00362 const void *vtx0, const void *vtx1, const void *vtx2,
00363 sglBound::IntersectResultEnum &result);
00364 static void intersectTriangle4i(
00365 sglIntersect<T> &segset,
00366 sglSegment<T> &seg,
00367 const void *vtx0, const void *vtx1, const void *vtx2,
00368 sglBound::IntersectResultEnum &result);
00369 static void intersectTriangle4f(
00370 sglIntersect<T> &segset,
00371 sglSegment<T> &seg,
00372 const void *vtx0, const void *vtx1, const void *vtx2,
00373 sglBound::IntersectResultEnum &result);
00374 static void intersectTriangle4d(
00375 sglIntersect<T> &segset,
00376 sglSegment<T> &seg,
00377 const void *vtx0, const void *vtx1, const void *vtx2,
00378 sglBound::IntersectResultEnum &result);
00379
00380 private:
00381 static IntersectTriangleFunc s_isect_tri_func_table[24];
00382
00383 IntersectResult m_result;
00384 deque<sglNode*> m_path;
00385 };
00386
00387
00388
00389
00390
00391 typedef sglIntersect<float> sglIntersectf;
00392 typedef sglIntersect<double> sglIntersectd;
00393
00394 #endif