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 _SO_INTERSECTION_DETECTION_ACTION_
00026 #define _SO_INTERSECTION_DETECTION_ACTION_
00027
00028
00029
00030
00031
00032 #include <Inventor/actions/SoAction.h>
00033 #include <Inventor/actions/SoSubAction.h>
00034 #include <Inventor/SoType.h>
00035 #include <Inventor/SbViewportRegion.h>
00036 #include <Inventor/SoPrimitiveVertex.h>
00037
00038
00039
00040
00041
00042
00043
00047 typedef SbBool SoIntersectionFilterCB(void *userData,
00048 const SoPath *p1,
00049 const SoPath *p2);
00050 struct SoIntersectingPrimitive {
00052 enum PrimitiveType {
00054 SEGMENT = 2,
00056 LINE_SEGMENT = 2,
00058 TRIANGLE = 3
00059 };
00063 SoPath *path;
00067 PrimitiveType type;
00071 SbVec3f vertex[3];
00075 SbVec3f xf_vertex[3];
00076 };
00077
00101 class SoIntersectionDetectionAction : public SoAction
00102 {
00103 SO_ACTION_HEADER(SoIntersectionDetectionAction);
00104
00105 public:
00106
00107
00109 enum Resp {
00111 NEXT_PRIMITIVE,
00113 NEXT_SHAPE,
00115 ABORT
00116 };
00117
00122 typedef Resp SoIntersectionCB(void *userData,
00123 const SoIntersectingPrimitive *,
00124 const SoIntersectingPrimitive *);
00125
00129 SoIntersectionDetectionAction ();
00133 ~SoIntersectionDetectionAction();
00134
00135
00136 void apply(SoNode *node);
00137 void apply(SoPath *path);
00138 void apply(const SoPathList &pathList, SbBool obeysRules = FALSE);
00139
00145 void setFilterCallback(SoIntersectionFilterCB *newFilterCB, void *data=NULL);
00146
00151 void addIntersectionCallback (SoIntersectionCB* f, void* userData = NULL);
00152
00157 void removeIntersectionCallback(SoIntersectionCB* f, void* userData = NULL);
00158
00159
00161 enum Axis {
00163 X_AXIS = 1,
00165 Y_AXIS = 2,
00167 Z_AXIS = 4
00168 };
00169
00171 enum Position {
00173 BEGIN,
00175 END
00176 };
00177 #ifndef HIDDEN_FROM_DOC
00178 struct ShapeInformationItem {
00179 SoPath *path;
00180 float xMin, yMin, zMin;
00181 float xMax, yMax, zMax;
00182 };
00183
00184 struct CoupleTableItem {
00185 int overlapFlags;
00186 float xMin, yMin, zMin;
00187 float xMax, yMax, zMax;
00188 };
00189
00190 struct ActiveListItem {
00191 int shapeIndex;
00193 enum Position position;
00194 SbBool toRemove;
00195 float x, y, z;
00196 };
00197 static float m_fIntersectEpsilon;
00198 #endif // HIDDEN_FROM_DOC
00199
00200 #if 1 SoDEPRECATED
00208 static void setIntersectEpsilon(float epsilon);
00209 SoDEPRECATED
00214 static float getIntersectEpsilon();
00215
00216 #endif
00218 private:
00219
00220 static void initClass();
00221 static void exitClass();
00222
00223 private :
00224 friend class SoCollisionManager;
00225
00226
00227
00228
00229 SbBool m_new_test;
00230 SbBool m_new_shapes;
00231
00232
00233 SoIntersectionFilterCB* filterCB;
00234 void* userDataFilterCB;
00235 SoIntersectionCB* intersectionCB;
00236 void* userDataIntersectionCB;
00237 void* m_callback_list;
00238 Resp response;
00239 Resp invokeCallbacks (const SoIntersectingPrimitive* p1,
00240 const SoIntersectingPrimitive* p2);
00241
00242
00243 int shapeCount;
00244 SbViewportRegion viewportRegion;
00245 int shapeInformationSize;
00246 int shapeInformationReservedSize;
00247 ShapeInformationItem* shapeInformation;
00248 int coupleTableSize;
00249 int coupleTableReservedSize;
00250 CoupleTableItem* coupleTable;
00251 int activeListSize;
00252 int activeListReservedSize;
00253 ActiveListItem* activeList;
00254 int primitiveTableSize;
00255 int primitiveTableReservedSize;
00256 SoIntersectingPrimitive* primitiveTable;
00257 int currentShapeIndex1;
00258 int currentShapeIndex2;
00259 CoupleTableItem* currentCouple;
00260
00261
00262 void seek (SoSearchAction* search);
00263
00264 void shapeInformationDestroy();
00265 void shapeInformationClear();
00266 void shapeInformationAddItem(SoPath *path);
00267
00268 void coupleTableDestroy();
00269 void coupleTableClear();
00270 CoupleTableItem * coupleTableGetItem(int shapeIndex1, int shapeIndex2);
00271 void coupleTableSetOverlaping(int shapeIndex1, int shapeIndex2,
00272 Axis axis);
00273 void coupleTableUpdate(enum Axis axis);
00274
00275 void activeListDestroy();
00276 void activeListClear();
00277 void activeListAddItem(int shapeIndex);
00278 void activeListSort(int (*compareFunction)(void const *, void const *));
00279 static int activeListXCompare(void const *pointer1, void const *pointer2);
00280 static int activeListYCompare(void const *pointer1, void const *pointer2);
00281 static int activeListZCompare(void const *pointer1, void const *pointer2);
00282 void activeListClean();
00283 void primitiveTableBuild();
00284 void primitiveTableDestroy();
00285 void primitiveTableClear();
00286 void primitiveTableReserveSpace();
00287 void primitiveTableAddTriangle (SoCallbackAction *action,
00288 const SoPrimitiveVertex *vertex1,
00289 const SoPrimitiveVertex *vertex2,
00290 const SoPrimitiveVertex *vertex3);
00291 void primitiveTableAddLineSegment(SoCallbackAction *action,
00292 const SoPrimitiveVertex *vertex1,
00293 const SoPrimitiveVertex *vertex2);
00294 void shapesCollisionTest(int shapeIndex1, int shapeIndex2);
00295
00296 void triangleCollisionTest(SoCallbackAction *action,
00297 const SoPrimitiveVertex *vertex1,
00298 const SoPrimitiveVertex *vertex2,
00299 const SoPrimitiveVertex *vertex3);
00300 void lineSegmentCollisionTest(SoCallbackAction *action,
00301 const SoPrimitiveVertex *vertex1,
00302 const SoPrimitiveVertex *vertex2);
00303 static SbBool isTriangleIntersectSegment(const SbVec3f &A,
00304 const SbVec3f &B,
00305 const SbVec3f &C,
00306 const SbVec3f &D,
00307 const SbVec3f &E);
00308 static SbBool isTriangleIntersectTriangle (const SoIntersectingPrimitive &triangle1,
00309 const SoIntersectingPrimitive &triangle2);
00310 static SbBool isSegmentIntersectSegment (const SbVec3f &A,
00311 const SbVec3f &B,
00312 const SbVec3f &C,
00313 const SbVec3f &D);
00314
00315
00316 static void primitiveTableAddTriangleCB (void *userData,
00317 SoCallbackAction *action,
00318 const SoPrimitiveVertex *vertex1,
00319 const SoPrimitiveVertex *vertex2,
00320 const SoPrimitiveVertex *vertex3)
00321 { ((SoIntersectionDetectionAction*) userData)->
00322 primitiveTableAddTriangle (action, vertex1, vertex2, vertex3); }
00323 static void primitiveTableAddLineSegmentCB (void *userData,
00324 SoCallbackAction *action,
00325 const SoPrimitiveVertex *vertex1,
00326 const SoPrimitiveVertex *vertex2)
00327 { ((SoIntersectionDetectionAction*) userData)->
00328 primitiveTableAddLineSegment (action, vertex1, vertex2); }
00329 static void triangleCollisionTestCB (void *userData,
00330 SoCallbackAction *action,
00331 const SoPrimitiveVertex *vertex1,
00332 const SoPrimitiveVertex *vertex2,
00333 const SoPrimitiveVertex *vertex3)
00334 { ((SoIntersectionDetectionAction*) userData)->
00335 triangleCollisionTest (action, vertex1, vertex2, vertex3); }
00336 static void lineSegmentCollisionTestCB (void *userData,
00337 SoCallbackAction *action,
00338 const SoPrimitiveVertex *vertex1,
00339 const SoPrimitiveVertex *vertex2)
00340 { ((SoIntersectionDetectionAction*) userData)->
00341 lineSegmentCollisionTest (action, vertex1, vertex2); }
00342
00343
00344 void quickSort(void *array, int nElm, int elmSize,
00345 int (*compare)(void const *, void const *),
00346 char *tmp);
00347 void sort(void *array, int nElm, int elmSize,
00348 int (*compare)(void const *, void const *));
00349
00350 static SbThreadMutex classMutex;
00351 };
00352
00353
00354 #endif // _SO_INTERSECTION_DETECTION_ACTION_
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364