Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r277 - trunk/Model/Primitives


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

Author: edwards
Date: Tue May 10 15:35:05 2005
New Revision: 277

Added:
   trunk/Model/Primitives/Hemisphere.cc
   trunk/Model/Primitives/Hemisphere.h
Modified:
   trunk/Model/Primitives/CMakeLists.txt
   trunk/Model/Primitives/Disk.cc
Log:
Added Hemisphere primitives and fixed Disks



Modified: trunk/Model/Primitives/CMakeLists.txt
==============================================================================
--- trunk/Model/Primitives/CMakeLists.txt       (original)
+++ trunk/Model/Primitives/CMakeLists.txt       Tue May 10 15:35:05 2005
@@ -8,4 +8,5 @@
      Primitives/Cone.cc
      Primitives/Triangle.cc
      Primitives/Disk.cc
+     Primitives/Hemisphere.cc
 )

Modified: trunk/Model/Primitives/Disk.cc
==============================================================================
--- trunk/Model/Primitives/Disk.cc      (original)
+++ trunk/Model/Primitives/Disk.cc      Tue May 10 15:35:05 2005
@@ -27,7 +27,7 @@
 void Disk::intersect(const RenderContext& context, RayPacket& rays) const {
   int i, numRays(rays.getSize());
   const static double EPSILON(1.0e-6);
-  Point rayO, p;
+  Point rayO;
   Vector rayD;
   double denom, t;
 
@@ -42,11 +42,8 @@
 
       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);
-         }
+       if (checkBounds(rayO + t * rayD)) {
+         e.hitInfo.hit(t, material, this, tex);
        }
       }
     }
@@ -59,11 +56,8 @@
 
       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);
-         }
+       if (checkBounds(rayO + t * rayD)) {
+         e.hitInfo.hit(t, material, this, tex);
        }
       }
     }
