00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "shape.h"
00024 #include "mc.h"
00025
00026 namespace lux
00027 {
00028
00029
00030 class QuadMesh : public Shape {
00031 public:
00032 QuadMesh(const Transform &o2w, bool ro, int nq, int nv,
00033 const int *vi, const Point *P)
00034 : Shape(o2w, ro), nquads(nq), nverts(nv) {
00035
00036 idx = new int[3 * nquads];
00037 memcpy(idx, vi, 4 * nquads * sizeof(int));
00038
00039 p = new Point[nverts];
00040
00041 for (int i = 0; i < nverts; ++i)
00042 p[i] = ObjectToWorld(P[i]);
00043
00044 uvs = NULL;
00045 }
00046
00047 virtual ~QuadMesh() {
00048 delete[] idx;
00049 delete[] p;
00050 }
00051
00052 virtual BBox ObjectBound() const;
00053
00054 int nquads, nverts;
00055 int *idx;
00056 Point *p;
00057 float *uvs;
00058 private:
00059
00060 };
00061
00062
00063
00064 class Quadrilateral : public Shape {
00065 public:
00066
00067 Quadrilateral(const Transform &o2w, bool ro, QuadMesh *m, int *indices);
00068 virtual ~Quadrilateral();
00069 virtual BBox ObjectBound() const;
00070 virtual BBox WorldBound() const;
00071 virtual bool Intersect(const Ray &ray, float *tHit,
00072 DifferentialGeometry *dg) const;
00073 virtual bool IntersectP(const Ray &ray) const;
00074 void GetUVs(float uv[4][2]) const {
00075 if (mesh->uvs) {
00076 uv[0][0] = mesh->uvs[2*idx[0]];
00077 uv[0][1] = mesh->uvs[2*idx[0]+1];
00078 uv[1][0] = mesh->uvs[2*idx[1]];
00079 uv[1][1] = mesh->uvs[2*idx[1]+1];
00080 uv[2][0] = mesh->uvs[2*idx[2]];
00081 uv[2][1] = mesh->uvs[2*idx[2]+1];
00082 uv[3][0] = mesh->uvs[2*idx[3]];
00083 uv[3][1] = mesh->uvs[2*idx[3]+1];
00084 } else {
00085
00086
00087
00088
00089
00090
00091
00092
00093 uv[0][0] = 0.f;
00094 uv[0][1] = 0.f;
00095 uv[1][0] = 1.f;
00096 uv[1][1] = 0.f;
00097 uv[2][0] = 1.f;
00098 uv[2][1] = 1.f;
00099 uv[3][0] = 0.f;
00100 uv[3][1] = 1.f;
00101 }
00102 }
00103 virtual float Area() const;
00104 virtual Point Sample(float u1, float u2, float u3, Normal *Ns) const {
00105 Point p;
00106
00107 const Point &p0 = mesh->p[idx[0]];
00108 const Point &p1 = mesh->p[idx[1]];
00109 const Point &p2 = mesh->p[idx[2]];
00110 const Point &p3 = mesh->p[idx[3]];
00111
00112 p = (1.f-u1)*(1.f-u2)*p0 + u1*(1.f-u2)*p1
00113 +u1*u2*p2 + (1.f-u1)*u2*p3;
00114
00115 Vector e0 = p1 - p0;
00116 Vector e1 = p2 - p0;
00117
00118 *Ns = Normalize(Normal(Cross(e0, e1)));
00119 if (reverseOrientation) *Ns *= -1.f;
00120 return p;
00121 }
00122
00123 private:
00124
00125 int *idx;
00126 QuadMesh *mesh;
00127 };
00128
00129 }