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