Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[Manta] r1742 - in trunk: Model/Primitives scenes


Chronological Thread 
  • From: thiago@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [Manta] r1742 - in trunk: Model/Primitives scenes
  • Date: Fri, 28 Sep 2007 12:16:50 -0600 (MDT)

Author: thiago
Date: Fri Sep 28 12:16:49 2007
New Revision: 1742

Modified:
   trunk/Model/Primitives/Cone.cc
   trunk/Model/Primitives/Cone.h
   trunk/scenes/primtest.cc
Log:
Cone primitive now works correctly (basically rewrote from
scratch). Also added a cone test to primtest.


Modified: trunk/Model/Primitives/Cone.cc
==============================================================================
--- trunk/Model/Primitives/Cone.cc      (original)
+++ trunk/Model/Primitives/Cone.cc      Fri Sep 28 12:16:49 2007
@@ -9,9 +9,8 @@
 using namespace SCIRun;
 using namespace std;
 
-Cone::Cone(Material* mat, const Vector& bottom, const Vector& top,
-           Real Rb, Real Rt)
-  : PrimitiveCommon(mat, this), bottom(bottom), top(top), Rb(Rb), Rt(Rt)
+Cone::Cone(Material* mat, Real radius, Real height)
+  : PrimitiveCommon(mat, this), r(radius), h(height)
 {
 }
 
