Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r1291 - in trunk: Model/Materials Model/Primitives scenes


Chronological Thread 
  • From: thiago@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r1291 - in trunk: Model/Materials Model/Primitives scenes
  • Date: Tue, 20 Feb 2007 14:50:29 -0700 (MST)

Author: thiago
Date: Tue Feb 20 14:50:28 2007
New Revision: 1291

Added:
   trunk/Model/Materials/CopyTextureMaterial.cc
   trunk/Model/Materials/CopyTextureMaterial.h
Modified:
   trunk/Model/Materials/CMakeLists.txt
   trunk/Model/Materials/Null.h
   trunk/Model/Primitives/Heightfield.cc
   trunk/Model/Primitives/Heightfield.h
   trunk/scenes/primtest.cc
Log:

Model/Materials/CMakeLists.txt
Model/Materials/CopyTextureMaterial.cc
Model/Materials/CopyTextureMaterial.h

  Added CopyTextureMaterial that simply copies the value of the
  texture into the RayPacket.  This used to be the old Flat material,
  before Solomon hijacked it to multipy it with the dot product
  between the light and the normal.

Model/Materials/Null.h

  Fix header guard.

Model/Primitives/Heightfield.cc
Model/Primitives/Heightfield.h

  Code replaced with Steve's reference implementation.

scenes/primtest.cc

  Added ability to specify some textures and materials separately.
  The previous material types are still valid.

  Heightfield now also takes a filename instead of being hard coded.


Modified: trunk/Model/Materials/CMakeLists.txt
==============================================================================
--- trunk/Model/Materials/CMakeLists.txt        (original)
+++ trunk/Model/Materials/CMakeLists.txt        Tue Feb 20 14:50:28 2007
@@ -4,6 +4,8 @@
      Materials/AmbientOcclusion.cc
      Materials/Checker.h
      Materials/Checker.cc
+     Materials/CopyTextureMaterial.cc
+     Materials/CopyTextureMaterial.h
      Materials/Dielectric.h
      Materials/Dielectric.cc
      Materials/Flat.h

Added: trunk/Model/Materials/CopyTextureMaterial.cc
==============================================================================
--- (empty file)
+++ trunk/Model/Materials/CopyTextureMaterial.cc        Tue Feb 20 14:50:28 
2007
@@ -0,0 +1,56 @@
+#include <Model/Materials/CopyTextureMaterial.h>
+#include <Model/Textures/Constant.h>
+
+using namespace Manta;
+
+CopyTextureMaterial::CopyTextureMaterial(const Color& color)
+{
+  colortex = new Constant<Color>(color);
+}
+
+CopyTextureMaterial::CopyTextureMaterial(const Texture<Color>* colortex)
+  : colortex(colortex)
+{
+}
+
+void CopyTextureMaterial::preprocess(const PreprocessContext&)
+{
+}
+
+void CopyTextureMaterial::shade(const RenderContext& context,
+                                RayPacket& rays) const
+{
+  // Compute colors
+  Packet<Color> colors;
+  colortex->mapValues(colors, context, rays);
+
+#ifndef MANTA_SSE
+  // Copy the colors into the ray packet.
+  for(int i=rays.begin();i<rays.end();i++) {
+    rays.setColor( i, colors.get(i) );
+  }
+#else
+  int b = (rays.rayBegin + 3) & ~3;
+  int e = (rays.rayEnd) & ~3;
+  if (b == e) {
+    for (int i = rays.begin(); i < rays.end(); i++) {
+      rays.setColor( i, colors.get(i) );
+    }
+  } else {
+    int i = rays.rayBegin;
+    for (; i < b; i++) {
+      rays.setColor( i, colors.get(i) );
+    }
+    // SIMD now
+    RayPacketData* data = rays.data;
+    for (; i < e; i+= 4) {
+      _mm_store_ps(&data->color[0][i], _mm_load_ps(&colors.colordata[0][i]));
+      _mm_store_ps(&data->color[1][i], _mm_load_ps(&colors.colordata[1][i]));
+      _mm_store_ps(&data->color[2][i], _mm_load_ps(&colors.colordata[2][i]));
+    }
+    for (; i < rays.rayEnd; i++) {
+      rays.setColor( i, colors.get(i) );
+    }
+  }
+#endif
+}

Added: trunk/Model/Materials/CopyTextureMaterial.h
==============================================================================
--- (empty file)
+++ trunk/Model/Materials/CopyTextureMaterial.h Tue Feb 20 14:50:28 2007
@@ -0,0 +1,57 @@
+#ifndef MANTA_MATERIAL_COPYTEXTUREMATERIAL_H__
+#define MANTA_MATERIAL_COPYTEXTUREMATERIAL_H__
+
+/*
+  For more information, please see: http://software.sci.utah.edu
+
+  The MIT License
+
+  Copyright (c) 2005
+  Scientific Computing and Imaging Institute, University of Utah
+
+  License for the specific language governing rights and limitations under
+  Permission is hereby granted, free of charge, to any person obtaining a
+  copy of this software and associated documentation files (the "Software"),
+  to deal in the Software without restriction, including without limitation
+  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+  and/or sell copies of the Software, and to permit persons to whom the
+  Software is furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included
+  in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+  DEALINGS IN THE SOFTWARE.
+*/
+
+#include <Core/Color/Color.h>
+
+#include <Interface/Texture.h>
+#include <Interface/Material.h>
+
+namespace Manta {
+
+  /*
+    This material simply uses the values of the texture as the final
+    result disregarding any lighing parameters.
+  */
+  class CopyTextureMaterial: public Material {
+  public:
+    CopyTextureMaterial(const Color& color);
+    CopyTextureMaterial(const Texture<Color>* colortex);
+
+    virtual void preprocess(const PreprocessContext&);
+    virtual void shade(const RenderContext& context, RayPacket& rays) const;
+    
+  private:
+    Texture<Color> const *colortex;
+  };
+  
+} // end namespace Manta
+
+#endif // #ifndef MANTA_MATERIAL_COPYTEXTUREMATERIAL_H__

