Text archives Help
- From: thiago@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r1444 - in trunk: Interface Model/Groups Model/Primitives scenes
- Date: Thu, 5 Jul 2007 17:59:48 -0600 (MDT)
Author: thiago
Date: Thu Jul 5 17:59:42 2007
New Revision: 1444
Added:
trunk/Model/Groups/Mesh.cc
Modified:
trunk/Interface/TexCoordMapper.h
trunk/Model/Groups/CMakeLists.txt
trunk/Model/Groups/Group.cc
trunk/Model/Groups/Group.h
trunk/Model/Groups/Mesh.h
trunk/Model/Groups/ObjGroup.cc
trunk/Model/Groups/ObjGroup.h
trunk/Model/Primitives/WaldTriangle.cc
trunk/Model/Primitives/WaldTriangle.h
trunk/scenes/objviewer.cc
Log:
Got Mesh class working. Now a WaldTriangle is able to do textures,
interpolated normals, and so on (it's fully featured). ObjGroup will
now return a mesh group instead of a normal group. The mesh group can
in theory be made up of any kind of triangle, but for now it just uses
wald triangles since they are so much faster (about 1.5-2x faster).
Advantages of the mesh class are:
-faster for interpolating, since vertices and other data are often
shared.
-allows triangle classes to have a small footprint, with shading data
stored in mesh class
-faster for calculating the mesh's bounding box for same reason as
interpolating being faster.
ObjGroup is currently the only thing that creates Meshes. objviewer
does not, although it would be a simple copy-paste to make it do that,
or better, have objviewer contain an ObjGroup. The ply reader also
still needs to be updated to use the Mesh class.
Modified: trunk/Interface/TexCoordMapper.h
==============================================================================
--- trunk/Interface/TexCoordMapper.h (original)
+++ trunk/Interface/TexCoordMapper.h Thu Jul 5 17:59:42 2007
@@ -8,7 +8,7 @@
class RayPacket;
class RenderContext;
- class TexCoordMapper : public Interpolable {
+ class TexCoordMapper {
public:
TexCoordMapper();
virtual ~TexCoordMapper();
Modified: trunk/Model/Groups/CMakeLists.txt
==============================================================================
--- trunk/Model/Groups/CMakeLists.txt (original)
+++ trunk/Model/Groups/CMakeLists.txt Thu Jul 5 17:59:42 2007
@@ -32,6 +32,8 @@
Groups/KDTreeLoaderIW.h
Groups/KDTree2.cc
Groups/KDTree2.h
+ Groups/Mesh.cc
+ Groups/Mesh.h
Groups/RealisticBvh.cc
Groups/RealisticBvh.h
Groups/TransparentKDTree.cc
Modified: trunk/Model/Groups/Group.cc
==============================================================================
--- trunk/Model/Groups/Group.cc (original)
+++ trunk/Model/Groups/Group.cc Thu Jul 5 17:59:42 2007
@@ -17,7 +17,8 @@
{
}
-Group::Group(): dirtybbox(true), barrier("group barrier"), mutex("group
mutex")
+Group::Group(): dirtybbox(true), barrier("group barrier"),
+ mutex("group mutex")
{
}
@@ -95,8 +96,6 @@
worstError = retcode;
}
- //XXXX: should we have a barrier here to make sure everything is
- //fully interpolated before other things get access to new data?
barrier.wait(numProc);
return worstError;
@@ -167,18 +166,13 @@
void Group::computeBounds(const PreprocessContext& context, BBox& bbox) const
{
if (dirtybbox) {
- for(vector<Object*>::const_iterator iter = objs.begin();
- iter != objs.end(); ++iter)
- (*iter)->computeBounds(context, bbox);
- dirtybbox = false;
- }
- else {
- bbox.extendByBox(this->bbox);
+ computeBounds(context, 0, 1);
}
+ bbox.extendByBox(this->bbox);
}
void Group::computeBounds(const PreprocessContext& context,
- int proc, int numProcs)
+ int proc, int numProcs) const
{
BBox myBBox;
PreprocessContext dummyContext;
Modified: trunk/Model/Groups/Group.h
==============================================================================
--- trunk/Model/Groups/Group.h (original)
+++ trunk/Model/Groups/Group.h Thu Jul 5 17:59:42 2007
@@ -57,8 +57,8 @@
#endif
virtual bool isParallel() const { return true; }
- void add(Object* obj);
- void set( int i, Object *obj );
+ virtual void add(Object* obj);
+ virtual void set( int i, Object *obj );
Object *get( int i );
const Object* get(int i) const;
@@ -67,9 +67,6 @@
bool isDirty() const;
void setDirty();
- vector<Object*> &getObjects() { return objs; }
- const vector<Object*> &getObjects() const { return objs; }
-
void shrinkTo(int firstNumObjs, bool deleteRemainder);
int getSize() const;
@@ -82,17 +79,18 @@
virtual void computeBounds(const PreprocessContext& context,
BBox& bbox) const;
virtual void computeBounds(const PreprocessContext& context,
- int proc, int numProcs);
+ int proc, int numProcs) const;
static Group* create(const vector<string>& args);
protected:
vector<Object*> objs;
vector<Object*>::iterator parallelSplit; //point to the start of the
parallel objects
- BBox bbox;
+ mutable BBox bbox;
mutable bool dirtybbox;
- SCIRun::Barrier barrier;
- SCIRun::Mutex mutex;
+ mutable SCIRun::Barrier barrier;
+ mutable SCIRun::Mutex mutex;
+
};
}
Added: trunk/Model/Groups/Mesh.cc
==============================================================================
--- (empty file)
+++ trunk/Model/Groups/Mesh.cc Thu Jul 5 17:59:42 2007
@@ -0,0 +1,194 @@
+#include <Model/Groups/Mesh.h>
+#include <Model/Primitives/WaldTriangle.h>
+using namespace Manta;
+
+Mesh::Mesh()
+{
+}
+
+Mesh* Mesh::clone(CloneDepth depth, Clonable* incoming)
+{
+ Mesh *copy;
+ if (incoming)
+ copy = static_cast<Mesh*>(incoming);
+ else
+ copy = new Mesh();
+
+ Group::clone(depth, copy);
+
+ //If we end up having more than just a WaldTriangle as the types of
+ //triangles that can come from a mesh, then the correct thing to do
+ //is create an interface that mesh triangles inherent from that
+ //requires attachMesh to be implemented. Then we can cast to that
+ //interface instead of the specific WaldTriangle.
+ for (unsigned int i=0; i < objs.size(); ++i) {
+ static_cast<WaldTriangle*>(copy->objs[i])->attachMesh(copy);
+ }
+
+ copy->vertices = vertices;
+ copy->vertexNormals = vertexNormals;
+ copy->texCoords = texCoords;
+ copy->materials = materials;
+ copy->vertex_indices = vertex_indices;
+ copy->normal_indices = normal_indices;
+ copy->texture_indices = texture_indices;
+ copy->face_material = face_material;
+
+ return copy;
+}
+
+Interpolable::InterpErr
+Mesh::serialInterpolate(const std::vector<keyframe_t> &keyframes)
+{
+ return parallelInterpolate(keyframes, 0, 1);
+}
+
+Interpolable::InterpErr
+Mesh::parallelInterpolate(const std::vector<keyframe_t> &keyframes,
+ int proc, int numProcs)
+{
+ InterpErr worstError = success;
+
+ Mesh *meshes[keyframes.size()];
+ for (unsigned int frame=0; frame < keyframes.size(); ++frame) {
+ Mesh *mesh = dynamic_cast<Mesh*>(keyframes[frame].keyframe);
+ if (mesh == NULL)
+ return notInterpolable;
+
+ meshes[frame] = mesh;
+
+ assert(vertices.size() == mesh->vertices.size());
+ assert(vertexNormals.size() == mesh->vertexNormals.size());
+ assert(texCoords.size() == mesh->texCoords.size());
+ assert(materials.size() == mesh->materials.size());
+
+ //These vectors should be identical down to the individual
+ //elements. But we don't check that far down.
+ assert(vertex_indices.size() == mesh->vertex_indices.size());
+ assert(normal_indices.size() == mesh->normal_indices.size());
+ assert(texture_indices.size() == mesh->texture_indices.size());
+ assert(face_material.size() == mesh->face_material.size());
+ }
+
+ //vertices
+ unsigned int size = vertices.size();
+ unsigned int start = proc*size/numProcs;
+ unsigned int end = (proc+1)*size/numProcs;
+ for (unsigned int i=start; i < end; ++i) {
+ vertices[i] = Vector(0,0,0);
+ for(unsigned int frame=0; frame < keyframes.size(); ++frame) {
+ vertices[i] += meshes[frame]->vertices[i] * keyframes[frame].t;
+ }
+ }
+
+ //vertexNormals
+ size = vertexNormals.size();
+ start = proc*size/numProcs;
+ end = (proc+1)*size/numProcs;
+ for (unsigned int i=start; i < end; ++i) {
+ vertexNormals[i] = Vector(0,0,0);
+ for(unsigned int frame=0; frame < keyframes.size(); ++frame) {
+ vertexNormals[i] += meshes[frame]->vertexNormals[i] *
keyframes[frame].t;
+ }
+ }
+
+ //texCoords
+ size = texCoords.size();
+ start = proc*size/numProcs;
+ end = (proc+1)*size/numProcs;
+ for (unsigned int i=start; i < end; ++i) {
+ texCoords[i] = Vector(0,0,0);
+ for(unsigned int frame=0; frame < keyframes.size(); ++frame) {
+ texCoords[i] += meshes[frame]->texCoords[i] * keyframes[frame].t;
+ }
+ }
+
+ //materials
+// size = materials.size();
+// start = proc*size/numProcs;
+// end = (proc+1)*size/numProcs;
+// vector<keyframe_t> mat_keyframes(keyframes);
+// for (unsigned int i=start; i < end; ++i) {
+// for(unsigned int frame=0; frame < keyframes.size(); ++frame) {
+// mat_keyframes[frame].keyframe = meshes[frame]->materials[i];
+// }
+// InterpErr retcode = materials[i]->serialInterpolate(mat_keyframes);
+// if (retcode != success)
+// worstError = retcode;
+// }
+
+ //there could still be some threads updating the vertices, which
+ //get used when the triangles are updated below.
+ barrier.wait(numProcs);
+
+ Group::parallelInterpolate(keyframes, proc, numProcs);
+
+ return worstError;
+}
+
+
+void Mesh::add(Object* obj)
+{
+ //I don't think this should be allowed.
+ assert(false);
+ exit(-1);
+}
+
+void Mesh::set( int i, Object *obj )
+{
+ //I don't think this should be allowed.
+ assert(false);
+ exit(-1);
+}
+
+void Mesh::computeBounds(const PreprocessContext& context,
+ int proc, int numProcs) const
+{
+ if (proc == 0) {
+ this->bbox.reset();
+ }
+
+ BBox myBBox;
+
+ //Compute Bounding boxes in parallel
+ int size = vertices.size();
+ int start = proc*size/numProcs;
+ int end = (proc+1)*size/numProcs;
+ for (int i=start; i < end; ++i) {
+ myBBox.extendByPoint(vertices[i]);
+ }
+
+ //this barrier enforces that bbox has been initialized before
+ //threads start writing to it.
+ barrier.wait(numProcs);
+
+ mutex.lock();
+ this->bbox.extendByBox(myBBox);
+ mutex.unlock();
+
+ if (proc == 0) {
+ dirtybbox = false;
+ }
+
+ //Need to wait for other threads to finish computing bbox
+ barrier.wait(numProcs);
+}
+
+BBox Mesh::getBBox(unsigned int which)
+{
+ const unsigned int index = which*3;
+ const Vector &p1 = vertices[vertex_indices[index+0]];
+ const Vector &p2 = vertices[vertex_indices[index+1]];
+ const Vector &p3 = vertices[vertex_indices[index+2]];
+ BBox bbox(p1, p1);
+ bbox.extendByPoint(p2);
+ bbox.extendByPoint(p3);
+ return bbox;
+}
+
+void Mesh::preprocess(const PreprocessContext& context)
+{
+ for (unsigned int i=0; i < materials.size(); ++i)
+ materials[i]->preprocess(context);
+ Group::preprocess(context);
+}
Modified: trunk/Model/Groups/Mesh.h
==============================================================================
--- trunk/Model/Groups/Mesh.h (original)
+++ trunk/Model/Groups/Mesh.h Thu Jul 5 17:59:42 2007
@@ -1,128 +1,69 @@
+#ifndef Manta_Model_Groups_Mesh_h
+#define Manta_Model_Groups_Mesh_h
+#include <Core/Geometry/Vector.h>
+#include <Core/Thread/Barrier.h>
+#include <SCIRun/Core/Thread/Mutex.h>
+#include <Core/Geometry/BBox.h>
+#include <Interface/Material.h>
+#include <Interface/RayPacket.h>
+#include <Interface/TexCoordMapper.h>
+#include <Model/Groups/Group.h>
-// IndexT is a template type, because you may not need the precision
-// of a whole int to store the geometry.
-//
-// MatIndexT is a template type, because you often don't have more
-// than 256 materials per mesh.
-template<class IndexT, class MatIndexT>
-class Mesh: public Primitive {
- // This will allow you to get access to the index type.
- typedef IndexT IndexType;
-
- // All the elements with index >= numeric_limits<IndexT>::max() will
- // be unable to be index.
- vector<Vector> vertices;
- vector<Vector> vertexNormals;
- vector<Vector> texCoords;
- vector<Vector> faceNormals;
- vector<Material*> materials;
-
- // I was tempted to make numTriangles of type IndexT, but then I
- // realized that you may have many more triangles than vertices, by
- // use of clever combinations of the existing vertex set.
- size_t numTriangles;
-
- // Per vertex data. size() == 3*numTriangles;
- vector<IndexT> vertex_indices;
- vector<IndexT> normal_indices;
- vector<IndexT> texture_indices;
-
- // Per face data. size() == numTriangles;
- vector<IndexT> face_normals;
- vector<MatIndexT> face_material;
-
- // Should we support having both face_normals and vertex_normals?
-
- //////////////////////////////
- // This is what would be stuffed into the scratchpad if there was a
- // hit.
-
- struct ScratchPadInfo {
- Real u, v;
- IndexT which;
- };
-
- //////////////////////////////////////////////////////////////
- // Here's the primitive interface
-
- // You can't get access to the actual primitive, because it may not
- // actually exist. You can get the bounds of it, though.
- BBox getBBox(IndexT which);
-
- // Computes the hit location. It doesn't register the hit. Call
- // registerHit later.
- Real intersect(const RenderContext& context, const RayPacket& rays,
- int which_ray, IndexT which_tri, ScratchPadInfo& info);
-#ifdef MANTA_SSE
- // SSE version
- __m128 intersectSSE(const RenderContext& context, const RayPacket& rays,
- IndexT which);
-#endif
-
- void registerHit(RayPacket& rays, int which_ray, ScratchPadInfo& info);
-#ifdef MANTA_SSE
- void registerHitSSE(RayPacket& rays, int which, __m128i hitMask);
-#endif
-
-
- // These functions shouldn't be called, as it doesn't make sense to
- // perform these operations on the whole mesh.
- virtual void intersect(const RenderContext& context,
- RayPacket& rays) const;
-
-
- virtual void preprocess(const PreprocessContext& context);
- virtual void setTexCoordMapper(const TexCoordMapper* new_tex);
- virtual void computeBounds(const PreprocessContext& context, BBox& bbox)
const = 0;
-
- // This is after intersection, and we need to be able to act the
- // part of a general primitive. The primitive index must be stored
- // in the scratchpad.
- virtual void computeNormal(const RenderContext& context,
- RayPacket& rays) const;
-
-};
-
-template<class IndexT, class MatIndexT>
-BBox Mesh::getBBox(IndexT which)
-{
- IndexT index = which*3;
- Vertex p1 = vertex_indices[index];
- BBox bbox(p1, p1);
- bbox.extendByPoint(vertex_indices[index+1]);
- bbox.extendByPoint(vertex_indices[index+2]);
-}
-
-// Computes the hit location. It doesn't register the hit. Call
-// registerHit later.
-template<class IndexT, class MatIndexT>
-Real Mesh::intersect(const RenderContext& context, const RayPacket& rays,
- int which_ray, IndexT which_tri, ScratchPadInfo& info)
-{
- IndexT index = which*3;
-
- Real t = numeric_limits<Real>::max();
-
- Vector edge1 = vertices[index+1] - vertices[index];
- Vector edge2 = vertices[index+2] - vertices[index];
- if (Intersection::intersectTriangleEdge( t, info.u, info.v,
- rays.getRay(which_ray),
- edge1, edge2, vertices[index] ))
- {
- info.which = which;
- }
- return t;
-}
+#include <vector>
-
-template<class IndexT, class MatIndexT>
-void Mesh::registerHit(RayPacket& rays, int which_ray,
- Real t, ScratchPadInfo& info)
+namespace Manta
{
- if (rays.hit(which_ray, t, material, prim, tex)) {
- rays.scratchpad<ScratchPadInfo>(which_ray) = info;
- }
+ using namespace std;
+ class Mesh : public Group {
+ public:
+
+ vector<Vector> vertices;
+ vector<Vector> vertexNormals;
+ vector<Vector> texCoords;
+// vector<Vector> faceNormals; //not handled for now
+ vector<Material*> materials;
+
+ //Note: We might want to templatize the indices in case we end up
+ //having lots of meshes with small (less than a short) numbers of
+ //vertices. Most likely though is that we have just one or two
+ //meshes total, so the space savings is minimal and we can just
+ //avoid template ugliness.
+
+ // Per vertex data. size() == 3*numTriangles;
+ vector<unsigned int> vertex_indices;
+ vector<unsigned int> normal_indices;
+ vector<unsigned int> texture_indices;
+
+ // Per face data. size() == numTriangles;
+ //vector<unsigned int> face_normals; //not handled for now.
+ vector<unsigned int> face_material;
+
+ // Should we support having both face_normals and vertex_normals?
+
+ Mesh();
+
+ virtual Mesh* clone(CloneDepth depth, Clonable* incoming=NULL);
+
+ virtual InterpErr serialInterpolate(const std::vector<keyframe_t>
&keyframes);
+ virtual InterpErr parallelInterpolate(const std::vector<keyframe_t>
&keyframes,
+ int proc, int numProc);
+ virtual bool isParallel() const { return true; }
+
+ bool hasVertexNormals() const { return !normal_indices.empty(); }
+
+ //should not be allowed to use Group's add and set.
+ virtual void add(Object* obj);
+ virtual void set( int i, Object *obj );
+
+ void computeBounds(const PreprocessContext& context, int proc, int
numProcs) const;
+
+ // You can't get access to the actual primitive, because it may not
+ // actually exist. You can get the bounds of it, though.
+ BBox getBBox(unsigned int which);
+
+ virtual void preprocess(const PreprocessContext& context);
+ };
}
-
+#endif //Manta_Model_Group_Mesh_h
Modified: trunk/Model/Groups/ObjGroup.cc
==============================================================================
--- trunk/Model/Groups/ObjGroup.cc (original)
+++ trunk/Model/Groups/ObjGroup.cc Thu Jul 5 17:59:42 2007
@@ -11,10 +11,7 @@
#include <Model/Materials/Phong.h>
#include <Model/Materials/Dielectric.h>
#include <Model/Materials/Flat.h>
-#include <Model/Primitives/TexTriangle.h>
-#include <Model/Primitives/HeavyTriangle.h>
#include <Model/Primitives/WaldTriangle.h>
-#include <Model/Primitives/Triangle.h>
#include <iostream>
#include <map>
@@ -175,51 +172,57 @@
// Allocate storage for primitives and materials.
create_materials( model );
+ for (unsigned int i=1; i <= model->numvertices; ++i)
+ vertices.push_back(Vector(model->vertices[i*3+0],
+ model->vertices[i*3+1],
+ model->vertices[i*3+2]));
+
+ for (unsigned int i=1; i <= model->numnormals; ++i)
+ vertexNormals.push_back(Vector(model->normals[i*3+0],
+ model->normals[i*3+1],
+ model->normals[i*3+2]));
+
+ for (unsigned int i=1; i <= model->numtexcoords; ++i)
+ texCoords.push_back(Vector(model->texcoords[i*2+0],
+ model->texcoords[i*2+1],
+ 1));
+
+// for (unsigned int i=1; i <= model->numfacetnorms; ++i)
+// faceNormals.push_back(Vector(model->facetnorms[i*3+0],
+// model->facetnorms[i*3+1],
+// model->facetnorms[i*3+2]));
+
Material *default_material = new Flat( new NormalTexture() );
+ materials.push_back(default_material);
+ for (unsigned int i=0; i < model->nummaterials; ++i)
+ materials.push_back(material_array[i]);
+
+ WaldTriangle *triangles = new WaldTriangle[model->numtriangles];
// Read in the groups.
GLMgroup *group = model->groups;
while (group != 0) {
- Material *material;
-
// Determine the material for this group.
- unsigned int material_index = group->material;
- if (material_index < model->nummaterials) {
- material = material_array[material_index];
- }
- else {
- material = default_material;
+ unsigned int material_index = 0;
+ if (group->material < model->nummaterials) {
+ material_index = group->material+1;
}
-
+
// Copy out triangles.
int total_faces = group->numtriangles;
for (int i=0;i<total_faces;++i) {
-
- Vector vertex[3];
- Vector normal[3];
- Vector texcoord[3];
-
+
bool have_normals = true;
bool have_textures = true;
for (int v=0;v<3;++v) {
- int index = model->triangles[ group->triangles[i] ].vindices[v];
- float *f = model->vertices+(index*3);
-
- // Copy out the vertex.
- vertex[v][0] = f[0];
- vertex[v][1] = f[1];
- vertex[v][2] = f[2];
+ int index = model->triangles[ group->triangles[i] ].vindices[v];
+ vertex_indices.push_back(index-1);
index = model->triangles[ group->triangles[i] ].nindices[v];
if (index > 0) {
- f = model->normals+(index*3);
-
- // Copy out the normal.
- normal[v][0] = f[0];
- normal[v][1] = f[1];
- normal[v][2] = f[2];
+ normal_indices.push_back(index-1);
}
else {
// If one of the vertices doesn't have texture
@@ -229,48 +232,27 @@
index = model->triangles[ group->triangles[i] ].tindices[v];
if (index > 0) {
- f = model->texcoords+(index*2);
-
- // Copy out the texcoord
- texcoord[v][0] = f[0];
- texcoord[v][1] = f[1];
- texcoord[v][2] = 1.0;
+ texture_indices.push_back(index-1);
}
else {
have_textures = false;
}
-
- }
-
- // Create a new triangle.
- Object *triangle = 0;
- if (have_textures) {
- if (have_normals) {
- triangle = new TexTriangle( material,
- vertex[0], vertex[1]-vertex[0],
vertex[2]-vertex[0],
- normal[0], normal[1], normal[2],
- texcoord[0], texcoord[1], texcoord[2]);
- } else {
- triangle = new TexTriangle( material,
- vertex[0], vertex[1], vertex[2],
- texcoord[0], texcoord[1], texcoord[2]);
- }
- } else {
- // No texture coordinates
- if (have_normals) {
- triangle = new HeavyTriangle( material,
- vertex[0], vertex[1]-vertex[0],
vertex[2]-vertex[0],
- normal[0], normal[1], normal[2]);
- } else {
- triangle = new WaldTriangle( material,
-// triangle = new Triangle( material,
-// triangle = new HeavyTriangle( material,
- vertex[0], vertex[1], vertex[2]);
- }
}
- // Add the triangle to the group.
- add(triangle);
+ // we don't support face normals right now. If someone wants it,
+ // feel free to finish implementing it.
+// index = model->triangles[ group->triangles[i] ].findex;
+// if (index > 0) {
+// face_normals.push_back(index-1);
+// }
+// else {
+// // have_face_normals = false;
+// }
+
+ face_material.push_back(material_index);
+
+ triangles[objs.size()].attachMesh(this, objs.size());
+ objs.push_back(&triangles[objs.size()]);
}
// Move to the next group.
Modified: trunk/Model/Groups/ObjGroup.h
==============================================================================
--- trunk/Model/Groups/ObjGroup.h (original)
+++ trunk/Model/Groups/ObjGroup.h Thu Jul 5 17:59:42 2007
@@ -2,7 +2,7 @@
#ifndef MODEL_GROUPS_OBJGROUP__H
#define MODEL_GROUPS_OBJGROUP__H
-#include <Model/Groups/Group.h>
+#include <Model/Groups/Mesh.h>
#include <Core/Exceptions/InputError.h>
#include <Model/Readers/glm/glm.h>
@@ -10,7 +10,7 @@
class Material;
- class ObjGroup : public Group {
+ class ObjGroup : public Mesh {
public:
ObjGroup( const char *filename ) throw (InputError);
virtual ~ObjGroup();
Modified: trunk/Model/Primitives/WaldTriangle.cc
==============================================================================
--- trunk/Model/Primitives/WaldTriangle.cc (original)
+++ trunk/Model/Primitives/WaldTriangle.cc Thu Jul 5 17:59:42 2007
@@ -8,19 +8,89 @@
using namespace Manta;
using namespace std;
-WaldTriangle::WaldTriangle(Material* mat,
- const Vector& _p1, const Vector& _p2, const
Vector& _p3) : PrimitiveCommon(mat)
+WaldTriangle::WaldTriangle() : myID(0), mesh(NULL)
{
- setPoints(_p1, _p2, _p3);
+}
+
+WaldTriangle::WaldTriangle(Mesh *mesh, unsigned int id) :
+ myID(id), mesh(mesh)
+{
+ update();
+}
+
+void WaldTriangle::attachMesh(Mesh *mesh)
+{
+ this->mesh = mesh;
+}
+
+void WaldTriangle::attachMesh(Mesh *mesh, unsigned int id)
+{
+ this->mesh = mesh;
+ myID = id;
+}
+
+void WaldTriangle::update()
+{
+ const unsigned int index = myID*3;
+ const Vector p1 = mesh->vertices[mesh->vertex_indices[index+0]];
+ const Vector p2 = mesh->vertices[mesh->vertex_indices[index+1]];
+ const Vector p3 = mesh->vertices[mesh->vertex_indices[index+2]];
+
+ setPoints(p1, p2, p3);
+}
+
+WaldTriangle* WaldTriangle::clone(CloneDepth depth, Clonable* incoming)
+{
+ WaldTriangle *copy;
+ if (incoming)
+ copy = static_cast<WaldTriangle*>(incoming);
+ else
+ copy = new WaldTriangle();
+
+ copy->n_u = n_u;
+ copy->n_v = n_v;
+ copy->n_d = n_d;
+ copy->k = k;
+ copy->b_nu = b_nu;
+ copy->b_nv = b_nv;
+ copy->b_d = b_d;
+ copy->n_k = n_k;
+ copy->c_nu = c_nu;
+ copy->c_nv = c_nv;
+ copy->c_d = c_d;
+ copy->myID = myID;
+ copy->mesh = mesh;
+
+ return copy;
+}
+
+Interpolable::InterpErr WaldTriangle::serialInterpolate(const
std::vector<keyframe_t> &keyframes)
+{
+ //We assume that the mesh has already been interpolated.
+ update();
+ return success;
+}
+
+void WaldTriangle::computeBounds(const PreprocessContext& context,
+ BBox& bbox) const
+{
+ bbox.extendByBox(mesh->getBBox(myID));
+}
+
+
+void WaldTriangle::preprocess(const PreprocessContext& context)
+{
+ //TODO: this materials->preprocess might end up getting called lots
+ //of times (imagine all the triangles share the same
+ //material). Would be nice to have the preprocess for this in the
+ //mesh class and just iterate over the materials. Not sure how to do
+ //that, so we will do extra work for now.
+ mesh->materials[mesh->face_material[myID]]->preprocess(context);
+ update();
}
void WaldTriangle::setPoints(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();
@@ -39,8 +109,9 @@
// copy to struct
k = n;
- n_u = normal[u] / normal[k];
- n_v = normal[v] / normal[k];
+ float inv_normalk = 1 / normal[k];
+ n_u = normal[u] * inv_normalk;
+ n_v = normal[v] * inv_normalk;
n_d = _p1[u] * n_u + _p1[v] * n_v + _p1[k];
float s;
@@ -83,6 +154,26 @@
#endif
}
+
+
+void WaldTriangle::computeTexCoords2(const RenderContext&, RayPacket& rays)
const
+{
+ for(int ray=rays.begin(); ray<rays.end(); ray++) {
+ float a = rays.getScratchpad<float>(0)[ray];
+ float b = rays.getScratchpad<float>(1)[ray];
+ float c = (1.0 - a - b);
+
+ const int which = myID*3;
+ const Vector &tex0 = mesh->texCoords[mesh->texture_indices[which]];
+ const Vector &tex1 = mesh->texCoords[mesh->texture_indices[which+1]];
+ const Vector &tex2 = mesh->texCoords[mesh->texture_indices[which+2]];
+
+ rays.setTexCoords(ray, (tex1 * a) + (tex2 * b) + (tex0 * c));
+ }
+ rays.setFlag( RayPacket::HaveTexture2|RayPacket::HaveTexture3 );
+}
+
+
#ifdef MANTA_SSE
//These should be defined in SSEDefs.h, but aren't...
@@ -201,7 +292,16 @@
const int hit_mask = getmask4(mask_test);
for (int ray = ray_begin; ray < sse_begin; ++ray) {
if ( hit_mask & (1<<(4 - (ray-ray_begin) )) ) {
- rays.hit(ray, ((float*)&f)[ray-ray_begin], getMaterial(), this,
getTexCoordMapper());
+ const bool hit = rays.hit(ray, ((float*)&f)[ray-sse_end],
mesh->materials[mesh->face_material[myID]], this, this);
+ if (hit) {
+
+ float *u = &rays.getScratchpad<float>(0)[ray];
+ float *v = &rays.getScratchpad<float>(1)[ray];
+// int *which = rays.getScratchpad<int*>(2)[ray];
+ *u = ((float*)&lambda)[ray-sse_end];
+ *v = ((float*)&mue)[ray-sse_end];
+// *which = myID;
+ }
}
}
}
@@ -245,7 +345,15 @@
mask_test = and4(mask_test, and4( _mm_cmpnlt_ps(mue, zero4()),
_mm_cmpnlt_ps(set4(1.f), add4(mue,
lambda))));
- rays.hitWithoutTminCheck(ray, mask_test, f, getMaterial(), this,
getTexCoordMapper());
+ rays.hitWithoutTminCheck(ray, mask_test, f,
mesh->materials[mesh->face_material[myID]], this, this);
+
+ float *u = &rays.getScratchpad<float>(0)[ray];
+ float *v = &rays.getScratchpad<float>(1)[ray];
+// int *which = rays.getScratchpad<int*>(2)[ray];
+
+ store44(u, mask4(mask_test, lambda, load44(u)));
+ store44(v, mask4(mask_test, mue, load44(v)));
+// store44i(which, mask4i((sse_t)mask_test, set4i(myID),
load44i(which)));
}
if (sse_end < ray_end) {
@@ -293,7 +401,15 @@
const int hit_mask = getmask4(mask_test);
for (int ray = sse_end; ray < ray_end; ++ray) {
if ( hit_mask & (1<<(ray-sse_end)) ) {
- rays.hit(ray, ((float*)&f)[ray-sse_end], getMaterial(), this,
getTexCoordMapper());
+ const bool hit = rays.hit(ray, ((float*)&f)[ray-sse_end],
mesh->materials[mesh->face_material[myID]], this, this);
+ if (hit) {
+ float *u = &rays.getScratchpad<float>(0)[ray];
+ float *v = &rays.getScratchpad<float>(1)[ray];
+// int *which = rays.getScratchpad<int*>(2)[ray];
+ *u = ((float*)&lambda)[ray-sse_end];
+ *v = ((float*)&mue)[ray-sse_end];
+// *which = myID;
+ }
}
}
}
@@ -355,8 +471,48 @@
if ( mue < 0.f || mue + lambda > 1.f )
continue;
- rays.hit(i, f, getMaterial(), this, getTexCoordMapper());
+ const bool hit = rays.hit(i, f,
mesh->materials[mesh->face_material[myID]], this, this);
+ if (hit) {
+ float *u = &rays.getScratchpad<float>(0)[i];
+ float *v = &rays.getScratchpad<float>(1)[i];
+ *u = lambda;
+ *v = mue;
+ }
}
}
#endif // MANTA_SSE
+
+void WaldTriangle::computeNormal(const RenderContext& context, RayPacket
&rays) const
+{
+ if (mesh->hasVertexNormals()) {
+ for(int ray=rays.begin(); ray<rays.end(); ray++) {
+
+ const float a = rays.getScratchpad<float>(0)[ray];
+ const float b = rays.getScratchpad<float>(1)[ray];
+ const float c = (1.0 - a - b);
+
+ const Vector &n0 = mesh->vertexNormals[mesh->normal_indices[myID*3+0]];
+ const Vector &n1 = mesh->vertexNormals[mesh->normal_indices[myID*3+1]];
+ const Vector &n2 = mesh->vertexNormals[mesh->normal_indices[myID*3+2]];
+
+ const Vector normal = (n1*a) + (n2*b) + (n0*c);
+ rays.setNormal(ray, normal);
+ }
+ }
+ else {
+ const int axis = k;
+ const int ku = (k==2)?0:k+1;
+ const int kv = (k==0)?2:k-1;
+
+ const float nu = n_k*n_u;
+ const float nv = n_k*n_v;
+ RayPacketData* data = rays.data;
+ for ( int ray = rays.begin(); ray < rays.end(); ray++ ) {
+ data->normal[axis][ray] = n_k;
+ data->normal[ku][ray] = nu;
+ data->normal[kv][ray] = nv;
+ }
+ rays.setFlag(RayPacket::HaveUnitNormals);
+ }
+}
Modified: trunk/Model/Primitives/WaldTriangle.h
==============================================================================
--- trunk/Model/Primitives/WaldTriangle.h (original)
+++ trunk/Model/Primitives/WaldTriangle.h Thu Jul 5 17:59:42 2007
@@ -2,65 +2,64 @@
#ifndef Manta_Model_WaldTriangle_h
#define Manta_Model_WaldTriangle_h
-#include <Model/Primitives/PrimitiveCommon.h>
#include <Interface/RayPacket.h>
#include <Core/Geometry/Vector.h>
#include <Core/Geometry/Ray.h>
#include <Core/Geometry/BBox.h>
+#include <Model/Groups/Mesh.h>
namespace Manta
{
- class WaldTriangle : public PrimitiveCommon
+ class WaldTriangle : public Primitive, public TexCoordMapper
{
public:
- WaldTriangle() { };
- WaldTriangle(Material* mat,
- const Vector& _p1, const Vector& _p2, const Vector& _p3);
-
- void setPoints(const Vector& _p1, const Vector& _p2, const Vector& _p3);
-
- void computeBounds(const PreprocessContext& context,
- BBox& bbox) const
- {
- bbox.extendByBox( box );
- }
-
- void intersect(const RenderContext& context, RayPacket& rays) const;
-
- void computeNormal(const RenderContext& context, RayPacket &rays) const
- {
- const int axis = k;
- const int ku = (k==2)?0:k+1;
- const int kv = (k==0)?2:k-1;
-
- const float mult = n_k;
- RayPacketData* data = rays.data;
- for ( int ray = rays.begin(); ray < rays.end(); ray++ )
- {
- data->normal[axis][ray] = mult;
- data->normal[ku][ray] = mult * n_u;
- data->normal[kv][ray] = mult * n_v;
- }
- rays.setFlag(RayPacket::HaveUnitNormals);
-
- }
-
-
- float n_u;
- float n_v;
- float n_d;
- unsigned int k;
-
- float b_nu;
- float b_nv;
- float b_d;
- float n_k;
-
- float c_nu;
- float c_nv;
- float c_d;
+ WaldTriangle();
+ WaldTriangle(Mesh *mesh, unsigned int id);
- BBox box; // for bounds
+ void attachMesh(Mesh *mesh);
+ void attachMesh(Mesh *mesh, unsigned int id);
+
+ void update();
+
+ virtual WaldTriangle* clone(CloneDepth depth, Clonable* incoming=NULL);
+ virtual InterpErr serialInterpolate(const std::vector<keyframe_t>
&keyframes);
+
+ void computeBounds(const PreprocessContext& context,
+ BBox& bbox) const;
+
+ virtual void preprocess(const PreprocessContext& context);
+
+ virtual void setTexCoordMapper(const TexCoordMapper* new_tex) {
+ //we always use ourselves as the TexCoordMapper
+ }
+ virtual void computeTexCoords2(const RenderContext&, RayPacket& rays)
const;
+ virtual void computeTexCoords3(const RenderContext& context, RayPacket&
rays) const {
+ computeTexCoords2(context, rays);
+ }
+
+ void intersect(const RenderContext& context, RayPacket& rays) const;
+
+ void computeNormal(const RenderContext& context, RayPacket &rays) const;
+
+ protected:
+ void setPoints(const Vector& p1, const Vector& p2, const Vector& p3);
+
+ float n_u;
+ float n_v;
+ float n_d;
+ unsigned int k;
+
+ float b_nu;
+ float b_nv;
+ float b_d;
+ float n_k;
+
+ float c_nu;
+ float c_nv;
+ float c_d;
+
+ unsigned int myID;
+ Mesh *mesh;
};
}
Modified: trunk/scenes/objviewer.cc
==============================================================================
--- trunk/scenes/objviewer.cc (original)
+++ trunk/scenes/objviewer.cc Thu Jul 5 17:59:42 2007
@@ -597,8 +597,7 @@
cerr << "Creating HeavyTriangle( "<<material_index<<",\n"
<< " "<<vertex[0]<<",
"<<vertex[1]<<", "<<vertex[2]<<");\n";
}
-// triangle = new HeavyTriangle( material,
- triangle = new WaldTriangle( material,
+ triangle = new HeavyTriangle( material,
vertex[0], vertex[1],
vertex[2]);
}
}
- [MANTA] r1444 - in trunk: Interface Model/Groups Model/Primitives scenes, thiago, 07/05/2007
Archive powered by MHonArc 2.6.16.