@@ -21,115 +20,65 @@
 
 void Cone::computeBounds(const PreprocessContext&, BBox& bbox) const
 {
-  Vector axis(top-bottom);
-  axis.normalize();
-  bbox.extendByDisc(bottom, axis, Rb);
-  bbox.extendByDisc(top, axis, Rt);
+  bbox.extendByBox(BBox(Vector(-r,-r,0), Vector(r,r,h)));
 }
 
 void Cone::intersect(const RenderContext&, RayPacket& rays) const
 {
-  if(rays.getFlag(RayPacket::ConstantOrigin)) {
-    Vector Pa = bottom + Rb * (top - bottom) / (Rb-Rt);
-    Real btx = (top.x()-bottom.x())*(top.x()-bottom.x());
-    Real bty = (top.y()-bottom.y())*(top.y()-bottom.y());
-    Real btz = (top.z()-bottom.z())*(top.z()-bottom.z());
-    Real lbt = Sqrt(btx+bty+btz);
-    Real RbRt = Rb-Rt;
-    Real hyp = Sqrt(lbt*lbt + RbRt*RbRt);
-    
-    Vector Va = (top-bottom) / lbt;
-    //    Real tgAlpha = (Rb-Rt) / lbt;
-    Real cosA = RbRt/hyp;
-    Real sinA = lbt/hyp;
-    Real cosA2 = cosA*cosA;
-    Real sinA2 = sinA*sinA;
-    Vector P(xform.multiply_point(rays.getOrigin(rays.begin())));
-    Vector dP(P - Pa);
-    for(int i=rays.begin(); i<rays.end(); i++) {
-      Vector V(xform.multiply_vector(rays.getDirection(i)));
-      Vector tv = V;
-      Real dist_scale = tv.normalize();
-      Real a = ((cosA2*Dot(V-Dot(V,Va)*Va, V-Dot(V,Va)*Va))-
-                (sinA2*Dot(V,Va)*Dot(V,Va)));
-      Real b = (2*cosA2*Dot(V-Dot(V,Va)*Va, dP-Dot(dP,Va)*Va)-
-                2*sinA2*Dot(V,Va)*Dot(dP,Va));
-      Real c = (cosA2*Dot(dP-Dot(dP,Va)*Va,
-                          dP-Dot(dP,Va)*Va)-
-                sinA2*Dot(dP,Va)*Dot(dP,Va));
-
-      Real d = Sqrt(b*b-4*a*c);
-
-      if(d > 0.0) {
-        Real t1 = (-b+d)/(2*a);
-        Real t2 = (-b-d)/(2*a);
-
-        if(t1 < t2) {
-          Real temp = t1;
-          t1 = t2;
-          t2 = temp;
-        }
-
-        Real z1 = P.z()+t1*V.z();
-        Real z2 = P.z()+t2*V.z();
-        if(t1>0 && z1 > 0 && z1 < 1) {
-          rays.hit(i, t1/dist_scale, getMaterial(), this, 
getTexCoordMapper());
-        }
-        if(t2>0 && z2 > 0 && z2 < 1) {
-          rays.hit(i, t2/dist_scale, getMaterial(), this, 
getTexCoordMapper());
-        }
-      }
-    }
-  }
-  else {
-    Vector Pa = bottom + Rb * (top - bottom) / (Rb-Rt);
-    Real btx = (top.x()-bottom.x())*(top.x()-bottom.x());
-    Real bty = (top.y()-bottom.y())*(top.y()-bottom.y());
-    Real btz = (top.z()-bottom.z())*(top.z()-bottom.z());
-    Real lbt = Sqrt(btx+bty+btz);
-    Real RbRt = Rb-Rt;
-    Real hyp = Sqrt(lbt*lbt + RbRt*RbRt);
-
-    Vector Va = (top-bottom) / lbt;
-    //    Real tgAlpha = (Rb-Rt) / lbt;
-    Real cosA = RbRt/hyp;
-    Real sinA = lbt/hyp;
-    Real cosA2 = cosA*cosA;
-    Real sinA2 = sinA*sinA;
-    for(int i=rays.begin(); i<rays.end(); i++) {
-      Vector P(xform.multiply_point(rays.getOrigin(i)));
-      Vector dP(P - Pa);
-      Vector V(xform.multiply_vector(rays.getDirection(i)));
-      Vector tv = V;
-      Real dist_scale = tv.normalize();
-      Real a = ((cosA2*Dot(V-Dot(V,Va)*Va, V-Dot(V,Va)*Va))-
-                (sinA2*Dot(V,Va)*Dot(V,Va)));
-      Real b = (2*cosA2*Dot(V-Dot(V,Va)*Va, dP-Dot(dP,Va)*Va)-
-                2*sinA2*Dot(V,Va)*Dot(dP,Va));
-      Real c = (cosA2*Dot(dP-Dot(dP,Va)*Va, dP-Dot(dP,Va)*Va)-
-                sinA2*Dot(dP,Va)*Dot(dP,Va));
-
-      Real d = Sqrt(b*b-4*a*c);
-
-      if(d > 0) {
-        Real t1 = (-b+d)/(2*a);
-        Real t2 = (-b-d)/(2*a);
-
-        if(t1 < t2) {
-          Real temp = t1;
-          t1 = t2;
-          t2 = temp;
-        }
-
-        Real z1 = P.z()+t1*V.z();
-        Real z2 = P.z()+t2*V.z();
-        if(t1>0 && z1 > 0 && z1 < 1) {
-          rays.hit(i, t1/dist_scale, getMaterial(), this, 
getTexCoordMapper());
-        }
-        if(t2>0 && z2 > 0 && z2 < 1) {
-          rays.hit(i, t2/dist_scale, getMaterial(), this, 
getTexCoordMapper());
-        }
+  //Equation of cone is x^2+y^2 == (r/h)^2 * (z-h)^2
+  //h is height of cone and cone base is located on z=0, xy plane
+  //(cone is oriented along z-axis).
+
+  // In[7]:= Expand[x^2+y^2==(r/h)^2 * (z-h)^2]
+  //
+  //           2     2                             2  2     2  2
+  // Out[7]= Ox  + Oy  + 2 Dx Ox t + 2 Dy Oy t + Dx  t  + Dy  t  == 
+  // 
+  //                 2     2  2         2              2       2  2  2
+  //       2   2 Oz r    Oz  r    2 Dz r  t   2 Dz Oz r  t   Dz  r  t
+  // >    r  - ------- + ------ - --------- + ------------ + ---------
+  //              h         2         h             2            2
+  //                       h                       h            h
+
+  //Solve quadratic equation in t.
+  //Note that the code below looks different because we've factored
+  //terms out, and done other algebraic optimizations.
+
+  const Real r_invh = r/h;
+  const Real r_invh2 = r_invh*r_invh;
+
+  for(int i=rays.begin(); i<rays.end(); i++) {
+    const Vector O = rays.getOrigin(i);
+    const Vector D = rays.getDirection(i);
+    const Vector O2 = O*O;
+    const Vector D2 = D*D;
+    const Vector DO = D*O;
+
+    const Real h_Oz = h-O.z();
+    const Real h_Oz_r_invh2 = h_Oz*r_invh2;
+
+    const Real a = D2.x() + D2.y() - D2.z()*r_invh2;
+    const Real b = 2*(DO.x() + DO.y() + D.z()*h_Oz_r_invh2);
+    const Real c = O2.x() + O2.y() - (h_Oz*h_Oz_r_invh2);
+
+    const Real d2 = b*b-4*a*c;
+    if (d2 >= 0) {
+      const Real d = Sqrt(d2);
+      const Real inv2a = 1/(2*a);
+      Real t1 = (-b+d)*inv2a;
+      Real t2 = (-b-d)*inv2a;
+
+      if(t1 > t2) {
+        swap(t1, t2);
       }
+
+      Real z1 = O.z() + t1*D.z();
+      Real z2 = O.z() + t2*D.z();
+
+      if (z1 >= 0 && z1 <= h)
+        rays.hit(i, t1, getMaterial(), this, getTexCoordMapper());
+      else if (z2 >= 0 && z2 <= h)
+        rays.hit(i, t2, getMaterial(), this, getTexCoordMapper());
     }
   }
 }
@@ -139,15 +88,10 @@
 {
   rays.computeHitPositions();
   for(int i=rays.begin(); i<rays.end(); i++) {
-#if 0
-    Vector xn(xform.project(e.hitPosition).asVector());
-    xn.z(0);
-    Vector v=ixform.project(xn);
-    v.normalize();
-    e.normal = v;
-#else
-    NOT_FINISHED("Cone::computeNormal");
-#endif
+    Vector xn = rays.getHitPosition(i);
+    const Real r_prime = Sqrt(xn.x()*xn.x() + xn.y()*xn.y());
+    xn[2] = r/h*r_prime;
+    rays.setNormal(i, xn);
   }
 }
 
@@ -159,10 +103,8 @@
   rays.setFlag(RayPacket::HaveTexture2|RayPacket::HaveTexture3);
 }
 
-void Cone::computeTexCoords3(const RenderContext&,
+void Cone::computeTexCoords3(const RenderContext& context,
                                      RayPacket& rays) const
 {
-  for(int i=rays.begin();i<rays.end();i++)
-    rays.setTexCoords(i, rays.scratchpad<Vector>(i));
-  rays.setFlag(RayPacket::HaveTexture2|RayPacket::HaveTexture3);
+  computeTexCoords2(context, rays);
 }

Modified: trunk/Model/Primitives/Cone.h
==============================================================================
--- trunk/Model/Primitives/Cone.h       (original)
+++ trunk/Model/Primitives/Cone.h       Fri Sep 28 12:16:49 2007
@@ -11,8 +11,7 @@
 {
   class Cone : public PrimitiveCommon, public TexCoordMapper {
   public:
-    Cone(Material* mat, const Vector& bottom, const Vector& top,
-         Real Rb, Real Rt);
+    Cone(Material* mat, Real radius, Real height);
     virtual ~Cone();
     
     virtual void computeBounds(const PreprocessContext& context,
@@ -25,9 +24,7 @@
                                   RayPacket& rays) const;
     
   private:
-    Vector bottom, top;
-    Real Rb, Rt;
-    AffineTransform xform, ixform;
+    Real r, h;
   };
 }
 

Modified: trunk/scenes/primtest.cc
==============================================================================
--- trunk/scenes/primtest.cc    (original)
+++ trunk/scenes/primtest.cc    Fri Sep 28 12:16:49 2007
@@ -31,6 +31,7 @@
 #include <Model/Instances/InstanceRST.h>
 #include <Model/Instances/InstanceST.h>
 #include <Model/Instances/InstanceT.h>
+#include <Model/Primitives/Cone.h>
 #include <Model/Primitives/Cube.h>
 #include <Model/Primitives/Disk.h>
 #include <Model/Primitives/Hemisphere.h>
@@ -315,6 +316,13 @@
     if ( mapr )
       prim->setTexCoordMapper( mapr );
     spinprim = prim;
+  } else if(primtype == "cone"){
+     Primitive* prim = new Cone(matl, scale/max, scale/max*2);
+//     Primitive* prim = new Cone(matl, 3, 10);
+    if ( mapr )
+      prim->setTexCoordMapper( mapr );
+    spinprim = prim;
+//     group->add(prim);
   } else if(primtype == "intersection"){
     Vector p2(scale/max/1.414, scale/max/1.414, scale/max/1.414);
     Primitive* o1 = new Cube(matl, -p2, p2);




  • [Manta] r1742 - in trunk: Model/Primitives scenes, thiago, 09/28/2007

Archive powered by MHonArc 2.6.16.

Top of page