Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r275 - trunk/Model/Primitives


Chronological Thread 
  • From: edwards@sci.utah.edu
  • To: rtrt@sci.utah.edu
  • Subject: [MANTA] r275 - trunk/Model/Primitives
  • Date: Tue, 10 May 2005 13:41:20 -0600 (MDT)

Author: edwards
Date: Tue May 10 13:41:19 2005
New Revision: 275

Added:
   trunk/Model/Primitives/Disk.cc
   trunk/Model/Primitives/Disk.h
Modified:
   trunk/Model/Primitives/CMakeLists.txt
Log:
Added Disk primitive and updated CMakeLists.txt to include it


Modified: trunk/Model/Primitives/CMakeLists.txt
==============================================================================
--- trunk/Model/Primitives/CMakeLists.txt       (original)
+++ trunk/Model/Primitives/CMakeLists.txt       Tue May 10 13:41:19 2005
@@ -7,4 +7,5 @@
      Primitives/Cube.cc
      Primitives/Cone.cc
      Primitives/Triangle.cc
+     Primitives/Disk.cc
 )

Added: trunk/Model/Primitives/Disk.cc
==============================================================================
--- (empty file)
+++ trunk/Model/Primitives/Disk.cc      Tue May 10 13:41:19 2005
@@ -0,0 +1,197 @@
+#include <Model/Primitives/Disk.h>
+#include <Interface/RayPacket.h>
+#include <Core/Geometry/BBox.h>
+
+using namespace Manta;
+using namespace std;
+
+Disk::Disk(Material* mat, const Point& center, const Vector& n, double 
radius, const Vector& axis) : PrimitiveCommon(mat, this), _c(center), _n(n), 
_r(radius), _partial(false), _minTheta(0.0), _maxTheta(2.0 * M_PI) {
+  _n.normalize();
+  _d = -Dot(_n, _c);
+  setupAxes(axis);
+}
+
+Disk::Disk(Material* mat, const Point& center, const Vector& n, double 
radius, const Vector& axis, double minTheta, double maxTheta) : 
PrimitiveCommon(mat, this), _c(center), _n(n), _r(radius), _partial(true), 
_minTheta(minTheta), _maxTheta(maxTheta) {
+  _n.normalize();
+  _d = -Dot(_n, _c);
+  setupAxes(axis);
+}
+
+Disk::~Disk() {
+}
+
+void Disk::computeBounds(const PreprocessContext& context, BBox& bbox) const 
{
+  bbox.extend_disc(_c, _n, _r);
+}
+
+void Disk::intersect(const RenderContext& context, RayPacket& rays) const {
+  int i, numRays(rays.getSize());
+  const static double EPSILON(1.0e-6);
+  Point rayO, p;
+  Vector rayD;
+  double denom, t;
+
+  if (rays.getFlags() & RayPacket::ConstantOrigin) {
+    rayO = rays.get(0).ray.origin();
+    double nDotO(Dot(_n, rayO));
+
+    for (i = 0; i < numRays; i++) {
+      RayPacket::Element& e(rays.get(i));
+      rayD = e.ray.direction();
+      denom = Dot(_n, rayD);
+
+      if ((denom < -EPSILON) || (denom > EPSILON)) {
+       t = -(_d + nDotO) / denom;
+       if (!e.hitInfo.wasHit() || (t < e.hitInfo.minT())) {
+         p = rayO + t * rayD;
+         if (checkBounds(p)) {
+           e.hitInfo.hit(t, material, this, tex);
+         }
+       }
+      }
+    }
+  } else {
+    for (i = 0; i < numRays; i++) {
+      RayPacket::Element& e(rays.get(i));
+      rayD = e.ray.direction();
+      rayO = e.ray.origin();
+      denom = Dot(_n, rayD);
+
+      if ((denom < -EPSILON) || (denom > EPSILON)) {
+       t = -(_d + Dot(_n, rayO)) / denom;
+       if (!e.hitInfo.wasHit() || (t < e.hitInfo.minT())) {
+         p = rayO + t * rayD;
+         if (checkBounds(p)) {
+           e.hitInfo.hit(t, material, this, tex);
+         }
+       }
+      }
+    }
+  }
+}
+
+
+void Disk::computeNormal(const RenderContext& context, RayPacket& rays) 
const {
+  int i, numRays(rays.getSize());
+  
+  for (i = 0; i < numRays; i++) {
+    RayPacket::Element& e(rays.get(i));
+    e.normal = _n;
+  }
+
+  // set flags to indicate packet now has unit normals
+  rays.setFlag(RayPacket::HaveNormals & RayPacket::HaveUnitNormals);
+}
+
+void Disk::computeTexCoords2(const RenderContext& context, RayPacket& rays) 
const {
+  int i, numRays(rays.getSize());
+  Point p;
+
+  // compute hit locations if necessary
+  if (!(rays.getFlags() & RayPacket::HaveHitPositions))
+    rays.computeHitPositions();
+
+  // set 2-d texture coordinates as returned by getTexCoords()
+  for (i = 0; i < numRays; i++) {
+    RayPacket::Element& e(rays.get(i));
+    p = e.hitPosition;
+    getTexCoords(p);
+    e.texCoords = p;
+  }
+
+  // set flag to show texcoords have been computed
+  rays.setFlag(RayPacket::HaveTexture2);
+}
+
+void Disk::computeTexCoords3(const RenderContext& context, RayPacket& rays) 
const {
+  int i, numRays(rays.getSize());
+  Point p;
+
+  // compute hit locations if necessary
+  if (!(rays.getFlags() & RayPacket::HaveHitPositions))
+    rays.computeHitPositions();
+
+  // set 3-d texture coordinates to be the hit locations
+  for (i = 0; i < numRays; i++) {
+    RayPacket::Element& e(rays.get(i));
+    e.texCoords = e.hitPosition;
+  }
+
+  // set flag to show texcoords have been computed
+  rays.setFlag(RayPacket::HaveTexture3);
+}
+
+/**
+ * checkBounds(p)
+ *
+ * Assumes the point p lies in the same plane as the disk.  Returns true if p
+ * lies within the region of the plane encompassed by the (possibly partial)
+ * disk, false otherwise.
+ **/
+bool Disk::checkBounds(const Point& p) const {
+  Vector dir(p - _c);
+  double dist(dir.normalize());
+
+  if (dist > _r)
+    return false;
+
+  if (_partial) {
+    double uComp(Dot(_u, dir)), vComp(Dot(_v, dir)), theta;
+
+    theta = atan2(vComp, uComp);
+    if (theta < 0.0)
+      theta = 2.0 * M_PI + theta;
+    if ((theta < _minTheta) || (theta > _maxTheta))
+      return false;
+  }
+
+  return true;
+}
+
+/**
+ * setupAxes(axis)
+ *
+ * Sets up the local coordinate system of the disk.  The disk normal is 
always
+ * preserved.  After calling this function, the u axis will be the 
projection of
+ * the given vector axis onto the plane of the disk.  If the given vector is
+ * close to the direction of the normal, then the z-axis is used instead of 
the
+ * given vector.
+ **/
+void Disk::setupAxes(const Vector& axis) {
+  const static double EPSILON(1.0e-6);
+
+  _u = axis;
+  _u.normalize();
+  _v = Cross(_n, _u);
+  if (_v.length2() < EPSILON) {
+    _u = Vector(0.0, 0.0, 1.0);
+    _v = Cross(_n, _u);
+    if (_v.length2() < EPSILON) {
+      _u = Vector(0.0, 1.0, 0.0);
+      _v = Cross(_n, _u);
+    }
+  }
+  _v.normalize();
+  _u = Cross(_v, _n);
+}
+
+/**
+ * getTexCoords(p)
+ *
+ * Assumes the point p lies within the disk.  Returns the 2-D texture
+ * coordinates in the disk in p.
+ **/
+void Disk::getTexCoords(Point& p) const {
+  Vector dir(p - _c);
+  double dist(dir.normalize()), uComp, vComp, theta;
+
+  uComp = Dot(_u, dir);
+  vComp = Dot(_v, dir);
+  theta = atan2(vComp, uComp);
+  if (theta < 0.0)
+    theta = 2.0 * M_PI + theta;
+  
+  p = Point(dist / _r, (theta - _minTheta) / (_maxTheta - _minTheta), 0.0);
+}
+
+

