File indexing completed on 2025-01-18 10:03:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef _BVH_BinaryTree_Header
0017 #define _BVH_BinaryTree_Header
0018
0019 #include <BVH_QuadTree.hxx>
0020
0021 #include <deque>
0022 #include <tuple>
0023
0024
0025 template<class T, int N>
0026 class BVH_Tree<T, N, BVH_BinaryTree> : public BVH_TreeBase<T, N>
0027 {
0028 public:
0029
0030 typedef typename BVH_TreeBase<T, N>::BVH_VecNt BVH_VecNt;
0031
0032 public:
0033
0034
0035 BVH_Tree() : BVH_TreeBase<T, N>() { }
0036
0037
0038 void SetOuter (const int theNodeIndex) { BVH::Array<int, 4>::ChangeValue (this->myNodeInfoBuffer, theNodeIndex).x() = 1; }
0039
0040
0041 void SetInner (const int theNodeIndex) { BVH::Array<int, 4>::ChangeValue (this->myNodeInfoBuffer, theNodeIndex).x() = 0; }
0042
0043
0044
0045 template<int K>
0046 int Child (const int theNodeIndex) const { return BVH::Array<int, 4>::Value (this->myNodeInfoBuffer, theNodeIndex)[K + 1]; }
0047
0048
0049
0050 template<int K>
0051 int& ChangeChild (const int theNodeIndex) { return BVH::Array<int, 4>::ChangeValue (this->myNodeInfoBuffer, theNodeIndex)[K + 1]; }
0052
0053
0054
0055 template<int K>
0056 int& Child (const int theNodeIndex) { return BVH::Array<int, 4>::ChangeValue (this->myNodeInfoBuffer, theNodeIndex)[K + 1]; }
0057
0058 public:
0059
0060
0061 void Clear()
0062 {
0063 this->myDepth = 0;
0064 BVH::Array<T, N>::Clear (this->myMinPointBuffer);
0065 BVH::Array<T, N>::Clear (this->myMaxPointBuffer);
0066 BVH::Array<int, 4>::Clear(this->myNodeInfoBuffer);
0067 }
0068
0069
0070
0071 void Reserve (const int theNbNodes)
0072 {
0073 BVH::Array<T, N>::Reserve (this->myMinPointBuffer, theNbNodes);
0074 BVH::Array<T, N>::Reserve (this->myMaxPointBuffer, theNbNodes);
0075 BVH::Array<int, 4>::Reserve (this->myNodeInfoBuffer, theNbNodes);
0076 }
0077
0078
0079 int AddLeafNode (const BVH_VecNt& theMinPoint,
0080 const BVH_VecNt& theMaxPoint,
0081 const int theBegElem,
0082 const int theEndElem)
0083 {
0084 BVH::Array<T, N>::Append (this->myMinPointBuffer, theMinPoint);
0085 BVH::Array<T, N>::Append (this->myMaxPointBuffer, theMaxPoint);
0086 BVH::Array<int, 4>::Append (this->myNodeInfoBuffer, BVH_Vec4i (1, theBegElem, theEndElem, 0));
0087 return BVH::Array<int, 4>::Size (this->myNodeInfoBuffer) - 1;
0088 }
0089
0090
0091 int AddInnerNode (const BVH_VecNt& theMinPoint,
0092 const BVH_VecNt& theMaxPoint,
0093 const int theLftChild,
0094 const int theRghChild)
0095 {
0096 BVH::Array<T, N>::Append (this->myMinPointBuffer, theMinPoint);
0097 BVH::Array<T, N>::Append (this->myMaxPointBuffer, theMaxPoint);
0098 BVH::Array<int, 4>::Append (this->myNodeInfoBuffer, BVH_Vec4i (0, theLftChild, theRghChild, 0));
0099 return BVH::Array<int, 4>::Size (this->myNodeInfoBuffer) - 1;
0100 }
0101
0102
0103 int AddLeafNode (const BVH_Box<T, N>& theAABB,
0104 const int theBegElem,
0105 const int theEndElem)
0106 {
0107 return AddLeafNode (theAABB.CornerMin(), theAABB.CornerMax(), theBegElem, theEndElem);
0108 }
0109
0110
0111 int AddInnerNode (const BVH_Box<T, N>& theAABB,
0112 const int theLftChild,
0113 const int theRghChild)
0114 {
0115 return AddInnerNode (theAABB.CornerMin(), theAABB.CornerMax(), theLftChild, theRghChild);
0116 }
0117
0118
0119 int AddLeafNode (const int theBegElem,
0120 const int theEndElem)
0121 {
0122 BVH::Array<int, 4>::Append (this->myNodeInfoBuffer, BVH_Vec4i (1, theBegElem, theEndElem, 0));
0123 return BVH::Array<int, 4>::Size (this->myNodeInfoBuffer) - 1;
0124 }
0125
0126
0127 int AddInnerNode (const int theLftChild,
0128 const int theRghChild)
0129 {
0130 BVH::Array<int, 4>::Append (this->myNodeInfoBuffer, BVH_Vec4i (0, theLftChild, theRghChild, 0));
0131 return BVH::Array<int, 4>::Size (this->myNodeInfoBuffer) - 1;
0132 }
0133
0134 public:
0135
0136
0137
0138
0139 T EstimateSAH() const;
0140
0141
0142
0143 BVH_Tree<T, N, BVH_QuadTree>* CollapseToQuadTree() const;
0144
0145 };
0146
0147 namespace BVH
0148 {
0149
0150
0151 template<class T, int N>
0152 void EstimateSAH (const BVH_Tree<T, N, BVH_BinaryTree>* theTree, const int theNode, T theProb, T& theSAH)
0153 {
0154 BVH_Box<T, N> aBox (theTree->MinPoint (theNode),
0155 theTree->MaxPoint (theNode));
0156
0157 if (theTree->IsOuter (theNode))
0158 {
0159 theSAH += theProb * (theTree->EndPrimitive (theNode) - theTree->BegPrimitive (theNode) + 1);
0160 }
0161 else
0162 {
0163 theSAH += theProb * static_cast<T> (2.0);
0164
0165 BVH_Box<T, N> aLftBox (theTree->MinPoint (theTree->template Child<0> (theNode)),
0166 theTree->MaxPoint (theTree->template Child<0> (theNode)));
0167
0168 if (theProb > 0.0)
0169 {
0170 EstimateSAH (theTree, theTree->template Child<0> (theNode),
0171 theProb * aLftBox.Area() / aBox.Area(), theSAH);
0172 }
0173
0174 BVH_Box<T, N> aRghBox (theTree->MinPoint (theTree->template Child<1> (theNode)),
0175 theTree->MaxPoint (theTree->template Child<1> (theNode)));
0176
0177 if (theProb > 0.0)
0178 {
0179 EstimateSAH (theTree, theTree->template Child<1> (theNode),
0180 theProb * aRghBox.Area() / aBox.Area(), theSAH);
0181 }
0182 }
0183 }
0184 }
0185
0186
0187
0188
0189
0190 template<class T, int N>
0191 T BVH_Tree<T, N, BVH_BinaryTree>::EstimateSAH() const
0192 {
0193 T aSAH = static_cast<T> (0.0);
0194 BVH::EstimateSAH<T, N> (this, 0, static_cast<T> (1.0), aSAH);
0195 return aSAH;
0196 }
0197
0198
0199
0200
0201
0202 template<class T, int N>
0203 BVH_Tree<T, N, BVH_QuadTree>* BVH_Tree<T, N, BVH_BinaryTree>::CollapseToQuadTree() const
0204 {
0205 BVH_Tree<T, N, BVH_QuadTree>* aQBVH = new BVH_Tree<T, N, BVH_QuadTree>;
0206
0207 if (this->Length() == 0)
0208 {
0209 return aQBVH;
0210 }
0211
0212 std::deque<std::pair<int, int> > aQueue (1, std::make_pair (0, 0));
0213
0214 for (int aNbNodes = 1; !aQueue.empty();)
0215 {
0216 const std::pair<int, int> aNode = aQueue.front();
0217
0218 BVH::Array<T, N>::Append (aQBVH->myMinPointBuffer, BVH::Array<T, N>::Value (this->myMinPointBuffer, std::get<0> (aNode)));
0219 BVH::Array<T, N>::Append (aQBVH->myMaxPointBuffer, BVH::Array<T, N>::Value (this->myMaxPointBuffer, std::get<0> (aNode)));
0220
0221 BVH_Vec4i aNodeInfo;
0222 if (this->IsOuter (std::get<0> (aNode)))
0223 {
0224 aNodeInfo = BVH_Vec4i (1 ,
0225 this->BegPrimitive (std::get<0> (aNode)), this->EndPrimitive (std::get<0> (aNode)), std::get<1> (aNode) );
0226 }
0227 else
0228 {
0229 NCollection_Vector<int> aGrandChildNodes;
0230
0231 const int aLftChild = Child<0> (std::get<0> (aNode));
0232 const int aRghChild = Child<1> (std::get<0> (aNode));
0233 if (this->IsOuter (aLftChild))
0234 {
0235 aGrandChildNodes.Append (aLftChild);
0236 }
0237 else
0238 {
0239 aGrandChildNodes.Append (Child<0> (aLftChild));
0240 aGrandChildNodes.Append (Child<1> (aLftChild));
0241 }
0242
0243 if (this->IsOuter (aRghChild))
0244 {
0245 aGrandChildNodes.Append (aRghChild);
0246 }
0247 else
0248 {
0249 aGrandChildNodes.Append (Child<0> (aRghChild));
0250 aGrandChildNodes.Append (Child<1> (aRghChild));
0251 }
0252
0253 for (int aNodeIdx = 0; aNodeIdx < aGrandChildNodes.Size(); ++aNodeIdx)
0254 {
0255 aQueue.push_back (std::make_pair (aGrandChildNodes (aNodeIdx), std::get<1> (aNode) + 1));
0256 }
0257
0258 aNodeInfo = BVH_Vec4i (0 ,
0259 aNbNodes, aGrandChildNodes.Size() - 1, std::get<1> (aNode) );
0260
0261 aQBVH->myDepth = Max (aQBVH->myDepth, std::get<1> (aNode) + 1);
0262
0263 aNbNodes += aGrandChildNodes.Size();
0264 }
0265
0266 BVH::Array<int, 4>::Append (aQBVH->myNodeInfoBuffer, aNodeInfo);
0267 aQueue.pop_front();
0268 }
0269
0270 return aQBVH;
0271 }
0272
0273 #endif