Text archives Help
- From: bigler@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r1002 - in trunk: Model/Groups Model/Readers scenes
- Date: Thu, 6 Apr 2006 16:49:47 -0600 (MDT)
Author: bigler
Date: Thu Apr 6 16:49:46 2006
New Revision: 1002
Modified:
trunk/Model/Groups/CMakeLists.txt
trunk/Model/Groups/KDTree2.cc
trunk/Model/Groups/KDTree2.h
trunk/Model/Groups/KDTreeLoaderIW.cc
trunk/Model/Readers/IW.cc
trunk/Model/Readers/IW.h
trunk/scenes/iwviewer.cc
Log:
Model/Groups/CMakeLists.txt
Added KDTree2.{cc,h}
Model/Groups/KDTree2.cc
Model/Groups/KDTree2.h
Loads data from IWObject and IWNode.
Intersection and shading seem to work properly, although there are
some stippled triangles. Those are present in the WaldTriangle
version (which I stole the intersection code from), so I'm inclined
to think it comes from that.
Model/Groups/KDTreeLoaderIW.cc
Moved the bsp file parsing stuff to IW.{h,cc}.
Model/Readers/IW.cc
Model/Readers/IW.h
Added file parsing stuff for IW's kd-trees.
scenes/iwviewer.cc
You can now load in kd-trees by specifying a -bsp <filename> on the
command line.
Modified: trunk/Model/Groups/CMakeLists.txt
==============================================================================
--- trunk/Model/Groups/CMakeLists.txt (original)
+++ trunk/Model/Groups/CMakeLists.txt Thu Apr 6 16:49:46 2006
@@ -22,6 +22,8 @@
Groups/KDTreeLoader.h
Groups/KDTreeLoaderIW.cc
Groups/KDTreeLoaderIW.h
+ Groups/KDTree2.cc
+ Groups/KDTree2.h
Groups/PsiGammaTable.cc
Groups/PsiGammaTable.h
Groups/RealisticBvh.cc
Modified: trunk/Model/Groups/KDTree2.cc
==============================================================================
--- trunk/Model/Groups/KDTree2.cc (original)
+++ trunk/Model/Groups/KDTree2.cc Thu Apr 6 16:49:46 2006
@@ -27,16 +27,121 @@
*/
#include <Model/Groups/KDTree2.h>
+#include <Interface/RayPacket.h>
+#include <Model/Intersections/AxisAlignedBox.h>
+#include <Core/Color/ColorSpace.h>
+#include <Model/Readers/IW.h>
+#include <MantaTypes.h>
+
+#include <Core/Math/MiscMath.h>
+
+#include <stdlib.h>
+
+#include <stack>
+
+using namespace Manta;
+using namespace SCIRun;
+
+KDTree2::KDTree2(Material* material_in)
+ : PrimitiveCommon( material_in ),
+
+ triangles(NULL), num_tris(0),
+ tri_indices(NULL), num_tri_indices(0),
+ group_ids(NULL),
+ group_colors(NULL), num_groups(0)
+{
+}
+
+int
+KDTree2::loadIW(IWObject* iw, IWTree* tree) {
+ // Allocate memory
+ reserveTriangles(iw->triangles.size());
+ reserveTriangleIndices(tree->num_tri_indices);
+ reserveGroupIDs();
+ reserveGroupColors(iw->shaders.size());
+ unsigned int num_nodes = tree->num_nodes + tree->num_empty_nodes;
+ Node* nodes = static_cast<Node*>(malloc(num_nodes*sizeof(Node)));
+ rootNode = nodes;
+
+ bbox.reset();
+
+ // Load in the triangles
+ for(size_t ti = 0; ti < iw->triangles.size(); ++ti) {
+ Vector va(iw->va(ti));
+ Vector vb(iw->vb(ti));
+ Vector vc(iw->vc(ti));
+
+ // Do bounding box extension
+ bbox.extendByPoint(va);
+ bbox.extendByPoint(vb);
+ bbox.extendByPoint(vc);
+
+ // Create the triangle and copy it over
+ Triangle tri(va, vc, vb);
+ triangles[ti] = tri;
+
+ // Copy of the color id
+ group_ids[ti] = iw->triangles[ti][3];
+ }
+
+ // Load in the colors
+ for(size_t ci = 0; ci < iw->shaders.size(); ++ci) {
+ group_colors[ci] = iw->shaders[ci];
+ }
+
+ // Load in the kd-tree data
+ Node* current_node = nodes;
+ unsigned int current_node_index = 0;
+ unsigned int current_tri_index = 0;
+
+ IWNode* top = tree->head;
+ top->index = current_node_index++;
+ std::stack<IWNode*> nodestack;
+ nodestack.push(top);
+ while(!nodestack.empty()) {
+ Node& node = nodes[top->index];
+ if (top->isNode()) {
+ // Node
+ node.type = top->flags;
+ node.split = top->split;
+
+ // Assign the left and right nodes
+ node.leftChild = nodes + current_node_index;
+ // For relative references you can do this:
+ // node.leftChild = current_node_index - top->index;
+
+ ASSERT(top->left);
+ ASSERT(top->right);
+ top->left->index = current_node_index++;
+ top->right->index = current_node_index++;
+
+ // Push the children on the stack
+ nodestack.push(top->left);
+ nodestack.push(top->right);
+
+ } else {
+ // Leaf
+ node.type = 3;
+ node.listLen = top->num_tris;
+ node.listBegin = current_tri_index;
+ unsigned int* tri_ids_p = tri_indices + current_tri_index;
+ for(unsigned int i = 0; i < node.listLen; ++i) {
+ *tri_ids_p = top->tri_ids[i];
+ ++tri_ids_p;
+ }
+ current_tri_index += node.listLen;
+ }
+ top = nodestack.top();
+ nodestack.pop();
+ }
+
+ return 0;
+}
KDTree2::Triangle::Triangle(const Vector& _p1,
const Vector& _p2,
const Vector& _p3)
{
- box.reset();
- box.extendByPoint(_p1);
- box.extendByPoint(_p2);
- box.extendByPoint(_p3);
-
Vector normal = Cross(_p2-_p1, _p3-_p1);
normal.normalize();
@@ -90,8 +195,6 @@
rays.computeInverseDirections();
rays.computeSigns();
- RayTriIntersectUserData isectData;
-
for(int i=rays.begin();i<rays.end();i++) {
Real minDist, maxDist;
@@ -106,26 +209,158 @@
// Determine the actual minimum distance.
minDist = SCIRun::Max( minDist, T_EPSILON );
maxDist = SCIRun::Min( maxDist, rays.getMinT(i) );
+ if (minDist > maxDist) continue;
- // Send the ray to the _intersect function.
- isectData.rayHitTriIndex = -1;
- isectData.duplicate = 0;
- intersect_node( rootNode, rays, i, isectData, context,
(float)minDist, (float)maxDist);
+ intersect_node( rootNode,
+ rays,
+ i,
+ (float)minDist,
+ (float)maxDist );
}
}
}
void
-KDTree2::computeNormal(const RenderContext& context, RayPacket &rays) const {
+KDTree2::intersect_node( Node* start_node, RayPacket& rays, int which,
+ float minDist, float maxDist ) const {
+ float near = minDist;
+ float far = maxDist;
+
+ Stack stack[MaxStackSize];
+ Stack *sptr = stack;
+
+ // mailBox.clear(); //...
+
+ RayPacketData* data = rays.data;
+ const int ray_signs[3] = { data->signs[0][which],
+ data->signs[1][which],
+ data->signs[2][which] };
+ const float origin[3] = { data->origin[0][which],
+ data->origin[1][which],
+ data->origin[2][which] };
+ const float direction[3] = { data->direction[0][which],
+ data->direction[1][which],
+ data->direction[2][which] };
+ const float invDir[3] = { data->inverseDirection[0][which],
+ data->inverseDirection[1][which],
+ data->inverseDirection[2][which] };
+ Node* node = start_node;
+
+ do {
+ while (node->type != 3 /* leaf */ ) {
+ int axis = node->type;
+ float dist = (node->split - origin[axis]) * invDir[axis];
+
+ Node* nearChild = node->leftChild + ray_signs[axis];
+ Node* farChild = node->leftChild + (1-ray_signs[axis]);
+
+ if (dist > far) // if interval (far end) is infront of the plane
+ {
+ node = nearChild;
+ continue;
+ }
+ if (dist < near) // KEEP THE ORDER OF COMPARISONS (nan's etc)
+ {
+ node = farChild;
+ continue;
+ }
+ // else: have to traverse both children
+ node = nearChild;
+
+ // push farchild [dist..far]
+ sptr->node = farChild;
+ sptr->far = far;
+ sptr++;
+ // go to nearchild [near...dist]
+ far = dist;
+ node = nearChild;
+ }
+
+ // now, have a leaf
+ if (node->listLen > 0) {
+ int hit_tri = -1;
+// fprintf(stderr, "node(%u): listBegin = %u, listLen = %u\n",
+// (rootNode-node)/sizeof(Node), node->listBegin,
node->listLen);
+ for (int tri_index=node->listBegin;
+ tri_index<node->listBegin+node->listLen;
+ ++tri_index) {
+ // intersectTriangle(....); // with mailboxing
+ const Triangle& tri = triangles[tri_indices[tri_index]];
+ const int axis = tri.k;
+ const int ku = (axis==2)?0:axis+1;
+ const int kv = (axis==0)?2:axis-1;
+
+ const float n_u = tri.n_u;
+ const float n_v = tri.n_v;
+ const float n_d = tri.n_d;
+
+ const float org_k = origin[axis];
+ const float org_ku = origin[ku];
+ const float org_kv = origin[kv];
+ const float f0 = n_d - (org_k + n_u * org_ku + n_v * org_kv);
+
+ const float dir_k = direction[axis];
+ const float dir_ku = direction[ku];
+ const float dir_kv = direction[kv];
+
+ const float nd0 = n_u * dir_ku + n_v * dir_kv + dir_k;
+ const float nd = 1.f/nd0;
+
+ const float f = f0 * nd;
+ // plane test
+ if ( f < T_EPSILON || f > data->minT[which] )
+ continue;
+
+ const float hu = org_ku + f*dir_ku;
+ const float hv = org_kv + f*dir_kv;
+ const float lambda = tri.b_d + hu*tri.b_nu + hv * tri.b_nv;
+
+ // barycentric test
+ if ( lambda < 0.f )
+ continue;
+
+ const float mue = tri.c_d + hu * tri.c_nu + hv * tri.c_nv;
+ if ( mue < 0.f || mue + lambda > 1.f )
+ continue;
+
+ if (rays.hit(which, f, getMaterial(), this, getTexCoordMapper())) {
+// if (tri_index > 11)
+// fprintf(stderr, "hit_tri = %d, tri_index = %d\n", hit_tri,
tri_index);
+ hit_tri = tri_indices[tri_index];
+ }
+ }
+ if (hit_tri >= 0) {
+ ScratchData sd;
+ sd.tri_index = hit_tri;
+ rays.scratchpad<ScratchData>(which) = sd;
+ }
+ if (data->minT[which] < far) return;
+ }
+
+ // pop item from stack:
+ // if stack is empty, we're done
+ if (sptr <= stack) // stack is empty
+ { return; };
+ // do actual popping
+ near = far; // next subtree's entry (near) is current subtree's exit(far)
+ sptr--;
+ far = sptr->far;
+ node = sptr->node;
+ } while (1);
+}
+
+
+void
+KDTree2::computeNormal(const RenderContext& context, RayPacket& rays) const {
RayPacketData* data = rays.data;
for ( int ray = rays.begin(); ray < rays.end(); ray++ ) {
const Triangle& tri =
triangles[rays.scratchpad<ScratchData>(ray).tri_index];
const int axis = tri.k;
- const int ku = (axis==2)?0:k+1;
- const int kv = (axis==0)?2:k-1;
- const flaot mult = tri.n_k;
+ const int ku = (axis==2)?0:axis+1;
+ const int kv = (axis==0)?2:axis-1;
+ const float mult = tri.n_k;
data->normal[axis][ray] = mult;
data->normal[ku][ray] = mult * tri.n_u;
@@ -133,6 +368,79 @@
}
rays.setFlag(RayPacket::HaveUnitNormals);
}
+
+// Returns 0 on success
+int
+KDTree2::reserveTriangles(size_t num_tris_in) {
+ triangles = static_cast<Triangle*>(malloc(num_tris_in*sizeof(Triangle)));
+ if (triangles) {
+ num_tris = num_tris_in;
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+// Returns 0 on success
+int
+KDTree2::reserveTriangleIndices(size_t num_tri_indices_in) {
+ tri_indices =
+ static_cast<unsigned int*>(malloc(num_tri_indices_in*sizeof(Triangle)));
+ if (tri_indices) {
+ num_tri_indices = num_tri_indices_in;
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+// Returns 0 on success
+int
+KDTree2::reserveGroupIDs() {
+ if (!num_tris)
+ // Haven't said how many triangles yet
+ return 1;
+ group_ids = static_cast<unsigned int*>(malloc(num_tris*sizeof(unsigned
int)));
+ if (!group_ids)
+ return 1;
+ return 0;
+}
+
+// Returns 0 on success
+int
+KDTree2::reserveGroupColors(unsigned int num_groups_in) {
+ group_colors = static_cast<Color*>(malloc(num_groups_in*sizeof(Color)));
+ if (group_colors) {
+ num_groups = num_groups_in;
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+void
+KDTree2Texture::mapValues(const RenderContext& context, RayPacket& rays,
+ Color results[]) const {
+ if (kdtree->group_ids && kdtree->group_colors) {
+ // Have group ids and colors
+ const unsigned int* group_ids = kdtree->group_ids;
+ const Color* group_colors = kdtree->group_colors;
+
+ for ( int ray = rays.begin(); ray < rays.end(); ++ray) {
+ unsigned int tri_index =
rays.scratchpad<KDTree2::ScratchData>(ray).tri_index;
+ const int group_id = group_ids[tri_index];
+ results[ray] = group_colors[group_id];
+ }
+ } else {
+ // No colors, so just assign something
+ Color default_color(RGBColor(0.7, 0.7, 0.7 ));
+ for ( int ray = rays.begin(); ray < rays.end(); ++ray) {
+ results[ray] = default_color;
+ }
+ }
+
+}
+
Modified: trunk/Model/Groups/KDTree2.h
==============================================================================
--- trunk/Model/Groups/KDTree2.h (original)
+++ trunk/Model/Groups/KDTree2.h Thu Apr 6 16:49:46 2006
@@ -32,22 +32,35 @@
#include <Model/Primitives/PrimitiveCommon.h>
#include <Core/Geometry/Vector.h>
#include <Core/Geometry/Ray.h>
+#include <Core/Geometry/BBox.h>
+#include <Interface/Texture.h>
namespace Manta {
+ class IWObject;
+ class IWTree;
+
class KDTree2 : public PrimitiveCommon {
public:
+
+ KDTree2(Material* material);
+ // Return 0 on success
+ int loadIW(IWObject*, IWTree*);
+ enum {
+ MaxStackSize = 128
+ };
+
struct Node {
union {
- Node *left_son; // rigth_son = left_son+1;
+ Node *leftChild; // rigth_son = left_son+1;
int listBegin;
};
union {
float split; // internal
int listLen; // leaf
- }
- char type; // 0=x,1=y,z=2,leaf=3
+ };
+ unsigned char type; // 0=x,1=y,z=2,leaf=3
};
class Triangle {
@@ -87,43 +100,46 @@
RayPacket &rays) const;
// Returns 0 on success
- int reserveTriangles(size_t num_tris_in) {
- triangles =
static_cast<Triangle*>(malloc(num_tris_in*sizeof(Triangle)));
- if (triangles) {
- num_tris = num_tris_in;
- return 0;
- } else {
- return 1;
- }
- }
-
- // Returns 0 on success
- int reserveTriangleIndices(size_t num_tri_indices_in) {
- tri_indicies =
- static_cast<Triangle*>(malloc(num_tri_indices_in*sizeof(Triangle)));
- if (tri_indicies) {
- num_tri_indices = num_tri_indices_in;
- return 0;
- } else {
- return 1;
- }
- }
-
+ int reserveTriangles(unsigned int num_tris_in);
+ int reserveTriangleIndices(unsigned int num_tri_indices_in);
+ int reserveGroupIDs();
+ int reserveGroupColors(unsigned int num_groups_in);
+
// Triangle list stuff
- Triangle* triangles;
- size_t num_tris;
- unsigned int* tri_indices;
- size_t num_tri_indices;
-
+ Triangle* triangles; // size == num_tris
+ unsigned int num_tris;
+ unsigned int* tri_indices; // size == num_tri_indices
+ unsigned int num_tri_indices;
+
+ // Group
+ unsigned int* group_ids; // size == num_tris;
+ // group_ids[i] = [0,num_groups-1]
+ Color* group_colors; // size == num_groups;
+ unsigned int num_groups;
// Root node
- Node* root_node;
+ Node* rootNode;
BBox bbox;
protected:
- void intersect_node();
+ void intersect_node(Node* start_node, RayPacket& rays, int which,
+ float minDist, float maxDist) const;
+
+ struct Stack {
+ Node* node;
+ float far;
+ };
+ };
+
+ class KDTree2Texture: public Texture<Color> {
+ public:
+ KDTree2Texture(): kdtree(0) {}
+
+ virtual void mapValues(const RenderContext& context, RayPacket& rays,
+ Color results[]) const;
+ KDTree2* kdtree;
};
} // end namespace Manta
Modified: trunk/Model/Groups/KDTreeLoaderIW.cc
==============================================================================
--- trunk/Model/Groups/KDTreeLoaderIW.cc (original)
+++ trunk/Model/Groups/KDTreeLoaderIW.cc Thu Apr 6 16:49:46 2006
@@ -101,66 +101,24 @@
*/
-struct IWNode {
- IWNode()
- : left(0), right(0), parent(0),
- split(0), flags(0),
- num_tris(0), tri_ids(0),
- index(0)
- {}
- IWNode(IWNode* parent)
- : left(0), right(0), parent(parent),
- split(0), flags(0),
- num_tris(0), tri_ids(0),
- index(0)
- {}
- ~IWNode() {
- if (left) delete left;
- if (right) delete right;
- if (tri_ids) delete[] tri_ids;
- }
-
- void setRight(IWNode* node) {
- right = node;
- flags |= KDNODE_RIGHT_CHILD_MASK;
- }
- void setLeft(IWNode* node) {
- left = node;
- flags |= KDNODE_LEFT_CHILD_MASK;
- }
- bool isNode() const {
- return flags & KDNODE_INTERNAL_MASK;
- }
- bool isLeaf() const {
- return (flags & KDNODE_INTERNAL_MASK) == 0;
- }
-
- IWNode *left, *right, *parent;
- float split;
- int flags;
- unsigned int num_tris;
- int* tri_ids;
- unsigned index;
-};
-
// Load the specified file (and associated kdtree files) using the
// given number of processors. The geometry should be found in
// geom_filename and the bsp data should be found in bsp_filename.
int Manta::Kdtree::loadIW( KDTreeData* kdtree, const char* geom_filename,
const char* bsp_filename, int np )
{
- FILE* bspf = fopen(bsp_filename, "r");
- if (!bspf) {
- fprintf(stderr, "Error: cannot open %s for loading\n",
bsp_filename);
- return LoadingProblem;
- }
IWObject* iw = IWObjectRead(geom_filename);
if (!iw) {
- fclose(bspf);
return LoadingProblem;
}
- // Allocate space for the triangles and read them in:
+ IWTree* tree = IWTreeRead(bsp_filename);
+ if (!tree) {
+ return LoadingProblem;
+ }
+
+
+ // Allocate space for the triangles
unsigned int num_tris = static_cast<unsigned int>(iw->triangles.size());
kdtree->tris = new VArray<Triangle>(num_tris);
kdtree->tris->setLen(num_tris);
@@ -220,6 +178,8 @@
}
}
+ delete iw;
+
// Copy the bounding box over.
kdtree->bbox = bbox;
cerr << "Model bounds: min: " << kdtree->bbox[0] << " max: " <<
kdtree->bbox[1] << "\n";
@@ -227,119 +187,28 @@
///////////////////////////////////////////////////////
// Load in the BSP stuff
- // First pass.
- //
// Count the number of triangle indecies and nodes needed.
- unsigned int num_tri_indicies = 0;
- unsigned int num_nodes = 0;
- // Buffer for line. This will be allocated by getline and
- // reallocated as needed. We will need to free it later, though.
- char* bline = NULL;
- size_t bline_len = 0;
-
- IWNode* head = 0;
- IWNode* top = head;
-
- while((getline(&bline, &bline_len, bspf)) != -1) {
-// fprintf (stderr, "line(%u): %s\n", bline_len, bline);
- // Check the first token
- char token[2];
- int num = sscanf(bline, "%1s", token);
- // fprintf(stderr, "num = %d, token = %s\n", num, token);
- if (strcmp(token, "N") == 0) {
- num_nodes ++;
-// fprintf(stderr, "Node %u found\n", num_nodes);
-
- IWNode* node = new IWNode(top);
- // Is this the first node?
- if (top) {
- if (top->left) {
- top->setRight(node);
- } else {
- top->setLeft(node);
- }
- } else {
- // Set the head to the first node
- head = node;
- }
- // Decend
- top = node;
+ unsigned int num_tri_indices = tree->num_tri_indices;
+ unsigned int num_nodes = tree->num_nodes;
- char axis_c;
- sscanf(bline, "%*s %c=%f,d=%*d", &axis_c, &(node->split));
-// fprintf(stderr, "axis = %c, split = %g\n", axis_c, node->split);
- switch (axis_c) {
- case 'x': node->flags |= 0; break;
- case 'y': node->flags |= 1; break;
- case 'z': node->flags |= 2; break;
- }
-
- } else if (strcmp(token, "L") == 0) {
- IWNode* node = new IWNode(top);
-
- if (top->left) {
- top->setRight(node);
- // Finish up this level
- while (top && top->right) {
- top = top->parent;
- }
- } else {
- top->setLeft(node);
- }
-
- // Grab how many objects we have
- sscanf(bline, "%*s %u", &(node->num_tris));
-// fprintf(stderr, "L %u\n", node->num_tris);
- num_tri_indicies += node->num_tris;
- if (node->num_tris) {
- num_nodes++;
-
- // If you ever change what type triIndices is you will need to
- // update this bit of code for the right type.
- int* tri_ids_p = node->tri_ids = new int[node->num_tris];
- int pos = 0; // Where to pick up parsing next. This will give
- // us an offset to our token string, so that we
- // can grab the next integer one at a time.
- sscanf(bline, "%*s %*u %n", &pos);
- // fprintf(stderr, "pos = %d\n", pos);
- char* bline_p = bline+pos;
- for(unsigned int i = 0; i < node->num_tris; ++i) {
- sscanf(bline_p, "%d %n", tri_ids_p, &pos);
- // fprintf(stderr, "pos = %d, %d\n", pos, *tri_ids_p);
-// fprintf(stderr, "tri (%d) = %d\n", i, *tri_ids_p);
- bline_p += pos;
- ++tri_ids_p;
- }
- }
- // else empty leaf
- } else {
- fprintf(stderr, "Unrecongnized token (%c)\n", token);
- }
-
- }
-
- // Allocate space for the num_tri_indicies. If this gets changed to
+ // Allocate space for the num_tri_indices. If this gets changed to
// unsigned int from int, you need up update the parser code below.
- kdtree->triIndices = new VArray<int>(num_tri_indicies);
- kdtree->triIndices->setLen(num_tri_indicies);
+ kdtree->triIndices = new VArray<int>(num_tri_indices);
+ kdtree->triIndices->setLen(num_tri_indices);
// Allocate space for the nodes
KDTreeNode* nodes =
reinterpret_cast<KDTreeNode*>(malloc(num_nodes*sizeof(KDTreeNode)));
KDTreeNode* current_node = nodes;
unsigned int current_node_index = 0;
- KDTreeNode* parent = NULL;
- // Reset the file pointer
- fseek(bspf, 0, SEEK_SET);
-
unsigned int current_tri_index = 0;
int* tri_ids_p = kdtree->triIndices->getArray();
bool bsp_debug = false;
// Now traverse the data structure and fill in the kd tree data.
- top = head;
+ IWNode* top = tree->head;
top->index = current_node_index++;
stack<IWNode*> nodestack;
nodestack.push(top);
@@ -389,7 +258,7 @@
if (bsp_debug)
fprintf(stderr, "Leaf(#%u): num_tris = %d (",
top->index, top->num_tris);
- // Copy the indicies
+ // Copy the indices
for(unsigned int i = 0; i < top->num_tris; ++i) {
*tri_ids_p = top->tri_ids[i];
if (bsp_debug) fprintf(stderr, "%d, ", *tri_ids_p);
@@ -409,19 +278,15 @@
nodestack.pop();
}
- fprintf(stderr, "num_tri_indicies = %u\n", num_tri_indicies);
+ fprintf(stderr, "num_tri_indices = %u\n", num_tri_indices);
fprintf(stderr, "current_tri_index = %u\n", current_tri_index);
fprintf(stderr, "num_nodes = %u, current_node_index = %u\n",
num_nodes, current_node_index);
- delete head;
+ delete tree;
// Specify the root node loaded from the file.
kdtree->rootNode = nodes;
-
- if (bline) free(bline);
- fclose(bspf);
-
return 1;
} // int loadIW()
Modified: trunk/Model/Readers/IW.cc
==============================================================================
--- trunk/Model/Readers/IW.cc (original)
+++ trunk/Model/Readers/IW.cc Thu Apr 6 16:49:46 2006
@@ -180,7 +180,7 @@
return 0;
}
- // Make sure that the triangle indicies and shader indicies are cool
+ // Make sure that the triangle indices and shader indicies are cool
for(size_t i = 0; i < iw->triangles.size(); ++i) {
unsigned int a, b, c, group;
a = iw->triangles[i][0];
@@ -220,3 +220,115 @@
return iw;
}
+
+IWTree* Manta::IWTreeRead(const char* filename)
+{
+ unsigned int num_tri_indices = 0;
+ unsigned int num_nodes = 0;
+ unsigned int num_empty_nodes = 0;
+
+ FILE* bspf = fopen(filename, "r");
+ if (!bspf) {
+ fprintf(stderr, "Error: cannot open %s for loading\n",
filename);
+ return 0;
+ }
+
+ // Buffer for line. This will be allocated by getline and
+ // reallocated as needed. We will need to free it later, though.
+ char* bline = NULL;
+ size_t bline_len = 0;
+
+ IWNode* head = 0;
+ IWNode* top = head;
+
+ while((getline(&bline, &bline_len, bspf)) != -1) {
+// fprintf (stderr, "line(%u): %s\n", bline_len, bline);
+ // Check the first token
+ char token[2];
+ int num = sscanf(bline, "%1s", token);
+ // fprintf(stderr, "num = %d, token = %s\n", num, token);
+ if (strcmp(token, "N") == 0) {
+ num_nodes ++;
+// fprintf(stderr, "Node %u found\n", num_nodes);
+
+ IWNode* node = new IWNode(top);
+ // Is this the first node?
+ if (top) {
+ if (top->left) {
+ top->setRight(node);
+ } else {
+ top->setLeft(node);
+ }
+ } else {
+ // Set the head to the first node
+ head = node;
+ }
+ // Decend
+ top = node;
+
+ char axis_c;
+ sscanf(bline, "%*s %c=%f,d=%*d", &axis_c, &(node->split));
+// fprintf(stderr, "axis = %c, split = %g\n", axis_c, node->split);
+ switch (axis_c) {
+ case 'x': node->flags |= 0; break;
+ case 'y': node->flags |= 1; break;
+ case 'z': node->flags |= 2; break;
+ }
+
+ } else if (strcmp(token, "L") == 0) {
+ IWNode* node = new IWNode(top);
+
+ if (top->left) {
+ top->setRight(node);
+ // Finish up this level
+ while (top && top->right) {
+ top = top->parent;
+ }
+ } else {
+ top->setLeft(node);
+ }
+
+ // Grab how many objects we have
+ sscanf(bline, "%*s %u", &(node->num_tris));
+// fprintf(stderr, "L %u\n", node->num_tris);
+ num_tri_indices += node->num_tris;
+ if (node->num_tris) {
+ num_nodes++;
+
+ // If you ever change what type triIndices is you will need to
+ // update this bit of code for the right type.
+ int* tri_ids_p = node->tri_ids = new int[node->num_tris];
+ int pos = 0; // Where to pick up parsing next. This will give
+ // us an offset to our token string, so that we
+ // can grab the next integer one at a time.
+ sscanf(bline, "%*s %*u %n", &pos);
+ // fprintf(stderr, "pos = %d\n", pos);
+ char* bline_p = bline+pos;
+ for(unsigned int i = 0; i < node->num_tris; ++i) {
+ sscanf(bline_p, "%d %n", tri_ids_p, &pos);
+ // fprintf(stderr, "pos = %d, %d\n", pos, *tri_ids_p);
+// fprintf(stderr, "tri (%d) = %d\n", i, *tri_ids_p);
+ bline_p += pos;
+ ++tri_ids_p;
+ }
+ } else {
+ // else empty leaf
+ num_empty_nodes++;
+ }
+ } else {
+ fprintf(stderr, "Unrecongnized token (%c)\n", token);
+ }
+
+ }
+
+ if (bline) free(bline);
+ fclose(bspf);
+
+ IWTree* tree = new IWTree();
+ tree->head = head;
+ tree->num_nodes = num_nodes;
+ tree->num_tri_indices = num_tri_indices;
+
+ return tree;
+}
+
Modified: trunk/Model/Readers/IW.h
==============================================================================
--- trunk/Model/Readers/IW.h (original)
+++ trunk/Model/Readers/IW.h Thu Apr 6 16:49:46 2006
@@ -69,6 +69,14 @@
namespace Manta {
+ class IWObject;
+ class IWNode;
+ class IWTree;
+
+ // Return null if there was a problem
+ IWObject* IWObjectRead(const char* filename);
+ IWTree* IWTreeRead(const char* filename);
+
class IWObject {
public:
IWObject() {}
@@ -93,8 +101,58 @@
IWObject( const Vector& copy ) {}
};
- // Return null if there was a problem
- IWObject* IWObjectRead(const char* filename);
+ struct IWNode {
+ IWNode()
+ : left(0), right(0), parent(0),
+ split(0), flags(0),
+ num_tris(0), tri_ids(0),
+ index(0)
+ {}
+ IWNode(IWNode* parent)
+ : left(0), right(0), parent(parent),
+ split(0), flags(0),
+ num_tris(0), tri_ids(0),
+ index(0)
+ {}
+ ~IWNode() {
+ if (left) delete left;
+ if (right) delete right;
+ if (tri_ids) delete[] tri_ids;
+ }
+
+ void setRight(IWNode* node) {
+ right = node;
+ }
+ void setLeft(IWNode* node) {
+ left = node;
+ }
+ bool isNode() const {
+ return (left || right);
+ }
+ bool isLeaf() const {
+ return !(left || right);
+ }
+
+ IWNode *left, *right, *parent;
+ float split;
+ int flags;
+ unsigned int num_tris;
+ int* tri_ids;
+ unsigned int index;
+ };
+
+ struct IWTree {
+ IWTree(): head(NULL) {}
+
+ ~IWTree() {
+ if (head) delete head;
+ }
+
+ IWNode* head;
+ unsigned int num_nodes;
+ unsigned int num_empty_nodes; // These are leaves with no triangles
+ unsigned int num_tri_indices;
+ };
} // end namespace Manta
Modified: trunk/scenes/iwviewer.cc
==============================================================================
--- trunk/scenes/iwviewer.cc (original)
+++ trunk/scenes/iwviewer.cc Thu Apr 6 16:49:46 2006
@@ -42,6 +42,7 @@
#include <Model/Materials/Flat.h>
#include <Model/Textures/NormalTexture.h>
#include <Model/Groups/DynBVH.h>
+#include <Model/Groups/KDTree2.h>
#include <iostream>
#include <vector>
@@ -57,14 +58,24 @@
enum {
Lambertian_Material,
Flat_Material,
- Normal_Material,
+ Normal_Material
};
-static string file_name;
+enum {
+ DynBVH_Build,
+ KDTree2_Build
+};
+
+static string iw_file_name;
+static string bsp_file_name;
static int tri_type = WaldTri;
static bool use_default_color = false;
static int material_type = Lambertian_Material;
static BBox bounds;
+static int build_type = DynBVH_Build;
+
+static Object* buildDynBVH(IWObject* iw);
+static Object* buildKDTree2(IWObject* iw);
extern "C"
Scene* make_scene(const ReadContext& context, const vector<string>& args) {
@@ -74,8 +85,13 @@
if (args[i] == "-file" || args[i] == "-iwfile") {
// Read in the file name.
- if (!getStringArg(i, args, file_name))
+ if (!getStringArg(i, args, iw_file_name))
throw IllegalArgument("iwviewer -file <filename>", i, args);
+ } else if (args[i] == "-bsp" || args[i] == "-bspfile") {
+ // Read in the file name.
+ if (!getStringArg(i, args, bsp_file_name))
+ throw IllegalArgument("iwviewer -bsp <filename>", i, args);
+ build_type = KDTree2_Build;
} else if (args[i] == "-tri" ) {
tri_type = Tri;
} else if (args[i] == "-flat" ) {
@@ -85,12 +101,49 @@
}
}
- IWObject* iw = IWObjectRead(file_name.c_str());
+ IWObject* iw = IWObjectRead(iw_file_name.c_str());
if (!iw) {
- cerr << "Error reading file : "<<file_name<<".\n";
+ cerr << "Error reading file : "<<iw_file_name<<".\n";
return 0;
}
+ ///////////////////////////////////////////////////////////////////////////
+ // Create the scene.
+ Scene *scene = new Scene();
+
+ // Add a head light.
+ LightSet *lights = new LightSet();
+ lights->add( new HeadLight( 0.0, Color(RGB(1.0,1.0,1.0)) ));
+ lights->setAmbientLight( new ConstantAmbient( Color(RGB(0.4,0.4,0.4) ) ));
+ scene->setLights( lights );
+
+ // Add the bvh to the scene.
+ switch(build_type) {
+ case DynBVH_Build: scene->setObject( buildDynBVH(iw) ); break;
+ case KDTree2_Build:
+ {
+ Object* kdtree = buildKDTree2(iw);
+ if (!kdtree) {
+ cerr << "Error building KDTree2\n";
+ delete iw;
+ return 0;
+ } else {
+ scene->setObject( kdtree );
+ }
+ }
+ break;
+ }
+
+ delete iw;
+
+ // Background.
+ scene->setBackground( new ConstantBackground( Color(RGB(0.8, 0.8, 1) ) ) );
+
+ return scene;
+
+}
+
+Object* buildDynBVH(IWObject* iw) {
// Make the materials
vector<Material*> materials;
for(size_t i = 0; i < iw->shaders.size(); ++i) {
@@ -136,22 +189,43 @@
break;
}
- ///////////////////////////////////////////////////////////////////////////
- // Create the scene.
- Scene *scene = new Scene();
+ return bvh_group;
+}
- // Add a head light.
- LightSet *lights = new LightSet();
- lights->add( new HeadLight( 0.0, Color(RGB(1.0,1.0,1.0)) ));
- lights->setAmbientLight( new ConstantAmbient( Color(RGB(0.4,0.4,0.4) ) ));
- scene->setLights( lights );
+Object* buildKDTree2(IWObject* iw) {
+ // attempt to open the bsp file
+ IWTree* tree = IWTreeRead(bsp_file_name.c_str());
+ if (!tree) {
+ cerr << "Error reading file : "<<bsp_file_name<<".\n";
+ return 0;
+ }
- // Add the bvh to the scene.
- scene->setObject( bvh_group );
+ Material* matl = 0;
+ KDTree2Texture* tex = new KDTree2Texture();
+ switch (material_type) {
+ case Lambertian_Material:
+ matl = new Lambertian( tex );
+ break;
+ case Flat_Material:
+ matl = new Flat( tex );
+ break;
+ case Normal_Material:
+ matl = new Flat( new NormalTexture() );
+ break;
+ }
- // Background.
- scene->setBackground( new ConstantBackground( Color(RGB(0.8, 0.8, 1) ) ) );
+ KDTree2* kdtree = new KDTree2(matl);
+ if (kdtree->loadIW(iw, tree)) {
+ delete tree;
+ cerr << "Error creating KDTree2\n";
+ return 0;
+ }
- return scene;
+ // Put a reference back to the kdree
+ tex->kdtree = kdtree;
+
+ // Clean up
+ delete tree;
+ return kdtree;
}
- [MANTA] r1002 - in trunk: Model/Groups Model/Readers scenes, bigler, 04/06/2006
Archive powered by MHonArc 2.6.16.