00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef __SIM_ColliderBFA_h__
00017 #define __SIM_ColliderBFA_h__
00018
00019 #include "SIM_API.h"
00020
00021 #include "SIM_Collider.h"
00022 #include "SIM_BVTree.h"
00023 #include "SIM_Names.h"
00024 #include "SIM_Isect.h"
00025 #include "SIM_Utils.h"
00026
00027 #include <GU/GU_DetailHandle.h>
00028
00029 #include <UT/UT_IntArray.h>
00030 #include <UT/UT_Vector3.h>
00031 #include <UT/UT_Vector3Array.h>
00032
00033 class SIM_BVTree;
00034 class SIM_TriangulatedGeometry;
00035 class BV_LeafIterator;
00036 class SIM_Geometry;
00037 class simBVCallback;
00038
00039
00040
00041
00042
00043
00044
00045 struct sim4PointEvent
00046 {
00047 sim4PointEvent()
00048 { }
00049 sim4PointEvent(const SIM_Time &time, const UT_Vector3 &normal,
00050 fpreal distance)
00051 : myTime(time),
00052 myNormal(normal),
00053 myDistance(distance)
00054 { }
00055
00056 SIM_Time myTime;
00057
00058
00059
00060
00061
00062
00063 UT_Vector3 myNormal;
00064 fpreal myDistance;
00065 };
00066
00067 struct simFaceVertexEvent : public sim4PointEvent
00068 {
00069 simFaceVertexEvent()
00070 { }
00071
00072 simFaceVertexEvent(const SIM_Time &time, const UT_Vector3 &normal,
00073 fpreal distance,
00074 bool firstIsFace, int vid,
00075 fpreal bary0, fpreal bary1)
00076 : sim4PointEvent(time, normal, distance),
00077 myFirstIsFace(firstIsFace),
00078 myVid(vid)
00079 {
00080 myBary[0] = bary0;
00081 myBary[1] = bary1;
00082 }
00083
00084
00085 UT_Vector3 getBaryV3() const
00086 {
00087 return UT_Vector3(myBary[0], myBary[1], 1-myBary[0]-myBary[1]);
00088 }
00089
00090
00091
00092 bool myFirstIsFace;
00093
00094 int myVid;
00095
00096 fpreal myBary[2];
00097 };
00098
00099 struct simEdgeEdgeEvent : public sim4PointEvent
00100 {
00101 simEdgeEdgeEvent()
00102 { }
00103
00104 simEdgeEdgeEvent(const SIM_Time &time, const UT_Vector3 &normal,
00105 fpreal distance,
00106 int eid0, int eid1,
00107 fpreal bary0, fpreal bary1)
00108 : sim4PointEvent(time, normal, distance)
00109 {
00110 myEid[0] = eid0;
00111 myEid[1] = eid1;
00112 myBary[0] = bary0;
00113 myBary[1] = bary1;
00114 }
00115
00116
00117 int myEid[2];
00118
00119
00120 fpreal myBary[2];
00121 };
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 class SIM_API SIM_ColliderBFA : public SIM_Collider
00151 {
00152 public:
00153 class simDetail;
00154 class simPrimPairEvent;
00155
00156
00157
00158
00159 void getCollisionsDeformable(
00160 SIM_IsectArray &collisions,
00161 SIM_Object &object, SIM_Object &affector,
00162 fpreal tolerance,
00163 const SIM_Time &startTime,
00164 const SIM_Time &endTime,
00165 bool doRepulsion) const
00166 {
00167 getCollisions(collisions, object, affector,
00168 tolerance, startTime, endTime,
00169 true, doRepulsion,
00170 NULL, NULL, NULL, NULL);
00171 }
00172
00173
00174
00175
00176
00177
00178 void getCollisionsRigid(
00179 SIM_IsectArray &collisions,
00180 SIM_Object &object, SIM_Object &affector,
00181 fpreal tolerance,
00182 const SIM_Time &startTime,
00183 const SIM_Time &endTime,
00184 const UT_DMatrix4 &startXformA,
00185 const UT_DMatrix4 &startXformB,
00186 const UT_DMatrix4 &endXformA,
00187 const UT_DMatrix4 &endXformB) const
00188 {
00189 getCollisions(collisions, object, affector,
00190 tolerance, startTime, endTime,
00191 false, false,
00192 &startXformA, &startXformB,
00193 &endXformA, &endXformB);
00194 }
00195
00196 protected:
00197 explicit SIM_ColliderBFA(const SIM_DataFactory *factory);
00198 virtual ~SIM_ColliderBFA();
00199
00200 virtual SIM_BVTree::simBVTreeType
00201 getBVTreeType() const;
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 virtual BV_LeafIterator
00216 *createLeafIt(const SIM_Object &object,
00217 const SIM_Time ×tep,
00218 bool startPosOnly) const = 0;
00219
00220
00221
00222 virtual void convertLeafToPrim(
00223 const BV_LeafIterator &leafIt,
00224 int leafId,
00225 int &outPrimId, int &outEdgeId) const = 0;
00226
00227
00228
00229
00230
00231 virtual fpreal getLeafRadius(
00232 const BV_LeafIterator &leafIt,
00233 int leafId) const = 0;
00234
00235
00236
00237
00238 virtual bool getEventsAtSurface() const;
00239
00240 void retrieveGeometry(const SIM_Object &object,
00241 GU_ConstDetailHandle &outGdh,
00242 const GU_Detail *&outGdp,
00243 UT_DMatrix4 *outEndTransform,
00244 const SIM_TriangulatedGeometry **tgeo) const;
00245
00246
00247
00248
00249
00250
00251 bool testFaceSharesPoint(const simDetail &sdpF,
00252 int pidF0, int pidF1, int pidF2,
00253 const simDetail &sdpV,
00254 int pidV) const;
00255
00256
00257
00258
00259
00260
00261 bool testEdgesSharePoint(const simDetail &sdpA,
00262 int pidA0, int pidA1,
00263 const simDetail&sdpB,
00264 int pidB0, int pidB1) const;
00265
00266
00267
00268
00269
00270 virtual bool doCheckTangle() const
00271 { return false; }
00272
00273 virtual void intersectPrims(simPrimPairEvent &event,
00274 simDetail &sdpA, simDetail &sdpB,
00275 fpreal tolerance, bool doRepulsion,
00276 bool selfCollision) const;
00277 private:
00278
00279
00280 void getCollisions(
00281 SIM_IsectArray &collisions,
00282 SIM_Object &object, SIM_Object &affector,
00283 fpreal tolerance,
00284 const SIM_Time &startTime,
00285 const SIM_Time &endTime,
00286 bool isDeformable,
00287 bool doRepulsion,
00288 const UT_DMatrix4 *startXformA,
00289 const UT_DMatrix4 *startXformB,
00290 const UT_DMatrix4 *endXformA,
00291 const UT_DMatrix4 *endXformB) const;
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 int intersectFaceVertex(simPrimPairEvent &event,
00303 simDetail &sdp0, simDetail &sdp1,
00304 bool firstIsFace, int vid,
00305 bool searchInTimestep,
00306 fpreal tol) const;
00307
00308
00309
00310
00311
00312
00313
00314
00315 int intersectEdgeEdge(simPrimPairEvent &event,
00316 int eid0, simDetail &sdp0,
00317 int eid1, simDetail &sdp1,
00318 bool searchInTimestep,
00319 fpreal tol) const;
00320
00321
00322
00323
00324
00325 bool intersectTriTri(simPrimPairEvent &event,
00326 const simDetail &sdp0,
00327 const simDetail &sdp1,
00328 bool &searchInTimestep,
00329 fpreal tol) const;
00330
00331
00332
00333
00334
00335
00336 SIM_BVTree *getBVTree(BV_LeafIterator* &leafIt,
00337 SIM_Object &object,
00338 const SIM_Time ×tep,
00339 bool startPosOnly,
00340 bool isDeformable) const;
00341
00342 DECLARE_STANDARD_GETCASTTOTYPE();
00343 DECLARE_CLASSNAME(SIM_ColliderBFA, SIM_Collider);
00344
00345 friend class simBVCallback;
00346 };
00347
00348 class SIM_API SIM_ColliderBFA::simDetail
00349 {
00350 public:
00351
00352
00353 simDetail(int objectId,
00354 const GU_Detail &gdp,
00355 const SIM_TriangulatedGeometry *tgeo,
00356 const UT_DMatrix4 &startXform,
00357 const UT_DMatrix4 &endXform,
00358 const SIM_Time &startTime,
00359 const SIM_Time &endTime);
00360
00361 int getObjectId() const
00362 { return myObjectId; }
00363 const GU_Detail &getGdp() const
00364 { return myGdp; }
00365 bool operator==(const simDetail &rhs) const
00366 { return &myGdp == &rhs.myGdp; }
00367
00368 const SIM_Time &getStartTime() const
00369 { return myStartTime; }
00370 const SIM_Time &getEndTime() const
00371 { return myEndTime; }
00372 const
00373 SIM_Time getTimestep() const
00374 { return myEndTime - myStartTime; }
00375
00376
00377 int getTriPointId(int fid, int vid) const
00378 {
00379 UT_ASSERT_P(fid >= 0);
00380 UT_ASSERT_P(vid >= 0 && vid < 3);
00381 return myTriPointIds(fid*3 + vid);
00382 }
00383
00384 int getPrimPointId(int fid, int vid) const;
00385 bool hasTriEdgeIds() const
00386 {
00387 return myTriEdgeIds.entries() > 0;
00388 }
00389 int getTriEdgeId(int fid, int vid) const
00390 {
00391 UT_ASSERT_P(fid >= 0);
00392 UT_ASSERT_P(vid >= 0 && vid < 3);
00393 return myTriEdgeIds(fid*3 + vid);
00394 }
00395
00396
00397
00398
00399
00400
00401 int getFusePointId(int pid) const
00402 {
00403 return myFusePointIds(pid);
00404 }
00405 bool hasFusePointIds() const
00406 {
00407 return myFusePointIds.entries() > 0;
00408 }
00409
00410 UT_Vector3 getDetailPointPos(int pid) const;
00411
00412 const UT_Vector3&getPointVel(int pid) const
00413 { return myVel(pid); }
00414 float getPointMass(int pid) const;
00415 const UT_Vector3&getPointStartPos(int pid) const
00416 { return myStartPos(pid); }
00417 const UT_Vector3&getPointEndPos(int pid) const
00418 { return myEndPos(pid); }
00419 UT_Vector3 getPointPos(int pid, const SIM_Time &time) const;
00420 UT_Vector3 getTriBaryPos(int primId,
00421 const UT_Vector3 &baryV3,
00422 const SIM_Time &time) const;
00423 UT_Vector3 getTriBaryVel(int primId,
00424 const UT_Vector3 &baryV3) const;
00425 fpreal getTriBaryMass(int primId,
00426 const UT_Vector3 &baryV3) const;
00427
00428 UT_Vector3 getTriEdgePos(int primId, int eid, fpreal bary,
00429 const SIM_Time &time) const;
00430
00431 UT_Vector3 getPrimEdgePos(int primId, int eid, fpreal bary,
00432 const SIM_Time &time) const;
00433 UT_Vector3 getTriStartBaryCenter(int primId) const;
00434
00435
00436
00437 bool setPointChecked(int primIdA, const simDetail &sdpB,
00438 int pidB);
00439
00440
00441
00442 bool setEdgeChecked(int eidA, const simDetail &sdpB, int eidB);
00443
00444 protected:
00445
00446
00447 GB_AttributeRef myAttMass;
00448
00449 private:
00450 int myObjectId;
00451 const GU_Detail &myGdp;
00452 SIM_EdgeData myEdgeData;
00453
00454
00455
00456
00457 UT_IntArray myTriEdgeIds;
00458 const SIM_TriangulatedGeometry *myTgeo;
00459 UT_DMatrix4 myStartXform, myEndXform;
00460 SIM_Time myStartTime;
00461 SIM_Time myEndTime;
00462
00463
00464
00465
00466
00467 UT_Vector3Array myStartPos;
00468 UT_Vector3Array myEndPos;
00469 UT_Vector3Array myVel;
00470 UT_IntArray myTriPointIds;
00471 UT_IntArray myFusePointIds;
00472
00473
00474
00475
00476 UT_RefArray<UT_IntArray> myPointsChecked;
00477
00478
00479
00480 UT_RefArray<UT_IntArray> myEdgesChecked;
00481 };
00482
00483
00484 class SIM_API SIM_ColliderBFA::simPrimPairEvent
00485 {
00486 public:
00487 simPrimPairEvent(int primId0, int primId1,
00488 int edgeId0, int edgeId1,
00489 fpreal radius0, fpreal radius1,
00490 int &adjacent);
00491
00492 int myPrimId[2];
00493 int myEdgeId[2];
00494 fpreal myRadii[2];
00495
00496
00497 int &myAdjacent;
00498 UT_RefArray<simEdgeEdgeEvent> myEdgeEdgeEvents;
00499 UT_RefArray<simFaceVertexEvent> myFaceVertexEvents;
00500 UT_RefArray<SIM_Isect> myTriTriEvents;
00501 };
00502
00503
00504 #endif