Added: trunk/Model/Primitives/Disk.h
==============================================================================
--- (empty file)
+++ trunk/Model/Primitives/Disk.h       Tue May 10 13:41:19 2005
@@ -0,0 +1,36 @@
+#ifndef Manta_Model_Disk_h
+#define Manta_Model_Disk_h
+
+#include <Model/Primitives/PrimitiveCommon.h>
+#include <Interface/TexCoordMapper.h>
+#include <Core/Geometry/Point.h>
+#include <Core/Geometry/Vector.h>
+
+namespace Manta {
+  using namespace SCIRun;
+  class Disk : public PrimitiveCommon, public TexCoordMapper {
+  public:
+    Disk(Material* mat, const Point& center, const Vector& n, double radius, 
const Vector& axis);
+    Disk(Material* mat, const Point& center, const Vector& n, double radius, 
const Vector& axis, double minTheta, double maxTheta);
+    virtual ~Disk();
+    
+    virtual void computeBounds(const PreprocessContext& context, 
SCIRun::BBox& bbox) const;
+    virtual void intersect(const RenderContext& context, RayPacket& rays) 
const ;
+    virtual void computeNormal(const RenderContext& context, RayPacket& 
rays) const;
+    
+    virtual void computeTexCoords2(const RenderContext& context, RayPacket& 
rays) const;
+    virtual void computeTexCoords3(const RenderContext& context, RayPacket& 
rays) const;
+    
+  private:
+    bool _partial;
+    Point _c;
+    Vector _n, _u, _v;
+    double _d, _r, _minTheta, _maxTheta;
+
+    bool checkBounds(const Point& p) const;
+    void setupAxes(const Vector& axis);
+    void getTexCoords(Point& p) const;
+  };
+}
+
+#endif




  • [MANTA] r275 - trunk/Model/Primitives, edwards, 05/10/2005

Archive powered by MHonArc 2.6.16.

Top of page