00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "shape.h"
00025 #include "mc.h"
00026
00027 namespace lux
00028 {
00029
00030
00031 class Sphere: public Shape {
00032 public:
00033
00034 Sphere(const Transform &o2w, bool ro, float rad,
00035 float zmin, float zmax, float phiMax);
00036 BBox ObjectBound() const;
00037 bool Intersect(const Ray &ray, float *tHit,
00038 DifferentialGeometry *dg) const;
00039 bool IntersectP(const Ray &ray) const;
00040 float Area() const;
00041 Point Sample(float u1, float u2, Normal *ns) const {
00042 Point p = Point(0,0,0) + radius *
00043 UniformSampleSphere(u1, u2);
00044 *ns = Normalize(ObjectToWorld(Normal(p.x, p.y, p.z)));
00045 if (reverseOrientation) *ns *= -1.f;
00046 return ObjectToWorld(p);
00047 }
00048 Point Sample(const Point &p,
00049 float u1, float u2, Normal *ns) const {
00050
00051 Point Pcenter = ObjectToWorld(Point(0,0,0));
00052 Vector wc = Normalize(Pcenter - p);
00053 Vector wcX, wcY;
00054 CoordinateSystem(wc, &wcX, &wcY);
00055
00056 if (DistanceSquared(p, Pcenter) - radius*radius < 1e-4f)
00057 return Sample(u1, u2, ns);
00058
00059 float cosThetaMax = sqrtf(max(0.f, 1.f - radius*radius /
00060 DistanceSquared(p, Pcenter)));
00061 DifferentialGeometry dgSphere;
00062 float thit;
00063 Point ps;
00064 Ray r(p,
00065 UniformSampleCone(u1, u2, cosThetaMax, wcX, wcY, wc));
00066 if (!Intersect(r, &thit, &dgSphere)) {
00067 ps = Pcenter - radius * wc;
00068 } else {
00069 ps = r(thit);
00070 }
00071 *ns = Normal(Normalize(ps - Pcenter));
00072 if (reverseOrientation) *ns *= -1.f;
00073 return ps;
00074 }
00075 float Pdf(const Point &p, const Vector &wi) const {
00076 Point Pcenter = ObjectToWorld(Point(0,0,0));
00077
00078 if (DistanceSquared(p, Pcenter) - radius*radius < 1e-4f)
00079 return Shape::Pdf(p, wi);
00080
00081 float cosThetaMax = sqrtf(max(0.f, 1.f - radius*radius /
00082 DistanceSquared(p, Pcenter)));
00083 return UniformConePdf(cosThetaMax);
00084 }
00085
00086 static Shape* CreateShape(const Transform &o2w, bool reverseOrientation, const ParamSet ¶ms);
00087 private:
00088
00089 float radius;
00090 float phiMax;
00091 float zmin, zmax;
00092 float thetaMin, thetaMax;
00093 };
00094
00095 }