@@ -136,9 +130,8 @@
     return false;
 
   if (_partial) {
-    double uComp(Dot(_u, dir)), vComp(Dot(_v, dir)), theta;
+    double theta(atan2(Dot(_v, dir), Dot(_u, dir)));
 
-    theta = atan2(vComp, uComp);
     if (theta < 0.0)
       theta = 2.0 * M_PI + theta;
     if ((theta < _minTheta) || (theta > _maxTheta))
@@ -183,11 +176,9 @@
  **/
 void Disk::getTexCoords(Point& p) const {
   Vector dir(p - _c);
-  double dist(dir.normalize()), uComp, vComp, theta;
+  double dist(dir.normalize()), theta;
 
-  uComp = Dot(_u, dir);
-  vComp = Dot(_v, dir);
-  theta = atan2(vComp, uComp);
+  theta = atan2(Dot(_v, dir), Dot(_u, dir));
   if (theta < 0.0)
     theta = 2.0 * M_PI + theta;
   

Added: trunk/Model/Primitives/Hemisphere.cc
==============================================================================
--- (empty file)
+++ trunk/Model/Primitives/Hemisphere.cc        Tue May 10 15:35:05 2005
@@ -0,0 +1,208 @@
+#include <Model/Primitives/Hemisphere.h>
+#include <Interface/RayPacket.h>
+#include <Core/Geometry/BBox.h>
+#include <Core/Math/MiscMath.h>
+
+using namespace Manta;
+using namespace std;
+
+Hemisphere::Hemisphere(Material* material, const Point& center, double 
radius, const Vector& normal) : PrimitiveCommon(material, this), _c(center), 
_r(radius), _n(normal) {
+  setupAxes();
+}
+
+Hemisphere::~Hemisphere() {
+}
+
+void Hemisphere::computeBounds(const PreprocessContext&, BBox& bbox) const {
+  bbox.extend(_c, _r);
+}
+
+void Hemisphere::intersect(const RenderContext&, RayPacket& rays) const {
+  int i, numRays(rays.getSize()),
+    rpFlags(rays.getFlags() & (RayPacket::ConstantOrigin | 
RayPacket::NormalizedDirections));
+  double a, b, c, disc, r, t;
+  Point rayO;
+  Vector rayD, tRayO;
+
+  if (rpFlags == (RayPacket::ConstantOrigin | 
RayPacket::NormalizedDirections)) {
+    // Rays all have the same origin and unit-length directions
+    rayO = rays.get(0).ray.origin();
+    tRayO = rayO - _c;
+    c = Dot(tRayO, tRayO) - _r * _r;
+
+    for (i = 0; i < numRays; i++) {
+      RayPacket::Element& e(rays.get(i));
+      
+      rayD = e.ray.direction();
+      
+      b = Dot(tRayO, rayD);
+      disc = b * b - c;
+      
+      if (disc >= 0.0) {
+       r = sqrt(disc);
+       t = -(b + r);
+       if ((t > 0.0) && checkBounds(rayO + t * rayD)) {
+         e.hitInfo.hit(t, material, this, tex);
+       } else {
+         t = r - b;
+         if ((t > 0.0) && checkBounds(rayO + t * rayD)) {
+           e.hitInfo.hit(t, material, this, tex);
+         }
+       }
+      }
+    }
+  } else if (rpFlags == RayPacket::ConstantOrigin) {
+    // Rays all have the same origin
+    rayO = rays.get(0).ray.origin();
+    tRayO = rayO - _c;
+    c = Dot(tRayO, tRayO) - _r * _r;
+
+    for (i = 0; i < numRays; i++) {
+      RayPacket::Element& e(rays.get(i));
+      
+      rayD = e.ray.direction();
+      
+      a = Dot(rayD, rayD);
+      b = Dot(tRayO, rayD);
+      disc = b * b - a * c;
+      
+      if (disc >= 0.0) {
+       r = sqrt(disc);
+       t = -(b + r) / a;
+       if ((t > 0.0) && checkBounds(rayO + t * rayD)) {
+         e.hitInfo.hit(t, material, this, tex);
+       } else {
+         t = (r - b) / a;
+         if ((t > 0.0) && checkBounds(rayO + t * rayD)) {
+           e.hitInfo.hit(t, material, this, tex);
+         }
+       }
+      }
+    }
+  } else if (rpFlags == RayPacket::NormalizedDirections) {
+    // Rays all have unit-length direction
+    for (i = 0; i < numRays; i++) {
+      RayPacket::Element& e(rays.get(i));
+      
+      rayO = e.ray.origin();
+      rayD = e.ray.direction();
+      tRayO = rayO - _c;
+      
+      b = Dot(tRayO, rayD);
+      c = Dot(tRayO, tRayO) - _r * _r;
+      disc = b * b - c;
+      
+      if (disc >= 0.0) {
+       r = sqrt(disc);
+       t = -(b + r);
+       if ((t > 0.0) && checkBounds(rayO + t * rayD)) {
+         e.hitInfo.hit(t, material, this, tex);
+       } else {
+         t = r - b;
+         if ((t > 0.0) && checkBounds(rayO + t * rayD)) {
+           e.hitInfo.hit(t, material, this, tex);
+         }
+       }
+      }
+    }
+  } else {
+    // General rays
+    for (i = 0; i < numRays; i++) {
+      RayPacket::Element& e(rays.get(i));
+      
+      rayO = e.ray.origin();
+      rayD = e.ray.direction();
+      tRayO = rayO - _c;
+      
+      a = Dot(rayD, rayD);
+      b = Dot(tRayO, rayD);
+      c = Dot(tRayO, tRayO) - _r * _r;
+      disc = b * b - a * c;
+      
+      if (disc >= 0.0) {
+       r = sqrt(disc);
+       t = -(b + r) / a;
+       if ((t > 0.0) && checkBounds(rayO + t * rayD)) {
+         e.hitInfo.hit(t, material, this, tex);
+       } else {
+         t = (r - b) / a;
+         if ((t > 0.0) && checkBounds(rayO + t * rayD)) {
+           e.hitInfo.hit(t, material, this, tex);
+         }
+       }
+      }
+    }
+  }
+}
+
+void Hemisphere::computeNormal(const RenderContext& context, RayPacket& 
rays) const {
+  int i, numRays(rays.getSize());
+
+  if (!(rays.getFlags() & RayPacket::HaveHitPositions))
+    rays.computeHitPositions();
+
+  for (i = 0; i < numRays; i++) {
+    RayPacket::Element& e = rays.get(i);
+    e.normal = e.hitPosition - _c;
+    e.normal.normalize();
+  }
+
+  rays.setFlag(RayPacket::HaveNormals | RayPacket::HaveUnitNormals);
+}
+
+void Hemisphere::computeTexCoords2(const RenderContext& context, RayPacket& 
rays) const {
+  int i, numRays(rays.getSize());
+  Vector n;
+  double theta, phi;
+
+  if (!(rays.getFlags() & RayPacket::HaveUnitNormals))
+    computeNormal(context, rays);
+
+  for (i = 0; i < numRays; i++) {
+    RayPacket::Element& e(rays.get(i));
+    n = e.normal;
+    theta = acos(Dot(_n, n));
+    phi = atan2(Dot(_u, n), Dot(_v, n));
+    e.texCoords = Point(0.5 * phi / M_PI, 2.0 * theta / M_PI, 0.0);
+  }
+
+  rays.setFlag(RayPacket::HaveTexture2);
+}
+
+void Hemisphere::computeTexCoords3(const RenderContext&, RayPacket& rays) 
const {
+  int i, numRays(rays.getSize());
+  Vector n;
+
+  if (!(rays.getFlags() & RayPacket::HaveHitPositions))
+    rays.computeHitPositions();
+
+  for (i = 0; i < numRays; i++) {
+    RayPacket::Element& e(rays.get(i));
+    e.texCoords = e.hitPosition;
+  }
+
+  rays.setFlag(RayPacket::HaveTexture3);
+}
+
+/**
+ * checkBounds(p)
+ *
+ * Given a point p assumed to lie on the sphere, checks to make sure it lies
+ * within the correct hemisphere.
+ **/
+bool Hemisphere::checkBounds(const Point& p) const {
+  return (Dot(_n, p - _c) >= 0.0);
+}
+
+void Hemisphere::setupAxes() {
+  const static double EPSILON(1.0e-6);
+
+  _u = Vector(1.0, 0.0, 0.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);
+}

Added: trunk/Model/Primitives/Hemisphere.h
==============================================================================
--- (empty file)
+++ trunk/Model/Primitives/Hemisphere.h Tue May 10 15:35:05 2005
@@ -0,0 +1,32 @@
+#ifndef Manta_Model_Hemisphere_h
+#define Manta_Model_Hemisphere_h
+
+#include <Model/Primitives/PrimitiveCommon.h>
+#include <Interface/TexCoordMapper.h>
+#include <Core/Geometry/Point.h>
+
+namespace Manta {
+  using namespace SCIRun;
+  class Hemisphere : public PrimitiveCommon, public TexCoordMapper {
+  public:
+    Hemisphere(Material* material, const Point& center, double radius, const 
Vector& normal);
+    virtual ~Hemisphere();
+
+    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:
+    Point _c;
+    double _r;
+    Vector _n, _u, _v;
+
+    bool checkBounds(const Point& p) const;
+    void setupAxes();
+  };
+}
+
+#endif




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

Archive powered by MHonArc 2.6.16.

Top of page