[Fix] Missing tris bug.
[Add] Do empty space cutoff in BIH tree builder.
This commit is contained in:
parent
94a979d850
commit
1b16cb2f70
@ -10,6 +10,8 @@
|
|||||||
#define MAX_LEAF_PRIMS 2
|
#define MAX_LEAF_PRIMS 2
|
||||||
#define MAX_DEPTH 20
|
#define MAX_DEPTH 20
|
||||||
#define MAX_SPLITPOS_RETRIES 32
|
#define MAX_SPLITPOS_RETRIES 32
|
||||||
|
#define MIN_SPACE_CUTOFF 0.33
|
||||||
|
#define EPSILON 0.00001
|
||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -100,8 +102,8 @@ GeomTree::GeomTree(int numVerts, int numTris, float* vertices, int* indices) : m
|
|||||||
m_aabb.max.x,
|
m_aabb.max.x,
|
||||||
m_aabb.max.y,
|
m_aabb.max.y,
|
||||||
m_aabb.max.z);
|
m_aabb.max.z);
|
||||||
m_nodes = new BIHNode[numTris*2];
|
m_nodes = new BIHNode[numTris*4];
|
||||||
m_nodesAllocSize = numTris*2;
|
m_nodesAllocSize = numTris*4;
|
||||||
m_nodesAllocPos = 0;
|
m_nodesAllocPos = 0;
|
||||||
m_triAllocPos = 0;
|
m_triAllocPos = 0;
|
||||||
|
|
||||||
@ -133,6 +135,82 @@ void GeomTree::BihTreeGhBuild(BIHNode* a_node, Aabb& a_box, Aabb& a_splitBox, in
|
|||||||
int s1count, s2count, splitAxis, attempt;
|
int s1count, s2count, splitAxis, attempt;
|
||||||
attempt = 0;
|
attempt = 0;
|
||||||
|
|
||||||
|
Aabb realAabb;
|
||||||
|
realAabb.min = vector3d(FLT_MAX, FLT_MAX, FLT_MAX);
|
||||||
|
realAabb.max = vector3d(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||||
|
/* Make actual objects aabb, to see if we can usefully cut off some empty space. */
|
||||||
|
for(int i = 0; i < a_prims; i++) {
|
||||||
|
vector3d v0 = vector3d(&m_vertices[3*m_indices[prim_lump[i]->triIdx]]);
|
||||||
|
vector3d v1 = vector3d(&m_vertices[3*m_indices[prim_lump[i]->triIdx+1]]);
|
||||||
|
vector3d v2 = vector3d(&m_vertices[3*m_indices[prim_lump[i]->triIdx+2]]);
|
||||||
|
realAabb.Update(v0);
|
||||||
|
realAabb.Update(v1);
|
||||||
|
realAabb.Update(v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("Empty space: (%f,%f,%f), (%f,%f,%f)\n",
|
||||||
|
(realAabb.min - a_box.min).x,
|
||||||
|
(realAabb.min - a_box.min).y.
|
||||||
|
(realAabb.min - a_box.min).z,
|
||||||
|
(a_box.max - realAabb.max).x,
|
||||||
|
(a_box.max - realAabb.max).y,
|
||||||
|
(a_box.max - realAabb.max).z);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
vector3d boxSize = a_box.max - a_box.min;
|
||||||
|
vector3d lowSpace = realAabb.min - a_box.min;
|
||||||
|
vector3d highSpace = a_box.max - realAabb.max;
|
||||||
|
/* Choose best. */
|
||||||
|
float bestCost = 0;
|
||||||
|
int axis = -1;
|
||||||
|
int isTop = false;
|
||||||
|
for(int i = 0; i < 3; i++) {
|
||||||
|
float cost = (lowSpace[i]+EPSILON) / boxSize[i];
|
||||||
|
if(cost > bestCost) {
|
||||||
|
bestCost = cost;
|
||||||
|
axis = i;
|
||||||
|
isTop = false;
|
||||||
|
}
|
||||||
|
cost = (highSpace[i]+EPSILON) / boxSize[i];
|
||||||
|
if(cost > bestCost) {
|
||||||
|
bestCost = cost;
|
||||||
|
axis = i;
|
||||||
|
isTop = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if(axis != -1) printf("Best is axis %d on %s (cost %f%%)\n", axis, (isTop ? "top" : "botton"), bestCost*100);
|
||||||
|
/* Cut off whitespace. */
|
||||||
|
if((bestCost > MIN_SPACE_CUTOFF) && (bestCost < 1.0f)) {
|
||||||
|
printf("Clicing off %f%%\n", bestCost*100);
|
||||||
|
a_node->SetLeaf(false);
|
||||||
|
a_node->SetAxis(axis);
|
||||||
|
|
||||||
|
Aabb newAabb = a_box;
|
||||||
|
if(isTop) {
|
||||||
|
newAabb.max[axis] = realAabb.max[axis]+EPSILON;
|
||||||
|
a_node->SetSplitPos1(realAabb.max[axis]);
|
||||||
|
a_node->SetSplitPos2(newAabb.max[axis]);
|
||||||
|
|
||||||
|
Aabb splitBox = newAabb;
|
||||||
|
left->SetList(prim_lump[0]);
|
||||||
|
BihTreeGhBuild(left, newAabb, splitBox, a_depth+1, a_prims);
|
||||||
|
right->SetLeaf(true);
|
||||||
|
} else {
|
||||||
|
newAabb.min[axis] = realAabb.min[axis] - EPSILON;
|
||||||
|
a_node->SetSplitPos1(a_box.min[axis]);
|
||||||
|
a_node->SetSplitPos2(newAabb.min[axis]);
|
||||||
|
|
||||||
|
Aabb splitBox = newAabb;
|
||||||
|
right->SetList(prim_lump[0]);
|
||||||
|
BihTreeGhBuild(right, newAabb, splitBox, a_depth+1, a_prims);
|
||||||
|
left->SetLeaf(true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
splitAxis = 0;
|
splitAxis = 0;
|
||||||
vector3d splitBoxSize = a_splitBox.max - a_splitBox.min;
|
vector3d splitBoxSize = a_splitBox.max - a_splitBox.min;
|
||||||
@ -223,7 +301,10 @@ void GeomTree::BihTreeGhBuild(BIHNode* a_node, Aabb& a_box, Aabb& a_splitBox, in
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//printf(prims total %d, left %d, right %d\n", a_prims, s1count, s2count);
|
|
||||||
|
/* Traversal algo can't handle completely flat cells. */
|
||||||
|
splitPos1 += EPSILON;
|
||||||
|
splitPos2 -= EPSILON;
|
||||||
|
|
||||||
a_node->SetLeaf(false);
|
a_node->SetLeaf(false);
|
||||||
a_node->SetAxis(splitAxis);
|
a_node->SetAxis(splitAxis);
|
||||||
@ -369,7 +450,6 @@ pop_bstack:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EPSILON 0.00001f
|
|
||||||
void GeomTree::RayTriIntersect(const vector3f& origin, const vector3f& dir, int triIdx, isect_t* isect) {
|
void GeomTree::RayTriIntersect(const vector3f& origin, const vector3f& dir, int triIdx, isect_t* isect) {
|
||||||
const vector3f a(&m_vertices[3*m_indices[triIdx]]);
|
const vector3f a(&m_vertices[3*m_indices[triIdx]]);
|
||||||
const vector3f b(&m_vertices[3*m_indices[triIdx+1]]);
|
const vector3f b(&m_vertices[3*m_indices[triIdx+1]]);
|
||||||
|
Loading…
Reference in New Issue
Block a user