22 #ifndef __NDG_AABB_POLYGONSOUP_H_
23 #define __NDG_AABB_POLYGONSOUP_H_
25 #include "ndCoreStdafx.h"
28 #include "ndFastRay.h"
29 #include "ndFastAabb.h"
30 #include "ndIntersections.h"
31 #include "ndPolygonSoupDatabase.h"
36 #define D_CONCAVE_EDGE_MASK (1<<31)
37 #define D_FACE_CLIP_DIAGONAL_SCALE ndFloat32 (0.25f)
39 enum ndIntersectStatus
45 typedef ndIntersectStatus(*ndAaabbIntersectCallback) (
void*
const context,
46 const ndFloat32*
const polygon, ndInt32 strideInBytes,
47 const ndInt32*
const indexArray, ndInt32 indexCount, ndFloat32 hitDistance);
49 typedef ndFloat32(*ndRayIntersectCallback) (
void*
const context,
50 const ndFloat32*
const polygon, ndInt32 strideInBytes,
51 const ndInt32*
const indexArray, ndInt32 indexCount);
68 #define DG_INDEX_COUNT_BITS 6
82 inline ndUnsigned32 IsLeaf ()
const
84 return m_node & 0x80000000;
87 inline ndUnsigned32 GetCount()
const
90 return (m_node & (~0x80000000)) >> (32 - DG_INDEX_COUNT_BITS - 1);
93 inline ndUnsigned32 GetIndex()
const
96 return m_node & (~(-(1 << (32 - DG_INDEX_COUNT_BITS - 1))));
99 inline ndLeafNodePtr (ndUnsigned32 faceIndexCount, ndUnsigned32 faceIndexStart)
101 ndAssert (faceIndexCount < (1<<DG_INDEX_COUNT_BITS));
102 m_node = 0x80000000 | (faceIndexCount << (32 - DG_INDEX_COUNT_BITS - 1)) | faceIndexStart;
105 inline ndNode* GetNode (
const void*
const root)
const
107 return ((
ndNode*) root) + m_node;
121 inline ndFloat32 RayDistance (
const ndFastRay& ray,
const ndTriplex*
const vertexArray)
const
123 ndVector minBox (&vertexArray[m_indexBox0].m_x);
124 ndVector maxBox (&vertexArray[m_indexBox1].m_x);
125 minBox = minBox & ndVector::m_triplexMask;
126 maxBox = maxBox & ndVector::m_triplexMask;
127 return ray.BoxIntersect(minBox, maxBox);
130 inline ndFloat32 BoxPenetration (
const ndFastAabb& obb,
const ndTriplex*
const vertexArray)
const
132 ndVector p0 (&vertexArray[m_indexBox0].m_x);
133 ndVector p1 (&vertexArray[m_indexBox1].m_x);
134 p0 = p0 & ndVector::m_triplexMask;
135 p1 = p1 & ndVector::m_triplexMask;
138 ndAssert(maxBox.m_x >= minBox.m_x);
139 ndAssert(maxBox.m_y >= minBox.m_y);
140 ndAssert(maxBox.m_z >= minBox.m_z);
142 ndVector mask ((minBox * maxBox) < ndVector::m_zero);
143 ndVector dist (maxBox.GetMin (minBox.Abs()) & mask);
144 dist = dist.GetMin(dist.ShiftTripleRight());
145 dist = dist.GetMin(dist.ShiftTripleRight());
147 if (dist.GetScalar() > ndFloat32 (0.0f))
149 ndVector origin (ndVector::m_half * (p1 + p0));
150 ndVector size (ndVector::m_half * (p1 - p0));
152 origin = obb.UntransformVector(origin);
153 size = obb.m_absDir.RotateVector(size);
158 ndAssert(maxBox1.m_x >= minBox1.m_x);
159 ndAssert(maxBox1.m_y >= minBox1.m_y);
160 ndAssert(maxBox1.m_z >= minBox1.m_z);
161 ndVector mask1 ((minBox1 * maxBox1) < ndVector::m_zero);
162 ndVector dist1 (maxBox1.GetMin (minBox1.Abs()) & mask1);
163 dist1 = dist1.GetMin(dist1.ShiftTripleRight());
164 dist1 = dist1.GetMin(dist1.ShiftTripleRight());
165 dist = dist.GetMin(dist1);
169 ndVector p1p0((minBox.Abs()).GetMin(maxBox.Abs()).AndNot(mask));
170 dist = p1p0.DotProduct(p1p0);
171 dist = dist.Sqrt() * ndVector::m_negOne;
173 return dist.GetScalar();
178 ndVector p0 (&vertexArray[m_indexBox0].m_x);
179 ndVector p1 (&vertexArray[m_indexBox1].m_x);
180 p0 = p0 & ndVector::m_triplexMask;
181 p1 = p1 & ndVector::m_triplexMask;
185 ndFloat32 dist = ray.BoxIntersect(minBox, maxBox);
186 if (dist < ndFloat32 (1.0f))
188 ndVector origin (ndVector::m_half * (p1 + p0));
189 ndVector size (ndVector::m_half * (p1 - p0));
191 origin = obb.UntransformVector(origin);
192 size = obb.m_absDir.RotateVector(size);
198 ndFloat32 dist1 = obbRay.BoxIntersect(minBox1, maxBox1);
199 dist = (dist1 > ndFloat32 (1.0f)) ? dist1 : ndMax (dist1, dist);
206 ndLeafNodePtr m_left;
207 ndLeafNodePtr m_right;
217 D_CORE_API
virtual void Serialize (
const char*
const path)
const;
220 D_CORE_API
virtual void Deserialize (
const char*
const path);
227 D_CORE_API
void CalculateAdjacent ();
228 D_CORE_API
virtual ndVector ForAllSectorsSupportVertex(
const ndVector& dir)
const;
229 D_CORE_API
virtual void ForAllSectorsRayHit (
const ndFastRay& ray, ndFloat32 maxT, ndRayIntersectCallback callback,
void*
const context)
const;
230 D_CORE_API
virtual void ForAllSectors (
const ndFastAabb& obbAabb,
const ndVector& boxDistanceTravel, ndFloat32 maxT, ndAaabbIntersectCallback callback,
void*
const context)
const;
231 D_CORE_API
virtual void ForThisSector(
const ndAabbPolygonSoup::ndNode*
const node,
const ndFastAabb& obbAabb,
const ndVector& boxDistanceTravel, ndFloat32 maxT, ndAaabbIntersectCallback callback,
void*
const context)
const;
244 return node->m_left.IsLeaf() ? nullptr : node->m_left.GetNode(m_aabb);
251 return node->m_right.IsLeaf() ? nullptr : node->m_right.GetNode(m_aabb);
259 p0 = p0 & ndVector::m_triplexMask;
260 p1 = p1 & ndVector::m_triplexMask;
264 ndNodeBuilder* BuildTopDown (ndNodeBuilder*
const leafArray, ndInt32 firstBox, ndInt32 lastBox, ndNodeBuilder**
const allocator)
const;
265 ndFloat32 CalculateFaceMaxDiagonal (
const ndVector*
const vertex, ndInt32 indexCount,
const ndInt32*
const indexArray)
const;
266 static ndIntersectStatus CalculateAllFaceEdgeNormals(
void*
const context,
const ndFloat32*
const polygon, ndInt32 strideInBytes,
const ndInt32*
const indexArray, ndInt32 indexCount, ndFloat32 hitDistance);
270 ndInt32 m_nodesCount;
271 ndInt32 m_indexCount;