00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef __BV_OBBTree_h__
00016 #define __BV_OBBTree_h__
00017
00018 #include "BV_API.h"
00019 #include "BV_Tree.h"
00020 #include <UT/UT_RefArray.h>
00021 #include <UT/UT_LinkListT.h>
00022
00023 #include <set>
00024 #include <map>
00025
00026 class UT_BoundingBox;
00027 class UT_IStream;
00028 struct bvTransform;
00029 class BV_OBB_Extra;
00030
00031
00032 #define CONVEX_HULL_DEBUG 0
00033
00034
00035 class BV_CHTriangle;
00036 class BV_CHEdgeInfo;
00037
00038
00039 typedef UT_RefArray<UT_Vector4> TPointArray;
00040 typedef UT_RefArray<int> TPointIndexArray;
00041 typedef UT_RefArray<fpreal> TFloatArray;
00042 typedef UT_LinkListT<BV_CHTriangle*> TTriArray;
00043
00044
00045
00046 struct BV_CHSimpleTriangle
00047 {
00048 UT_Vector3 myVertices[3];
00049 };
00050 typedef UT_RefArray<BV_CHSimpleTriangle> TSimpleTriangleArray;
00051
00052
00053 class BV_CHEdgeInfo
00054 {
00055 public:
00056 BV_CHEdgeInfo();
00057
00058 void reset(void);
00059
00060 bool operator()(const BV_CHEdgeInfo& s1, const BV_CHEdgeInfo& s2) const;
00061
00062 uint myV1, myV2;
00063 int myUsedCount;
00064
00065
00066
00067
00068
00069 bool myIsV1Starting;
00070 };
00071 typedef std::set<BV_CHEdgeInfo,BV_CHEdgeInfo> TEdgeInfoSet;
00072
00073 class BV_CHPointInfo
00074 {
00075 public:
00076 BV_CHPointInfo();
00077 BV_CHPointInfo(const UT_Vector3 point_in);
00078
00079
00080 void addPoint(const UT_Vector3 point_in);
00081
00082
00083 UT_Vector3 getAveragePoint(void) const;
00084
00085 bool operator()(const UT_Vector3& s1, const UT_Vector3& s2) const;
00086
00087 private:
00088 UT_Vector3 myAccumPosition;
00089 int myAccumCount;
00090 };
00091 typedef std::map<UT_Vector3, BV_CHPointInfo, BV_CHPointInfo> TPointInfoMap;
00092
00093 class BV_CHDataManager
00094 {
00095 public:
00096
00097
00098 BV_CHDataManager(const TPointArray& points_in);
00099
00100
00101 const BV_CHEdgeInfo* findEdge(int curr_v1_idx, int curr_v2_idx) const;
00102
00103
00104 const BV_CHEdgeInfo* edgeTraversalBegin(void);
00105 const BV_CHEdgeInfo* edgeTraversalNext(void);
00106
00107
00108 void edgeSanityCheck(void);
00109
00110
00111
00112 void setAboutToReset(void);
00113
00114
00115 void reset(void);
00116
00117
00118
00119 void weldPoints(const TPointArray& points_in, TPointArray& merged_pts_out);
00120
00121 TPointArray& getPoints(void)
00122 { return myPoints; }
00123 bool getDoRestart(void) const
00124 { return myDoRestart; }
00125
00126
00127 void onTriangleDeleted(BV_CHTriangle* triangle_in);
00128
00129
00130 void onTriangleCreated(BV_CHTriangle* triangle_in);
00131
00132
00133 fpreal jigglePointTetra(BV_CHTriangle *coplanar_triangle, int iPointIndex);
00134
00135 private:
00136
00137
00138 TPointArray myPoints;
00139
00140
00141 TEdgeInfoSet myEdges;
00142 TEdgeInfoSet::iterator myTraversalIt;
00143
00144 bool myDoRestart;
00145 bool myIsAboutToReset;
00146
00147
00148 TFloatArray myPointJiggleMults;
00149
00150 #if CONVEX_HULL_DEBUG
00151 int myDBJigglePath;
00152 #endif
00153
00154 };
00155
00156 class BV_CHTriangle
00157 {
00158 public:
00159
00160 BV_CHTriangle(BV_CHDataManager& parent_manager, uint point1_idx,uint point2_idx,uint point3_idx);
00161 ~BV_CHTriangle();
00162
00163
00164
00165 void markDeleted(bool do_call_manager = true);
00166
00167
00168 inline fpreal getSignedDistance(const uint point_index);
00169
00170
00171 bool canSee(const uint point_index);
00172
00173
00174
00175
00176 void associatePoints(TPointIndexArray& points_in, bool do_ignore_restart_flag);
00177
00178
00179 bool getIsBad(void) const;
00180
00181
00182 void clearAssocPoints(void);
00183
00184
00185 bool findMostDistantAssocPoint(uint& point_idx_out);
00186
00187
00188 void getNormal(UT_Vector3 &normal);
00189
00190
00191 void getAssocPoints(TPointIndexArray& points_idx_out);
00192 void printAssocPoints(void);
00193
00194 bool getIsDeleted(void) const
00195 { return myIsDeleted; }
00196 inline uint getVertex(int index) const
00197 { return myVertices[index]; }
00198
00199 private:
00200 BV_CHDataManager *myManager;
00201 uint myVertices[3];
00202 bool myIsDeleted;
00203
00204 UT_Vector3 myCachedNormal;
00205 bool myIsNormalValid;
00206
00207 fpreal myIterationJiggleMult;
00208
00209
00210 TPointIndexArray myAssocPoints;
00211
00212 TPointArray& myAllPoints;
00213 };
00214
00215
00216
00217 class BV_API BV_OBB
00218 {
00219 public:
00220 BV_OBB(int startLeaf, int numLeaves);
00221 BV_OBB(const BV_OBB &);
00222 ~BV_OBB();
00223
00224 bool isLeaf() const;
00225
00226 void save(ostream &os, bool onlyStructure) const;
00227 static BV_OBB *load(UT_IStream &is, bool onlyStructure);
00228
00229 int64 getMemoryUsage() const;
00230
00231
00232 bool isDisabled() const
00233 { return mySize < 0; }
00234
00235
00236
00237 UT_Matrix3 myRot;
00238
00239 UT_Vector3 myTrans;
00240
00241
00242 UT_Vector3 myRadii;
00243
00244
00245 fpreal mySize;
00246
00247
00248 int myStartLeaf;
00249
00250 int myNumLeaves;
00251
00252 BV_OBB *myLeft, *myRight;
00253
00254 BV_OBB_Extra*myExtra;
00255
00256 void *myUserData;
00257
00258 private:
00259
00260 BV_OBB &operator=(const BV_OBB &);
00261 };
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 class BV_API BV_OBBTree : public BV_Tree
00274 {
00275 public:
00276 typedef BV_Tree BaseClass;
00277
00278 BV_OBBTree();
00279 BV_OBBTree(const BV_OBBTree &);
00280 virtual ~BV_OBBTree();
00281
00282 BV_OBBTree &operator=(const BV_OBBTree &);
00283
00284 virtual const char *getType() const;
00285 virtual const BV_Tree
00286 *castTo(const char *type) const;
00287 virtual BV_Tree *castTo(const char *type);
00288
00289
00290
00291
00292
00293 void buildLazy(BV_LeafIterator &leafIt)
00294 {
00295 buildInternal(leafIt, true);
00296 }
00297
00298 void getRootOBB(UT_Matrix4 &xform, UT_Vector3 &radii) const;
00299
00300
00301
00302
00303
00304 void setUseConvexHull(bool bValue);
00305 bool getUseConvexHull(void);
00306
00307 protected:
00308 class bvLeaf
00309 {
00310 public:
00311
00312
00313
00314
00315 float sortkey;
00316 int leafId;
00317 UT_Vector3 barycenter;
00318 };
00319
00320 virtual BV_Tree *cloneSubclass() const;
00321 virtual int64 getMemoryUsageSubclass() const;
00322 virtual int getNumLeavesSubclass() const;
00323
00324
00325 virtual void saveSubclass(ostream &os, bool onlyStructure) const;
00326 virtual bool loadSubclass(UT_IStream &is, bool onlyStructure);
00327
00328
00329 virtual void buildSubclass(BV_LeafIterator &leafIt)
00330 {
00331 buildInternal(leafIt, false);
00332 }
00333 virtual void updateExtentsSubclass(BV_LeafIterator &leafIt);
00334
00335 virtual Status intersectSubclass(BV_Callback &callback,
00336 const BV_Tree &treeb,
00337 const UT_DMatrix4 &startxforma,
00338 const UT_DMatrix4 &startxformb,
00339 const UT_DMatrix4 &endxforma,
00340 const UT_DMatrix4 &endxformb,
00341 fpreal tol) const;
00342
00343 BV_OBB *getRoot()
00344 {
00345 return myRoot;
00346 }
00347 void buildInternal(BV_LeafIterator &leafIt, bool lazy);
00348
00349
00350 BV_OBB *createTree(int startprim, int numleaves,
00351 const UT_Matrix3 &rootBasis,
00352 const UT_Vector3 &rootPos, int depth = -1);
00353 void createChildren(BV_OBB &root, int depth = -1);
00354 bool updateExtentsRecurse(BV_OBB &node,
00355 const UT_Matrix3 &parentBasis,
00356 const UT_Vector3 &parentPos);
00357
00358 void getBounds(const UT_Matrix3 &basis,
00359 UT_BoundingBox &bbox, bool &firstPrim);
00360
00361
00362
00363 void calcOBB(BV_OBB &node);
00364
00365
00366 void calcSize(BV_OBB &node);
00367
00368
00369
00370
00371
00372 bool computeConvexHull(const TPointArray& source_points_in, TSimpleTriangleArray& final_triangles_out);
00373 bool doConvexHullIteration(BV_CHDataManager& data_manager, TTriArray& working_triangles);
00374
00375 bool intersectRecurse(BV_Callback &callback,
00376 const BV_OBBTree &treeb,
00377 const BV_OBB &a, const BV_OBB &b,
00378 const bvTransform &t1, const bvTransform &t2,
00379 const bvTransform &t3, const bvTransform &t4,
00380 fpreal tol, int identities) const;
00381
00382
00383 static int compareLeaves(const void *t1, const void *t2);
00384
00385 void calculateSortKeys(bvLeaf *prims, int numleaves,
00386 UT_Matrix3 &basis, int axis) const;
00387
00388 BV_OBB *myRoot;
00389 UT_RefArray<bvLeaf> myLeaves;
00390 BV_LeafIterator *myLeafIt;
00391
00392 bool myUseConvexHullForBBoxes;
00393 };
00394
00395
00396 class BV_OBB_Extra
00397 {
00398 public:
00399 UT_Matrix3 rot;
00400 UT_Vector3 trans;
00401 };
00402
00403
00404 struct BV_API bvTransform
00405 {
00406
00407 UT_Matrix3 R;
00408
00409 UT_Vector3 T;
00410
00411 UT_DMatrix4 xform[2];
00412
00413
00414 void updateL(const UT_Matrix3 &rot,
00415 const UT_Vector3 &trans,
00416 bvTransform &xform) const;
00417
00418 void updateR(const UT_Matrix3 &rot,
00419 const UT_Vector3 &trans,
00420 bvTransform &xform) const;
00421
00422
00423 void update(const UT_Matrix3 &ra,
00424 const UT_Matrix3 &rb,
00425 const UT_Vector3 &ta,
00426 const UT_Vector3 &tb,
00427 const UT_DMatrix4 &xforma,
00428 const UT_DMatrix4 &xformb,
00429 const UT_DMatrix4 &xformc,
00430 const UT_DMatrix4 &xformd);
00431 };
00432
00433
00434 #endif