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