Modified: trunk/Model/Materials/Null.h
==============================================================================
--- trunk/Model/Materials/Null.h        (original)
+++ trunk/Model/Materials/Null.h        Tue Feb 20 14:50:28 2007
@@ -1,6 +1,6 @@
 
-#ifndef Manta_Model_Flat_h
-#define Manta_Model_Flat_h
+#ifndef Manta_Model_Null_h
+#define Manta_Model_Null_h
 
 /*
   For more information, please see: http://software.sci.utah.edu

Modified: trunk/Model/Primitives/Heightfield.cc
==============================================================================
--- trunk/Model/Primitives/Heightfield.cc       (original)
+++ trunk/Model/Primitives/Heightfield.cc       Tue Feb 20 14:50:28 2007
@@ -2,9 +2,6 @@
 #include <Model/Primitives/Heightfield.h>
 #include <Interface/RayPacket.h>
 #include <Core/Geometry/BBox.h>
-#include <Core/Math/Expon.h>
-#include <Core/Math/MiscMath.h>
-#include <Core/Math/MinMax.h>
 #include <Core/Geometry/Vector.h>
 
 #include <sgi_stl_warnings_off.h>
@@ -14,57 +11,57 @@
 
 using namespace Manta;
 using namespace std;
-using SCIRun::Sqrt;
-
-#define ALLOCATE2DARRAY(array, nx, ny, type)  \
-{                                             \
-       unsigned int i;                       \
-       type * ar = new type[(nx) * (ny)];    \
-                                              \
-       (array) = new type * [nx];            \
-       for(i=0; i<(unsigned int)(nx); i++)   \
-       {                                     \
-               (array)[i] = ar + i*(ny);     \
-       }                                     \
-}
-
-#define DELETE2DARRAY(array, nx)              \
-{                                             \
-       unsigned int i;                       \
-                                              \
-       for(i=0; i<(unsigned int)(nx); i++)   \
-       {                                     \
-               delete [] (array)[i];         \
-       }                                     \
-       delete [] (array);                    \
-       (array) = NULL;                       \
-}
-
 
 
-// 
--------------------------------------------------------------------------------------
-// --- Constructor
-// 
--------------------------------------------------------------------------------------
-Heightfield::Heightfield(Material * material, char * fileName, const Vector 
& minBound, const Vector & maxBound, Real scale)
-  : PrimitiveCommon(material), m_Box(minBound, maxBound)
+Heightfield::Heightfield(Material *material, const string& filename,
+                         const Vector &minBound, const Vector &maxBound// ,
+//                          Real scale
+                         )
+  : PrimitiveCommon(material)
 {
-  readHeightfieldFile(fileName, &m_Nx, &m_Ny, &m_Data);
-  rescaleDataHeight(scale);
-}
+  cout << "\n\nbounds are: " << minBound << " " <<maxBound<<endl;
+  ifstream in(filename.c_str());
+  if(!in){
+    cerr << "Error opening " << filename << "\n";
+    exit(1);
+  }
+  Real minz, maxz;
+  in >> nx >> ny >> minz >> maxz;
+  if(!in){
+    cerr << "Error reading header from " << filename << "\n";
+    exit(1);
+  }
+  in.get();
+  data = new float*[nx+1];
+  float* p = new float[(nx+1)*(ny+1)];
+  for(int i=0;i<=nx;i++)
+    data[i] = p+i*(ny+1);
+  in.read(reinterpret_cast<char*>(data[0]), sizeof(float)*(nx+1)*(ny+1));
+  if(!in){
+    cerr << "Error reading data from " << filename << "\n";
+    exit(1);
+  }
+  Real dz = maxz-minz;
+  if(dz < 1.e-3)
+    dz = 1.e-3;
+  m_Box = BBox( Vector(minBound.x(), minBound.y(), minz-dz*1.e-4),
+                Vector(maxBound.x(), maxBound.y(), maxz+dz*1.e-4));
+  // Step 1
+  diag = m_Box.diagonal();
+  cellsize = diag/Vector(nx, ny, 1);
+  inv_cellsize = cellsize.inverse();
 
+//   readHeightfieldFile(fileName, &m_Nx, &m_Ny, &m_Data);
+//   rescaleDataHeight(scale);
+}
 
-// 
--------------------------------------------------------------------------------------
-// --- Destructor
-// 
--------------------------------------------------------------------------------------
 Heightfield::~Heightfield()
 {
-  DELETE2DARRAY(m_Data, m_Nx+1);
+  for (int i=0; i<=nx; ++i)
+    delete data[i];
+  delete[] data;
 }
 
-
-// 
--------------------------------------------------------------------------------------
-// --- Get the Bounding Box
-// 
--------------------------------------------------------------------------------------
 void Heightfield::computeBounds(const PreprocessContext& /*context*/,
                                 BBox & bbox) const
 {
@@ -79,172 +76,147 @@
 void Heightfield::intersect(const RenderContext& /*context*/,
                             RayPacket& rays) const
 {
-  Vector diagonal;
-  Vector hitPoint;
-  int hitLattice[2], stop[2], di[2], ind;
-  Real tnext[2], dtd[2], far[2], zm[2], datam[2], cellSize[2];
-  Real tnear, tfar, zenter, texit, zexit;
-  bool validtcells[2];
-
   rays.normalizeDirections();
   rays.computeInverseDirections();
 
-  for(int i=rays.begin(); i<rays.end(); i++)
-  {
-    Ray ray = rays.getRay(i);
-
-    using Manta::Min;
-    using Manta::Max;
-    Vector id = rays.getInverseDirection(i);
-    Vector t1 = (m_Box.getMin() - ray.origin()) * id;
-    Vector t2 = (m_Box.getMax() - ray.origin()) * id;
-    Vector tn = Min(t1, t2);
-    Vector tf = Max(t1, t2);
-    tnear = tn.maxComponent();
-    tfar  = tf.minComponent();
-    if (tnear > tfar)
-      continue;
+  for(int rayIndex=rays.begin(); rayIndex<rays.end(); rayIndex++) {
+    Ray ray = rays.getRay(rayIndex);
 
-    using SCIRun::Min;
-    using SCIRun::Max;
 
-    if (m_Box.getMin().x() < ray.origin().x() 
-        && m_Box.getMin().y() < ray.origin().y() 
-        && m_Box.getMin().z() < ray.origin().z() 
-        && m_Box.getMax().x() > ray.origin().x() 
-        && m_Box.getMax().y() > ray.origin().y() 
-        && m_Box.getMax().z() < ray.origin().z() )
-      tnear = 0.0;
-
-    diagonal = m_Box.diagonal();
-    cellSize[0] = diagonal.x() / (Real)m_Nx;
-    cellSize[1] = diagonal.y() / (Real)m_Ny;
-
-    hitPoint = ray.origin() + (ray.direction() * tnear);
-    hitLattice[0] = (int)((hitPoint.x() - m_Box.getMin().x()) / cellSize[0]);
-    hitLattice[1] = (int)((hitPoint.y() - m_Box.getMin().y()) / cellSize[1]);
-
-    if      (hitLattice[0] < 0)          hitLattice[0] = 0;
-    else if (hitLattice[0] >= (int)m_Nx) hitLattice[0] = (int)(m_Nx-1);
-    if      (hitLattice[1] < 0)          hitLattice[1] = 0;
-    else if (hitLattice[1] >= (int)m_Ny) hitLattice[1] = (int)(m_Ny-1);
-
-    di[0] = (diagonal.x() * ray.direction().x() > 0.0) ? 1 : -1;
-    stop[0] = (di[0] == 1) ? (int)m_Nx : -1;
-    di[1] = (diagonal.y() * ray.direction().y() > 0.0) ? 1 : -1;
-    stop[1] = (di[1] == 1) ? (int)m_Ny : -1;
-
-    dtd[0] = fabs(cellSize[0] / ray.direction().x());
-    dtd[1] = fabs(cellSize[1] / ray.direction().y());
-
-    if (di[0] == 1) far[0] = m_Box.getMin().x() + cellSize[0] * 
(Real)(hitLattice[0] + 1);
-    else            far[0] = m_Box.getMin().x() + cellSize[0] * 
(Real)(hitLattice[0]    );
-    if (di[1] == 1) far[1] = m_Box.getMin().y() + cellSize[1] * 
(Real)(hitLattice[1] + 1);
-    else            far[1] = m_Box.getMin().y() + cellSize[1] * 
(Real)(hitLattice[1]    );
-
-    tnext[0] = (far[0] - ray.origin().x()) / ray.direction().x();
-    tnext[1] = (far[1] - ray.origin().y()) / ray.direction().y();
-
-    for(;;)
-    {
-      zenter = ray.origin().z() + (tnear * ray.direction().z());
-      texit  = Min(tnext[0], tnext[1]);
-      zexit  = ray.origin().z() + (texit * ray.direction().z());
-
-      datam[0] = Min(Min(m_Data[hitLattice[0]][hitLattice[1]  ], 
m_Data[hitLattice[0]+1][hitLattice[1]  ]) ,
-                     Min(m_Data[hitLattice[0]][hitLattice[1]+1], 
m_Data[hitLattice[0]+1][hitLattice[1]+1]) );
-      zm[0] = Min(zenter, zexit);
-      datam[1] = Max(Max(m_Data[hitLattice[0]][hitLattice[1]  ], 
m_Data[hitLattice[0]+1][hitLattice[1]  ]) ,
-                     Max(m_Data[hitLattice[0]][hitLattice[1]+1], 
m_Data[hitLattice[0]+1][hitLattice[1]+1]) );
-      zm[1] = Max(zenter, zexit);
-
-      if (!(zm[0] > datam[1] || zm[1] < datam[0]))
-      {
-        Real a, b, c;
-        Real sx, dx, sy, dy;
-        Vector pe;
-        Real ce[2], z[4];
-
-        pe = ray.origin() + ray.direction() * tnear;
-        ce[0] = pe.x() - (m_Box.getMin().x() + cellSize[0] * 
(Real)(hitLattice[0]));
-        ce[1] = pe.y() - (m_Box.getMin().y() + cellSize[1] * 
(Real)(hitLattice[1]));
-
-        sx = ce[0] / cellSize[0];
-        sy = ce[1] / cellSize[1];
-        dx = ray.direction().x() / cellSize[0];
-        dy = ray.direction().y() / cellSize[1];
-
-        z[0] = m_Data[hitLattice[0]  ][hitLattice[1]  ];
-        z[1] = m_Data[hitLattice[0]+1][hitLattice[1]  ] - z[0];
-        z[2] = m_Data[hitLattice[0]  ][hitLattice[1]+1] - z[0];
-        z[3] = m_Data[hitLattice[0]+1][hitLattice[1]+1] - 
m_Data[hitLattice[0]+1][hitLattice[1]] - z[2];
-
-        a = dx * dy * z[3];
-        b = (sx * dy + sy * dx)*z[3] + dx*z[1] + dy*z[2] - 
ray.direction().z();
-        c = sx*sy*z[3] + sx*z[1] + sy*z[2] + z[0] - pe.z();
-
-        if (a == 0.0)
-        {
-          Real tcell, u, v;
-
-          tcell = -c / b;
-          u = sx + tcell * dx;
-          v = sy + tcell * dy;
-
-          if (tcell > T_EPSILON &&
-              tcell < texit &&
-              u > 0 && u < 1 &&
-              v > 0 && v < 1)
-          {
-            if (rays.hit(i, tnear + tcell, getMaterial(), this, 
getTexCoordMapper()))
-              rays.scratchpad<Vector>(i) = Vector(- (z[1] + v*z[3]) / 
cellSize[0], - (z[2] + u*z[3]) / cellSize[1], 1.0);
-            break;
+    // Step 2
+    Vector idir = rays.getInverseDirection(rayIndex);
+    Vector v1 = (m_Box.getMin()-ray.origin())*idir;
+    Vector v2 = (m_Box.getMax()-ray.origin())*idir;
+    Vector vmin = Min(v1, v2);
+    Vector vmax = Max(v1, v2);
+    Real tnear = vmin.maxComponent();
+    Real tfar = vmax.minComponent();
+    if(tnear >= tfar)
+      continue;
+    if(tfar < 1.e-6)
+      continue;
+    if(tnear < 0)
+      tnear = 0;
+
+    // Step 3
+    Vector p = ray.origin() + tnear * ray.direction();
+    int Lx = (int)((p.x()-m_Box.getMin().x())*inv_cellsize.x());
+    Lx = Lx<0?0:Lx>=nx?nx-1:Lx;
+    int Ly = (int)((p.y()-m_Box.getMin().y())*inv_cellsize.y());
+    if(Ly < 0) Ly = 0;
+    else if(Ly >= ny) Ly = ny-1;
+
+    // Step 4
+    Real signx = diag.x()*ray.direction().x();
+    Real signy = diag.y()*ray.direction().y();
+    int dix = signx>0?1:-1;
+    int stopx = signx>0?nx:-1;
+    int diy = signy>0?1:-1;
+    int stopy = signy>0?ny:-1;
+
+    // Step 5
+    Real dtdx = SCIRun::Abs(cellsize.x()/ray.direction().x());
+    Real dtdy = SCIRun::Abs(cellsize.y()/ray.direction().y());
+
+    // Step 6
+    Real far_x;
+    if(signx>0)
+      far_x = (Lx+1)*cellsize.x() + m_Box.getMin().x();
+    else
+      far_x = Lx*cellsize.x() + m_Box.getMin().x();
+    Real far_y;
+    if(signy>0)
+      far_y = (Ly+1)*cellsize.y() + m_Box.getMin().y();
+    else
+      far_y = Ly*cellsize.y() + m_Box.getMin().y();
+
+    // Step 7
+    Real tnext_x = (far_x - ray.origin().x())/ray.direction().x();
+    Real tnext_y = (far_y - ray.origin().y())/ray.direction().y();
+
+    // Step 8
+    Real zenter = ray.origin().z() + tnear * ray.direction().z();
+    tfar = SCIRun::Min((Real)tfar, rays.getMinT(rayIndex));
+    while(tnear < tfar) {
+      Real texit = SCIRun::Min(tnext_x, tnext_y);
+      Real zexit = ray.origin().z() + texit * ray.direction().z();
+
+      // Step 9
+      float datamin = SCIRun::Min(SCIRun::Min(data[Lx][Ly], data[Lx+1][Ly]), 
+                                  SCIRun::Min(data[Lx][Ly+1], 
data[Lx+1][Ly+1]));
+      float datamax = SCIRun::Max(SCIRun::Max(data[Lx][Ly], data[Lx+1][Ly]),
+                                  SCIRun::Max(data[Lx][Ly+1], 
data[Lx+1][Ly+1]));
+      float zmin = SCIRun::Min(zenter, zexit);
+      float zmax = SCIRun::Max(zenter, zexit);
+      if(zmin < datamax && zmax > datamin){
+        // Step 10
+        Vector C = m_Box.getMin() + Vector(Lx, Ly, 0)*cellsize;
+        Vector EC = ray.origin()+tnear*ray.direction()-C;
+        Real Ex = EC.x()*inv_cellsize.x();
+        Real Ey = EC.y()*inv_cellsize.y();
+        Real Ez = ray.origin().z()+tnear*ray.direction().z();
+        Real Vx = ray.direction().x()*inv_cellsize.x();
+        Real Vy = ray.direction().y()*inv_cellsize.y();
+        Real Vz = ray.direction().z();
+        float za = data[Lx][Ly];
+        float zb = data[Lx+1][Ly]-za;
+        float zc = data[Lx][Ly+1]-za;
+        float zd = data[Lx+1][Ly+1]-zb-zc-za;
+        Real a = Vx*Vy*zd;
+        Real b = -Vz + Vx*zb + Vy*zc + (Ex*Vy + Ey*Vx)*zd;
+        Real c = -Ez + za + Ex*zb + Ey*zc + Ex*Ey*zd;
+        if(SCIRun::Abs(a) < 1.e-6){
+          // Linear
+          Real tcell = -c/b;
+          if(tcell > 0 && tnear+tcell < texit){
+            if(rays.hit(rayIndex, tnear+tcell, getMaterial(), this, 
getTexCoordMapper())) {
+              rays.scratchpad<Vector>(rayIndex) = Vector(Lx, Ly, 0);
+              break;
+            }
           }
-        }
-        else
-        {
-          Real delta = b*b - 4*a*c;
-          if (delta >= 0.0)
-          {
-            Real tcells[2], a2, u, v, tcell;
-
-            delta = Sqrt(delta);
-            a2 = 2 * a;
-
-            tcells[0] = (-b - delta) / a2;
-            tcells[1] = (-b + delta) / a2;
-
-            validtcells[0] = (tcells[0] > 0.0 && tcells[0] < texit);
-            validtcells[1] = (tcells[1] > 0.0 && tcells[1] < texit);
-
-            tcell = -1.0;
-            if (validtcells[0] && validtcells[1]) tcell = Min(tcells[0], 
tcells[1]);
-            else if (validtcells[0])              tcell = tcells[0];
-            else if (validtcells[1])              tcell = tcells[1];
-
-            if (tcell > T_EPSILON)
-            {
-              u = sx + tcell * dx;
-              v = sy + tcell * dy;
-              if (u > 0.0 && u < 1.0 && v > 0.0 && v < 1.0)
-              {
-                if (rays.hit(i, tnear + tcell, getMaterial(), this, 
getTexCoordMapper()))
-                  rays.scratchpad<Vector>(i) = Vector( - (z[1] + v*z[3]) / 
cellSize[0], - (z[2] + u*z[3]) / cellSize[1], 1.0);
+        } else {
+          // Solve quadratic
+          Real disc = b*b-4*a*c;
+          if(disc > 0){
+            Real root = sqrt(disc);
+            Real tcell1 = (-b + root)/(2*a);
+            Real tcell2 = (-b - root)/(2*a);
+            if(tcell1 >= 0 && tnear+tcell1 <= texit){
+              if(rays.hit(rayIndex, tnear+tcell1, getMaterial(), this, 
getTexCoordMapper())) {
+                if(tcell2 >= 0)
+                  // Check the other root in case it is closer.
+                  // No need for an additional if() because it will still
+                  // be in the same cell
+                  rays.hit(rayIndex, tnear+tcell2, getMaterial(), this, 
getTexCoordMapper());
+                rays.scratchpad<Vector>(rayIndex) = Vector(Lx, Ly, 0);
+                break;
+              }
+            } else if(tcell2 >= 0 && tnear+tcell2 <= texit){
+              if(rays.hit(rayIndex, tnear+tcell2, getMaterial(), this, 
getTexCoordMapper())){ 
+                rays.scratchpad<Vector>(rayIndex) = Vector(Lx, Ly, 0);
                 break;
               }
             }
           }
-       }
+        }
+      }
+      // Step 11
+      zenter = zexit;
+      if(tnext_x < tnext_y){
+        Lx += dix;
+        if(Lx == stopx)
+          break;
+        tnear = tnext_x;
+        tnext_x += dtdx;
+      } else {
+        Ly += diy;
+        if(Ly == stopy)
+          break;
+        tnear = tnext_y;
+        tnext_y += dtdy;
       }
-
-      ind = (tnext[0] < tnext[1]) ? 0 : 1;
-      tnear = tnext[ind];
-      tnext[ind] += dtd[ind];
-      hitLattice[ind] += di[ind];
-
-      if (hitLattice[0] == stop[0] || hitLattice[1] == stop[1] || tnear > 
tfar)
-        break;
     }
+
   }
 }
 
@@ -255,81 +227,97 @@
 void Heightfield::computeNormal(const RenderContext& /*context*/,
                                 RayPacket& rays) const
 {
-  for (int i=rays.begin(); i<rays.end(); i++)
-    rays.setNormal(i, rays.scratchpad<Vector>(i));
+  rays.computeHitPositions();
+  
+  for (int rayIndex=rays.begin(); rayIndex<rays.end(); rayIndex++) {
+    int Lx = rays.scratchpad<Vector>(rayIndex).x();
+    int Ly = rays.scratchpad<Vector>(rayIndex).y();
+    Vector C = m_Box.getMin() + Vector(Lx, Ly, 0)*cellsize;
+    Real u = (rays.getHitPosition(rayIndex).x()-C.x())*inv_cellsize.x();
+    Real v = (rays.getHitPosition(rayIndex).y()-C.y())*inv_cellsize.y();
+    Real dudx = inv_cellsize.x();
+    Real dvdy = inv_cellsize.y();
+    float za = data[Lx][Ly];
+    float zb = data[Lx+1][Ly]-za;
+    float zc = data[Lx][Ly+1]-za;
+    float zd = data[Lx+1][Ly+1]-zb-zc-za;
+    Real px = dudx*zb + dudx*v*zd;
+    Real py = dvdy*zc + dvdy*u*zd;
+    rays.setNormal( rayIndex, Vector(-px, -py, 1) );
+  }
   rays.setFlag(RayPacket::HaveNormals);
 }
 
 
-// 
--------------------------------------------------------------------------------------
-// --- Rescale the height of the data to fit the Box
-// --- according to the given percentage of the size of the box to which the 
data should be rescaled
-// 
--------------------------------------------------------------------------------------
-void Heightfield::rescaleDataHeight(Real scale)
-{
-  using SCIRun::Min;
-  using SCIRun::Max;
-
-  unsigned int i, j;
-  Real min, max, factor, margin;
-
-  min = m_Data[0][0];
-  max = min;
-  for(i=0; i<=m_Nx; i++)
-    for(j=0; j<=m_Ny; j++)
-    {
-      min = Min(min, m_Data[i][j]);
-      max = Max(max, m_Data[i][j]);
-    }
-
-  factor = m_Box.getMax().z() - m_Box.getMin().z();
-  margin = factor * (1 - scale) * (Real)0.5;
-  factor *= scale / (max - min);
-
-  for(i=0; i<=m_Nx; i++)
-    for(j=0; j<=m_Ny; j++)
-      m_Data[i][j] = ((m_Data[i][j] - min) * factor) + (m_Box.getMin().z() + 
margin);
-}
-
-
-// 
--------------------------------------------------------------------------------------
-// --- Read the given file and returns nx, ny and the data
-// 
--------------------------------------------------------------------------------------
-void Heightfield::readHeightfieldFile(char * fileName, unsigned int * pnx, 
unsigned int * pny, Real *** pdata)
-{
-  Real minz, maxz;
-  int nx, ny, i, j;
-  float ** data;
-
-  ifstream in(fileName, std::ios::in | std::ios::binary);
-  if (!in)
-  {
-    cerr << "Error : unable to open " << fileName << "\n";
-    exit(1);
-  }
-
-  in >> nx >> ny >> minz >> maxz;
-  if (!in)
-  {
-    cerr << "Error : unable to read header from " << fileName << "\n";
-    exit(1);
-  }
-  in.get();
-
-  ALLOCATE2DARRAY(data, nx+1, ny+1, float);
-  in.read((char *)data[0], sizeof(float)*(nx+1)*(ny+1));
-  if (!in)
-  {
-    cerr << "Error : unable to read data from " << fileName << "\n";
-    exit(1);
-  }
+// // 
--------------------------------------------------------------------------------------
+// // --- Rescale the height of the data to fit the Box
+// // --- according to the given percentage of the size of the box to which 
the data should be rescaled
+// // 
--------------------------------------------------------------------------------------
+// void Heightfield::rescaleDataHeight(Real scale)
+// {
+//   using SCIRun::Min;
+//   using SCIRun::Max;
+
+//   unsigned int i, j;
+//   Real min, max, factor, margin;
+
+//   min = m_Data[0][0];
+//   max = min;
+//   for(i=0; i<=m_Nx; i++)
+//     for(j=0; j<=m_Ny; j++)
+//     {
+//       min = Min(min, m_Data[i][j]);
+//       max = Max(max, m_Data[i][j]);
+//     }
+
+//   factor = m_Box.getMax().z() - m_Box.getMin().z();
+//   margin = factor * (1 - scale) * (Real)0.5;
+//   factor *= scale / (max - min);
+
+//   for(i=0; i<=m_Nx; i++)
+//     for(j=0; j<=m_Ny; j++)
+//       m_Data[i][j] = ((m_Data[i][j] - min) * factor) + 
(m_Box.getMin().z() + margin);
+// }
+
+
+// // 
--------------------------------------------------------------------------------------
+// // --- Read the given file and returns nx, ny and the data
+// // 
--------------------------------------------------------------------------------------
+// void Heightfield::readHeightfieldFile(const char *fileName, unsigned int 
* pnx, unsigned int * pny, Real *** pdata)
+// {
+//   Real minz, maxz;
+//   int nx, ny, i, j;
+//   float ** data;
+
+//   ifstream in(fileName, std::ios::in | std::ios::binary);
+//   if (!in)
+//   {
+//     cerr << "Error : unable to open " << fileName << "\n";
+//     exit(1);
+//   }
+
+//   in >> nx >> ny >> minz >> maxz;
+//   if (!in)
+//   {
+//     cerr << "Error : unable to read header from " << fileName << "\n";
+//     exit(1);
+//   }
+//   in.get();
+
+//   ALLOCATE2DARRAY(data, nx+1, ny+1, float);
+//   in.read((char *)data[0], sizeof(float)*(nx+1)*(ny+1));
+//   if (!in)
+//   {
+//     cerr << "Error : unable to read data from " << fileName << "\n";
+//     exit(1);
+//   }
+
+//   *pnx = nx;
+//   *pny = ny;
+//   ALLOCATE2DARRAY(*pdata, nx+1, ny+1, Real);
+//   for(i=0; i<=nx; i++)
+//     for(j=0; j<=ny; j++)
+//       (*pdata)[i][j] = (Real)data[i][j];
 
-  *pnx = nx;
-  *pny = ny;
-  ALLOCATE2DARRAY(*pdata, nx+1, ny+1, Real);
-  for(i=0; i<=nx; i++)
-    for(j=0; j<=ny; j++)
-      (*pdata)[i][j] = (Real)data[i][j];
-
-  //  DELETE2DARRAY(data, nx+1);
-}
+//   //  DELETE2DARRAY(data, nx+1);
+// }

Modified: trunk/Model/Primitives/Heightfield.h
==============================================================================
--- trunk/Model/Primitives/Heightfield.h        (original)
+++ trunk/Model/Primitives/Heightfield.h        Tue Feb 20 14:50:28 2007
@@ -11,23 +11,31 @@
   class Heightfield : public PrimitiveCommon
   {
 
-    public:
+  public:
+    Heightfield(Material *material, const std::string& filename, 
+                const Vector &minBound, const Vector &maxBound //, Real 
scale = 0.95);
+                );
+    virtual ~Heightfield();
 
-                   Heightfield(Material * material, char * fileName, const 
Vector & minBound, const Vector & maxBound, Real scale = 0.95);
-      virtual      ~Heightfield();
+    virtual void computeBounds(const PreprocessContext & context, BBox & 
bbox) const;
+    virtual void intersect(const RenderContext& context, RayPacket& rays) 
const;
+    virtual void computeNormal(const RenderContext & context, RayPacket & 
rays) const;
 
-      virtual void computeBounds(const PreprocessContext & context, BBox & 
bbox) const;
-      virtual void intersect(const RenderContext & context, RayPacket & 
rays) const;
-      virtual void computeNormal(const RenderContext & context, RayPacket & 
rays) const;
-      virtual void rescaleDataHeight(Real scale);
-      virtual void readHeightfieldFile(char * fileName, unsigned int * pnx, 
unsigned int * pny, Real *** pdata);
+//     virtual void rescaleDataHeight(Real scale);
+//     virtual void readHeightfieldFile(const char *fileName, unsigned int * 
pnx, unsigned int * pny, Real *** pdata);
 
-    private:
+  private:
+    BBox m_Box;
+    float** data;
+    int nx, ny;
+    Vector diag;
+    Vector cellsize;
+    Vector inv_cellsize;
+
+    struct HitData {
+      int x, y;
+    };
 
-      BBox         m_Box;
-      unsigned int m_Nx;
-      unsigned int m_Ny;
-      Real **    m_Data;
   };
 }
 

Modified: trunk/scenes/primtest.cc
==============================================================================
--- trunk/scenes/primtest.cc    (original)
+++ trunk/scenes/primtest.cc    Tue Feb 20 14:50:28 2007
@@ -3,6 +3,8 @@
 #include <Image/TGAFile.h>
 #include <Core/Exceptions/IllegalArgument.h>
 #include <Core/Util/Args.h>
+#include <Core/Color/ColorDB.h>
+#include <Core/Exceptions/UnknownColor.h>
 #include <Interface/LightSet.h>
 #include <Interface/Scene.h>
 #include <Model/AmbientLights/ArcAmbient.h>
@@ -18,6 +20,8 @@
 #include <Model/Materials/MetalMaterial.h>
 #include <Model/Materials/Phong.h>
 #include <Model/Materials/Null.h>
+#include <Model/Materials/Flat.h>
+#include <Model/Materials/CopyTextureMaterial.h>
 #include <Model/Instances/Instance.h>
 #include <Model/Instances/InstanceRT.h>
 #include <Model/Instances/InstanceRST.h>
@@ -37,6 +41,7 @@
 #include <Model/Textures/Constant.h>
 #include <Model/Textures/CheckerTexture.h>
 #include <Model/Textures/MarbleTexture.h>
+#include <Model/Textures/NormalTexture.h>
 #include <Model/Readers/PlyReader.h>
 #include <Model/Textures/WoodTexture.h>
 #include <Model/Textures/OakTexture.h>
@@ -67,7 +72,8 @@
   int numx = 8;
   int numy = 8;
   string primtype = "sphere";
-  string material = "redphong";
+  string material = "default";
+  string texture = "default";
   string arraytype = "spin";
   string modelName = 
"/usr/sci/data/Geometry/Stanford_Sculptures/bun_zipper_res4.ply";
   string imageName = "texture.tga";
@@ -89,6 +95,9 @@
     } else if(arg == "-material"){
       if(!getStringArg(i, args, material))
         throw IllegalArgument("scene primtest -material", i, args);
+    } else if(arg == "-texture"){
+      if(!getStringArg(i, args, texture))
+        throw IllegalArgument("scene primtest -texture", i, args);
     } else if(arg == "-array"){
       if(!getStringArg(i, args, arraytype))
         throw IllegalArgument("scene primtest -array", i, args);
@@ -145,78 +154,108 @@
   Material* matl;
   TexCoordMapper* mapr = 0;
 
-  if(material == "redphong")
-    matl=new Phong(Color(RGB(.6,0,0)), Color(RGB(.6,.6,.6)),
-                   32, (ColorComponent)0.4);
-  else if(material == "redlambertian")
-    matl=new Lambertian(Color(RGB(.6,0,0)));
-  else if(material == "null")
-    matl=new Null();
-  else if(material == "metal")
-    matl = new MetalMaterial(Color(RGB(0.7,0.7,0.8)));
-  else if(material == "checker")
-    matl = new Phong(new CheckerTexture<Color>(Color(RGB(.6,.6,.6)),
-                                               Color(RGB(.6,0,0)),
-                                               Vector(1,0,0)*texscale,
-                                               Vector(0,1,0)*texscale),
-                     new Constant<Color>(Color(RGB(.6,.6,.6))),
-                     32,
-                     new Constant<ColorComponent>(0));
-  else if(material == "checker2")
-    matl = new Phong(new CheckerTexture<Color>(Color(RGB(.6,.6,.6)),
-                                               Color(RGB(.6,0,0)),
-                                               Vector(1,0,0)*texscale,
-                                               Vector(0,1,0)*texscale),
-                     new Constant<Color>(Color(RGB(.6,.6,.6))),
-                     32,
-                     new CheckerTexture<ColorComponent>
-                     ((ColorComponent)0.2,
-                      (ColorComponent)0.5,
-                      Vector(1,0,0)*texscale,
-                      Vector(0,1,0)*texscale));
-  else if(material == "checker3")
-    matl = new Checker(new Phong(Color(RGB(.6,.6,.6)), Color(RGB(.6,.6,.6)), 
32, (ColorComponent)0.2),
-                       new Phong(Color(RGB(.6,0,0)), Color(RGB(.6,.6,.6)), 
32, (ColorComponent)0.5),
-                       Vector(1,0,0)*texscale, Vector(0,1,0)*texscale);
-  else if(material == "marble")
-  {
-    matl = new Phong(
-             new MarbleTexture<Color>(
-               Color(RGB(0.1,0.2,0.5)), Color(RGB(0.7,0.8,1.0)),
-               10.0, 1.0, 15.0, 6, 2.0, 0.6 ),
-                     new Constant<Color>(Color(RGB(.6,.6,.6))),
-                     32,
-                     new Constant<ColorComponent>(0));
-    mapr = new UniformMapper();
-  }
-  else if(material == "wood")
-  {
-    matl = new Lambertian(
-             new WoodTexture<Color>(
-               Color(RGB(0.32,0.25,0.21)), Color(RGB(0.41,0.35,0.3)),
-               12.0, 20.0, 5.0, 5.0, 6, 2.0, 0.6 ) );
-    mapr = new UniformMapper();
-  }
-  else if(material == "oak")
-  {
-    matl = new Lambertian(
-             new OakTexture<Color>(
-               Color(RGB(0.15,0.077,0.028)), Color(RGB(0.5,0.2,0.067)),
-               64.0, 0.5, 200.0, 0.02, 1.0, 0.3, 0.4, 1.0, 2.0, 1.0, 0.4 ) );
-    mapr = new UniformMapper();
-  }
-  else if(material == "image")
-  {
-    Image *img = readTGA( imageName );
-    matl = new Lambertian( new ImageTexture<Color>( img ) );
-    mapr = new UniformMapper();
-  }
-  else if(material == "dielectric")
-  {
-    matl = new Dielectric(1.6, 1.0, Color(RGB(.9, .8, .8)));
+  if (texture == "default") {
+    if(material == "redphong" || material == "default")
+      matl=new Phong(Color(RGB(.6,0,0)), Color(RGB(.6,.6,.6)),
+                     32, (ColorComponent)0.4);
+    else if(material == "redlambertian")
+      matl=new Lambertian(Color(RGB(.6,0,0)));
+    else if(material == "null")
+      matl=new Null();
+    else if(material == "metal")
+      matl = new MetalMaterial(Color(RGB(0.7,0.7,0.8)));
+    else if(material == "checker")
+      matl = new Phong(new CheckerTexture<Color>(Color(RGB(.6,.6,.6)),
+                                                 Color(RGB(.6,0,0)),
+                                                 Vector(1,0,0)*texscale,
+                                                 Vector(0,1,0)*texscale),
+                       new Constant<Color>(Color(RGB(.6,.6,.6))),
+                       32,
+                       new Constant<ColorComponent>(0));
+    else if(material == "checker2")
+      matl = new Phong(new CheckerTexture<Color>(Color(RGB(.6,.6,.6)),
+                                                 Color(RGB(.6,0,0)),
+                                                 Vector(1,0,0)*texscale,
+                                                 Vector(0,1,0)*texscale),
+                       new Constant<Color>(Color(RGB(.6,.6,.6))),
+                       32,
+                       new CheckerTexture<ColorComponent>
+                       ((ColorComponent)0.2,
+                        (ColorComponent)0.5,
+                        Vector(1,0,0)*texscale,
+                        Vector(0,1,0)*texscale));
+    else if(material == "checker3")
+      matl = new Checker(new Phong(Color(RGB(.6,.6,.6)), 
Color(RGB(.6,.6,.6)), 32, (ColorComponent)0.2),
+                         new Phong(Color(RGB(.6,0,0)), Color(RGB(.6,.6,.6)), 
32, (ColorComponent)0.5),
+                         Vector(1,0,0)*texscale, Vector(0,1,0)*texscale);
+    else if(material == "marble")
+      {
+        matl = new Phong(
+                         new MarbleTexture<Color>(
+                                                  Color(RGB(0.1,0.2,0.5)), 
Color(RGB(0.7,0.8,1.0)),
+                                                  10.0, 1.0, 15.0, 6, 2.0, 
0.6 ),
+                         new Constant<Color>(Color(RGB(.6,.6,.6))),
+                         32,
+                         new Constant<ColorComponent>(0));
+        mapr = new UniformMapper();
+      }
+    else if(material == "wood")
+      {
+        matl = new Lambertian(
+                              new WoodTexture<Color>(
+                                                     
Color(RGB(0.32,0.25,0.21)), Color(RGB(0.41,0.35,0.3)),
+                                                     12.0, 20.0, 5.0, 5.0, 
6, 2.0, 0.6 ) );
+        mapr = new UniformMapper();
+      }
+    else if(material == "oak")
+      {
+        matl = new Lambertian(
+                              new OakTexture<Color>(
+                                                    
Color(RGB(0.15,0.077,0.028)), Color(RGB(0.5,0.2,0.067)),
+                                                    64.0, 0.5, 200.0, 0.02, 
1.0, 0.3, 0.4, 1.0, 2.0, 1.0, 0.4 ) );
+        mapr = new UniformMapper();
+      }
+    else if(material == "image")
+      {
+        Image *img = readTGA( imageName );
+        matl = new Lambertian( new ImageTexture<Color>( img ) );
+        mapr = new UniformMapper();
+      }
+    else if(material == "dielectric")
+      {
+        matl = new Dielectric(1.6, 1.0, Color(RGB(.9, .8, .8)));
+      }
+    else
+      throw IllegalArgument("Unknown material type for primtest: "+material, 
0, args);
+  } // end if (texture == "default")
+  else {
+    Texture<Color>* tex = NULL;
+    if (texture == "normal") {
+      tex = new NormalTexture();
+    } else {
+      try {
+        if (texture == "default")
+          texture = "red4";
+        Color color = ColorDB::getNamedColor(texture);
+        tex = new Constant<Color>(color);
+      } catch (UnknownColor& e) {
+        throw IllegalArgument("Unknown color name for texture: "+texture, 0, 
args);
+      }
+    }
+    if (material == "copy") {
+      matl = new CopyTextureMaterial(tex);
+    } else if (material == "flat") {
+      matl = new Flat(tex);
+    } else if (material == "phong" || material == "default") {
+      matl=new Phong(tex, new Constant<Color>(Color(RGB(.6,.6,.6))),
+                     32, new Constant<ColorComponent>((ColorComponent)0.4));
+    } else if (material == "lambertian") {
+      matl = new Lambertian( tex );
+    } else {
+      throw IllegalArgument("Unknown material type: "+material, 0, args);
+    }
   }
-  else
-    throw IllegalArgument("Unknown material type for primtest: "+material, 
0, args);
+    
 
   Object* spinprim = 0;
   if(primtype == "simplesphere"){
@@ -332,7 +371,12 @@
        printf("error loading or reading ply file: %s\n", modelName.c_str()); 
//would be better to throw an error.
 #endif //USE_PRIVATE_CODE
   } else if (primtype == "heightfield") {
-    Primitive* prim = new Heightfield(matl, "../sinc200x200.hf", 
Vector(-0.2, -0.2, 0.2), Vector(0.2, 0.2, 0.4));
+
+    Vector anchor(-scale-1./max, -scale-1./max, -1.5/max);
+    Vector v1(scale*20+2./max, 0, 0);
+    Vector v2(0, scale*20+2./max, .1);
+
+    Primitive* prim = new Heightfield(matl, modelName.c_str(), anchor+v1, 
anchor+v2);
     if ( mapr )
         prim->setTexCoordMapper( mapr );
     group->add(prim);




  • [MANTA] r1291 - in trunk: Model/Materials Model/Primitives scenes, thiago, 02/20/2007

Archive powered by MHonArc 2.6.16.

Top of page