Text archives Help
- 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.