79 unsigned int* prims = (
unsigned int*)malloc(
initialMesh->size() *
sizeof(
unsigned int));
80 for (
unsigned int i = 0; i <
initialMesh->size(); i++)
91 for (
int i = 0; i < 3; ++i)
98 for (
int i = 0; i < 3; ++i)
113 unsigned int* newPrims = (
unsigned int*)malloc(nbPrims *
sizeof(
unsigned int));
114 for (
unsigned int i = 0; i < nbPrims; i++)
116 newPrims[i] = prims[i];
118 node.
createLeaf(nbPrims, newPrims[0], newPrims);
129 unsigned int n0(0), n1(0);
130 unsigned int *prims0 =
nullptr, *prims1 =
nullptr;
131 prims0 = (
unsigned int*)malloc(nbPrims *
sizeof(
unsigned int));
132 prims1 = (
unsigned int*)malloc(nbPrims *
sizeof(
unsigned int));
136 float split = (localBox.
pMin[axis] + localBox.
pMax[axis]) / 2.f;
138 for (
unsigned int i = 0; i < nbPrims; i++)
143 prims0[n0] = prims[i];
148 prims1[n1] = prims[i];
153 prims0[n0] = prims[i];
155 prims1[n1] = prims[i];
163 size_t indexCurrentNode =
tableNode.size();
168 firstBox.
pMax[axis] = split;
171 tableNode.at(indexCurrentNode).createNode(axis, split,
static_cast<unsigned int>(
tableNode.size()));
174 secondBox.
pMin[axis] = split;
181 decimal tmin = NAN, tmax = NAN, intermin = -1.;
208 int axis = node->
getAxe();
212 KDNode *firstChild =
nullptr, *secondChild =
nullptr;
217 firstChild = node + 1;
223 secondChild = node + 1;
227 if (tplane > tmax || tplane < 0)
231 else if (tplane < tmin)
238 todo[todoPos].
node = secondChild;
239 todo[todoPos].
tmin = tplane;
240 todo[todoPos].
tmax = tmax;
250 if (nPrimitives == 1)
256 if (prim->
getIntersection(*
r, currentIntersection) && currentIntersection.
t > 0.0001)
258 result.push_back(currentIntersection);
261 intermin = (*pLeafTreatmentFunction)(result, intermin);
264 else if (nPrimitives > 1)
266 unsigned int* prims = node->
getPrims();
267 for (
unsigned int i = 0; i < nPrimitives; i++)
274 if (prim->
getIntersection(*
r, currentIntersection) && currentIntersection.
t > 0.0001)
276 result.push_back(currentIntersection);
278 intermin = (*pLeafTreatmentFunction)(result, intermin);
287 node = todo[todoPos].
node;
288 tmin = todo[todoPos].
tmin;
289 tmax = todo[todoPos].
tmax;
303 for (
unsigned int i = 0; i <
tableNode.size(); i++)
307 if (
tableNode.at(i).getNbPrimitives() == 1)
321 unsigned int nbPrims,
unsigned int* prims)
326 unsigned int* newPrims = (
unsigned int*)malloc(nbPrims *
sizeof(
unsigned int));
327 for (
unsigned int i = 0; i < nbPrims; i++)
329 newPrims[i] = prims[i];
331 node.
createLeaf(nbPrims, newPrims[0], newPrims);
342 unsigned int n0(0), n1(0);
343 unsigned int *prims0 =
nullptr, *prims1 =
nullptr;
344 prims0 = (
unsigned int*)malloc(nbPrims *
sizeof(
unsigned int));
345 prims1 = (
unsigned int*)malloc(nbPrims *
sizeof(
unsigned int));
349 int bestAxis = -1, bestOffset = -1;
350 float bestCost = std::numeric_limits<float>::infinity();
352 float totalSA = (2.f * (d.x * d.y + d.x * d.z + d.y * d.z));
353 float invTotalSA = 1.f / totalSA;
356 if (d.x > d.y && d.x > d.z)
362 axis = (d.y > d.z) ? 1 : 2;
368 for (
int i = 0; i < static_cast<int>(nbPrims); ++i)
375 std::sort(&edges[axis][0], &edges[axis][2 * nbPrims]);
377 int nBelow = 0, nAbove = nbPrims;
378 for (
int i = 0; i < static_cast<int>(2 * nbPrims); ++i)
384 float edget = edges[axis][i].
t;
385 if (edget > localBox.
pMin[axis] && edget < localBox.
pMax[axis])
388 int otherAxis[3][2] = {{1, 2}, {0, 2}, {0, 1}};
389 int otherAxis0 = otherAxis[axis][0];
390 int otherAxis1 = otherAxis[axis][1];
391 float belowSA = 2 * (d[otherAxis0] * d[otherAxis1] +
392 (edget - localBox.
pMin[axis]) * (d[otherAxis0] + d[otherAxis1]));
393 float aboveSA = 2 * (d[otherAxis0] * d[otherAxis1] +
394 (localBox.
pMax[axis] - edget) * (d[otherAxis0] + d[otherAxis1]));
395 float pBelow = belowSA * invTotalSA;
396 float pAbove = aboveSA * invTotalSA;
397 float eb = (nAbove == 0 || nBelow == 0) ?
emptyBonus : 0.f;
414 if (bestAxis == -1 && retries < 2)
417 axis = (axis + 1) % 3;
421 float split = edges[bestAxis][bestOffset].
t;
423 for (
unsigned int i = 0; i < nbPrims; i++)
426 if (
triangle->getBBox().pMax[axis] < split)
428 prims0[n0] = prims[i];
431 else if (
triangle->getBBox().pMin[axis] > split)
433 prims1[n1] = prims[i];
438 prims0[n0] = prims[i];
440 prims1[n1] = prims[i];
448 size_t indexCurrentNode =
tableNode.size();
453 firstBox.
pMax[axis] = split;
456 tableNode.at(indexCurrentNode).createNode(axis, split,
static_cast<unsigned int>(
tableNode.size()));
459 secondBox.
pMin[axis] = split;
Base class for accelerators.
BBox globalBox
Global bounding box.
Definition of a bounding box which is aligned along the axis (BBox AABB).
vec3 pMax
Upper point of the BBox.
bool IntersectP(vec3 rayPos, vec3 rayDir, decimal *hitt0=NULL, decimal *hitt1=NULL) const
Compute the intersection between a Ray and this BBox.
vec3 pMin
Lower point of the BBox.
int MaximumExtend() const
Return the index of the dominant direction (maximal dimension). Index is 0 for x, 1 for y,...
int realMaxProfondeur
Real max depth.
std::vector< BBox > tableBox
Bounding boxes list of the tree.
float emptyBonus
Parameter for best splitting.
virtual decimal traverse(Ray *r, std::list< Intersection > &result) const
Run this accelerator.
void generateSAHKdTree(int currentProfondeur, BBox &localBox, TaBRecBoundEdge *edges[3], unsigned int nbPrims, unsigned int *prims)
Generate the tree with SAH (Surface Area Heuristic) method.
int maxPrimPerLeaf
Maximal primitives per leaf.
virtual ~KdtreeAccelerator()
Destructor.
float isectCost
Parameter for best splitting.
KdtreeAccelerator(std::vector< Shape * > *_initialMesh=NULL, BBox _globalBox=BBox())
Constructor.
std::vector< Shape * > * initialMesh
Pointer to the mesh.
float traversalCost
Parameter for best splitting.
int maxProfondeur
Maximal depth.
bool alreadyFail
Unused attribute.
virtual bool build()
Build this accelerator.
void generateMidKdTree(int currentProfondeur, BBox &localBox, unsigned int nbPrims, unsigned int *prims)
Generate the tree by middle subdivision.
void print()
Print the tree (not implemented yet)
unsigned int nbFail
Unused attribute.
std::vector< InfoPrim > tablePrimitive
List of primitives and their bounding box.
bool trace
Unused attribute.
std::vector< KDNode > tableNode
: Describes a ray by a pair of unsigned int. The first one gives the source number (in the range 0-40...
decimal getMaxt() const
Return maxt.
vec3 getPosition() const
Return starting point ray.
vec3 getDirection() const
Return direction of the ray.
base class for shapes (Cylindre, Mesh, Sphere, Triangle,...)
virtual bool getIntersection(Ray &ray, Intersection &inter)
Get the Intersection between a ray and this shape.
BBox getBBox()
Return the bounding box.
base_vec3< decimal > vec3
Node structure (optimized to be stored on 2 bytes)
unsigned int AboveChild()
Return second child.
int flag
0 : node, x axis, 1 : node, y axis, 2 : node, z axis, 3 : leaf. 2 bits used
unsigned int * prims
Leaf : array containing primitives indexes.
int getAxe()
Return the axis number of the separator plane (node)
unsigned int nbPrims
Leaf : number of primitives. Use 30 bits integer.
unsigned int secondChild
Node : the first child is just after current node, second one is further.
void createLeaf(unsigned int _nbPrims, unsigned int _firstIndex, unsigned int *_prims)
Leaf initialization.
unsigned int firstIndex
Leaf : index of the first primitive in the list.
float getAxeValue()
Return the axis value of the separator plane (node)
bool isLeaf()
Return true if the node is a leaf.
void createNode(int axis, float _split, unsigned int nextChild)
Node initialization.
unsigned int getFirstIndex()
Return the index of the first node primitive (all)
float split
Node : separator axis value.
unsigned int * getPrims()
Get the primitives.
unsigned int getNbPrimitives()
Return primitives number.