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