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 "texture.h"
00026 #include "error.h"
00027 #include <set>
00028 #include <map>
00029 using std::set;
00030 using std::map;
00031
00032 #define NEXT(i) (((i)+1)%3)
00033 #define PREV(i) (((i)+2)%3)
00034
00035 namespace lux
00036 {
00037
00038
00039 struct SDFace;
00040 struct SDFace;
00041 struct SDVertex {
00042
00043 SDVertex(Point pt = Point(0,0,0), float uu = 0.0f, float vv = 0.0f)
00044 : P(pt), u(uu), v(vv), startFace(NULL), child(NULL),
00045 regular(false), boundary(false) {
00046 }
00047
00048
00049 int valence();
00050 void oneRing(Point *P);
00051 void oneRing(SDVertex **V);
00052
00053 Point P;
00054 float u, v;
00055 SDFace *startFace;
00056 SDVertex *child;
00057 bool regular, boundary, hasUV;
00058 };
00059
00060 struct SDFace {
00061
00062 SDFace() {
00063 int i;
00064 for (i = 0; i < 3; ++i) {
00065 v[i] = NULL;
00066 f[i] = NULL;
00067 }
00068 for (i = 0; i < 4; ++i)
00069 children[i] = NULL;
00070 }
00071
00072 int vnum(SDVertex *vert) const {
00073 for (int i = 0; i < 3; ++i)
00074 if (v[i] == vert) return i;
00075 luxError(LUX_BUG,LUX_SEVERE,"Basic logic error in SDFace::vnum()");
00076 return -1;
00077 }
00078 SDFace *nextFace(SDVertex *vert) {
00079 return f[vnum(vert)];
00080 }
00081 SDFace *prevFace(SDVertex *vert) {
00082 return f[PREV(vnum(vert))];
00083 }
00084 SDVertex *nextVert(SDVertex *vert) {
00085 return v[NEXT(vnum(vert))];
00086 }
00087 SDVertex *prevVert(SDVertex *vert) {
00088 return v[PREV(vnum(vert))];
00089 }
00090 SDVertex *otherVert(SDVertex *v0, SDVertex *v1) {
00091 for (int i = 0; i < 3; ++i)
00092 if (v[i] != v0 && v[i] != v1)
00093 return v[i];
00094 luxError(LUX_BUG,LUX_SEVERE,"Basic logic error in SDVertex::otherVert()");
00095 return NULL;
00096 }
00097 SDVertex *v[3];
00098 SDFace *f[3];
00099 SDFace *children[4];
00100 };
00101
00102 struct SDEdge {
00103
00104 SDEdge(SDVertex *v0 = NULL, SDVertex *v1 = NULL) {
00105 v[0] = min(v0, v1);
00106 v[1] = max(v0, v1);
00107 f[0] = f[1] = NULL;
00108 f0edgeNum = -1;
00109 }
00110
00111 bool operator<(const SDEdge &e2) const {
00112 if (v[0] == e2.v[0]) return v[1] < e2.v[1];
00113 return v[0] < e2.v[0];
00114 }
00115 SDVertex *v[2];
00116 SDFace *f[2];
00117 int f0edgeNum;
00118 };
00119
00120
00121 class LoopSubdiv : public Shape {
00122 public:
00123
00124 LoopSubdiv(const Transform &o2w, bool ro,
00125 int nt, int nv, const int *vi,
00126 const Point *P, const float *uv, int nlevels,
00127 const boost::shared_ptr<Texture<float> > dismap,
00128 float dmscale, float dmoffset,
00129 bool dmnormalsmooth, bool dmsharpboundary);
00130 virtual ~LoopSubdiv();
00131 virtual bool CanIntersect() const;
00132 virtual void Refine(vector<boost::shared_ptr<Shape> > &refined) const;
00133 virtual BBox ObjectBound() const;
00134 virtual BBox WorldBound() const;
00135
00136 static Shape *CreateShape(const Transform &o2w, bool reverseOrientation,
00137 const ParamSet ¶ms);
00138
00139 class SubdivResult {
00140 public:
00141 SubdivResult(int aNtris, int aNverts, const int* aIndices,
00142 const Point *aP, const Normal *aN, const float *aUv)
00143 : ntris(aNtris), nverts(aNverts), indices(aIndices),
00144 P(aP), N(aN), uv(aUv)
00145 {
00146 }
00147 ~SubdivResult() {
00148 delete[] indices;
00149 delete[] P;
00150 if( N )
00151 delete[] N;
00152 if( uv )
00153 delete[] uv;
00154 }
00155
00156 const int ntris;
00157 const int nverts;
00158
00159 const int * const indices;
00160 const Point * const P;
00161 const Normal * const N;
00162 const float * const uv;
00163 };
00164 boost::shared_ptr<SubdivResult> Refine() const;
00165
00166 private:
00167
00168 float beta(int valence) const {
00169 if (valence == 3) return 3.f/16.f;
00170 else return 3.f / (8.f * valence);
00171 }
00172 void weightOneRing(SDVertex *destVert, SDVertex *vert, float beta) const ;
00173 void weightBoundary(SDVertex *destVert, SDVertex *vert, float beta) const;
00174 float gamma(int valence) const {
00175 return 1.f / (valence + 3.f / (8.f * beta(valence)));
00176 }
00177 static void GenerateNormals(const vector<SDVertex *> verts, Normal *Ns);
00178
00179 void ApplyDisplacementMap(
00180 const vector<SDVertex *> verts,
00181 const Normal *norms,
00182 const float *uvs) const;
00183
00184
00185 int nLevels;
00186 vector<SDVertex *> vertices;
00187 vector<SDFace *> faces;
00188
00189
00190 boost::shared_ptr<Texture<float> > displacementMap;
00191 float displacementMapScale;
00192 float displacementMapOffset;
00193
00194 bool hasUV, displacementMapNormalSmooth, displacementMapSharpBoundary;
00195
00196
00197 mutable boost::shared_ptr<Shape> refinedShape;
00198 };
00199
00200
00201 inline int SDVertex::valence() {
00202 SDFace *f = startFace;
00203 if (!boundary) {
00204
00205 int nf = 1;
00206 while ((f = f->nextFace(this)) != startFace)
00207 ++nf;
00208 return nf;
00209 }
00210 else {
00211
00212 int nf = 1;
00213 while ((f = f->nextFace(this)) != NULL)
00214 ++nf;
00215 f = startFace;
00216 while ((f = f->prevFace(this)) != NULL)
00217 ++nf;
00218 return nf+1;
00219 }
00220 }
00221
00222 }
00223