00001
00002
00003
00004 #include "normals_texture.H"
00005 #include "std/config.H"
00006 #include "gtex/gl_sphir_tex_coord_gen.H"
00007 #include "gtex/gl_extensions.H"
00008 #include "gtex/util.H"
00009 #include "mesh/uv_data.H"
00010 #include "mesh/vert_attrib.H"
00011
00012
00013
00014 using mlib::CWpt;
00015 using mlib::Wvec;
00016 using mlib::CWvec;
00017
00018 bool NormalsTexture::_uv_vectors = false;
00019
00020
00021
00022
00023
00024
00025
00026
00027 inline void
00028 draw_seg(CWpt& p, CWvec& v)
00029 {
00030 glVertex3dv(p.data());
00031 glVertex3dv((p + v).data());
00032 }
00033
00034 int
00035 VertNormalsTexture::draw(CVIEWptr& v)
00036 {
00037
00038
00039
00040 if (_ctrl)
00041 return _ctrl->draw(v);
00042
00043
00044
00045
00046 glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
00047 glDisable(GL_LIGHTING);
00048 GL_COL(COLOR::red, alpha());
00049
00050
00051 if (BasicTexture::draw(v)) {
00052 glPopAttrib();
00053 return _patch->num_faces();
00054 }
00055
00056 CBMESH* mesh = _patch->mesh();
00057 if (!mesh) {
00058 err_msg( "VertNormalsTexture::draw: mesh is nil");
00059 return 0;
00060 }
00061
00062
00063
00064 int dl = 0;
00065 if ((dl = _dl.get_dl(v, 1, _patch->stamp()))) {
00066 glNewList(dl, GL_COMPILE);
00067 }
00068
00069
00070 double scale = ((BMESH*)&*mesh)->get_bb().dim().length() / 50;
00071
00072
00073
00074 Bvert_list verts = _patch->cur_verts().filter(PrimaryVertFilter());
00075
00076 ARRAY<Wvec> norms;
00077 glBegin(GL_LINES);
00078 for (int i=0; i<verts.num(); i++) {
00079 CBvert* bv = verts[i];
00080 bv->get_normals(norms);
00081 for (int k=0; k<norms.num(); k++)
00082 draw_seg(bv->loc(), norms[k]*scale);
00083 }
00084 glEnd();
00085
00086
00087 if (_dl.dl(v)) {
00088 _dl.close_dl(v);
00089
00090
00091 BasicTexture::draw(v);
00092 }
00093
00094
00095 glPopAttrib();
00096
00097 return _patch->num_faces();
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 class UV_attrib : public VertAttrib<UVpt,UVvec>
00111 {
00112 public:
00113
00114 UV_attrib()
00115 {
00116 auto_UV = new GLSphirTexCoordGen;
00117 auto_UV->setup();
00118 }
00119
00120 virtual ~UV_attrib()
00121 {
00122 delete auto_UV;
00123 }
00124
00125 virtual UVpt get_attrib(CBvert* v, CBface* f)
00126 {
00127 assert(v&&f);
00128
00129 TexCoordGen* tg = f->patch()->tex_coord_gen();
00130 if (tg)
00131 return tg->uv_from_vert(v,f);
00132 else
00133 if (UVdata::lookup(f))
00134 return UVdata::get_uv(v,f);
00135 else
00136 return auto_UV->uv_from_vert(v,f);
00137 }
00138
00139 protected :
00140 TexCoordGen* auto_UV;
00141 };
00142
00143
00144 int
00145 VertUVTexture::draw(CVIEWptr& v)
00146 {
00147
00148 if (_ctrl)
00149 return _ctrl->draw(v);
00150
00151
00152
00153
00154 glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
00155 glDisable(GL_LIGHTING);
00156
00157
00158 GL_COL(COLOR::blue, alpha());
00159
00160
00161 if (BasicTexture::draw(v)) {
00162 glPopAttrib();
00163 return _patch->num_faces();
00164 }
00165
00166 CBMESH* mesh = _patch->mesh();
00167 if (!mesh) {
00168 err_msg( "VertNormalsTexture::draw: mesh is nil");
00169 return 0;
00170 }
00171
00172
00173
00174 int dl = 0;
00175 if ((dl = _dl.get_dl(v, 1, _patch->stamp()))) {
00176 glNewList(dl, GL_COMPILE);
00177 }
00178
00179 cerr << "Please wait while compiling UV gradients display list" << endl;
00180
00181 compute_UV_grads();
00182
00183
00184
00185 double scale = ((BMESH*)&*mesh)->get_bb().dim().length() / 50;
00186
00187
00188
00189
00190
00191
00192 Bvert_list verts = _patch->cur_verts().filter(PrimaryVertFilter());
00193
00194 ARRAY<Wvec> norms;
00195 UV_attrib attr;
00196
00197 glBegin(GL_LINES);
00198 for (int i=0; i<verts.num(); i++)
00199 {
00200 CBvert* bv = verts[i];
00201
00202 Bface_list faces = bv->get_faces();
00203
00204 Wvec acc_U(0,0,0);
00205 Wvec acc_V(0,0,0);
00206
00207 Wvec U_vec,V_vec;
00208
00209 UVvec derivative;
00210
00211 Wvec vertex_normal = bv->norm();
00212 Wvec base_2 = cross(vertex_normal,Wvec(1.0,0.0,0.0));
00213 Wvec base_3 = cross(vertex_normal,base_2);
00214
00215 vertex_normal = vertex_normal.normalized();
00216 base_2 = base_2.normalized();
00217 base_3 = base_3.normalized();
00218
00219
00220
00221
00222 for(int i=0; i<faces.num(); i++)
00223 {
00224
00225
00226
00227 U_vec = face_gradient_map[int(faces[i])].U_grad;
00228 V_vec = face_gradient_map[int(faces[i])].V_grad;
00229
00230
00231
00232
00233 double U_magnitude = U_vec.length();
00234 double V_magnitude = V_vec.length();
00235
00236 U_vec = Wvec((base_2 * (base_2 *U_vec)) + (base_3 * (base_3 * U_vec)));
00237 V_vec = Wvec((base_2 * (base_2 * V_vec)) + (base_3 * (base_3 * V_vec)));
00238
00239 U_vec = U_vec.normalized() * U_magnitude;
00240 V_vec = V_vec.normalized() * V_magnitude;
00241
00242 acc_U += U_vec;
00243 acc_V += V_vec;
00244
00245 }
00246
00247
00248 acc_U = (acc_U / double(faces.num()) );
00249 acc_V = (acc_V / double(faces.num()) );
00250
00251
00252
00253
00254 GL_COL(COLOR::blue, alpha());
00255 draw_seg(bv->loc(), acc_U * scale);
00256 GL_COL(COLOR::green, alpha());
00257 draw_seg(bv->loc(), acc_V * scale);
00258
00259
00260
00261 }
00262 glEnd();
00263
00264
00265 if (_dl.dl(v)) {
00266 _dl.close_dl(v);
00267
00268
00269 BasicTexture::draw(v);
00270 }
00271
00272
00273 glPopAttrib();
00274
00275 return _patch->num_faces();
00276 }
00277
00278
00279 void
00280 VertUVTexture::compute_UV_grads()
00281 {
00282 UV_attrib attr;
00283 Bface_list faces = patch()->faces();
00284
00285 UV_grads gradient;
00286 UVvec derivative;
00287
00288 for(int i=0; i<faces.num(); i++)
00289 {
00290 derivative = attr.dFdx(faces[i]);
00291
00292 gradient.U_grad[0] = derivative[0];
00293 gradient.V_grad[0] = derivative[1];
00294
00295 derivative = attr.dFdy(faces[i]);
00296
00297 gradient.U_grad[1] = derivative[0];
00298 gradient.V_grad[1] = derivative[1];
00299
00300 derivative = attr.dFdz(faces[i]);
00301
00302 gradient.U_grad[2] = derivative[0];
00303 gradient.V_grad[2] = derivative[1];
00304
00305 face_gradient_map[int(faces[i])]= gradient;
00306 }
00307
00308 }
00309
00310
00311
00312
00313
00314 int
00315 NormalsTexture::draw(CVIEWptr& v)
00316 {
00317 if (_ctrl)
00318 return _ctrl->draw(v);
00319
00320 _smooth->draw(v);
00321
00322 if (_uv_vectors)
00323 {
00324
00325 _uv_vecs->draw(v);
00326 }
00327 else
00328 _normals->draw(v);
00329
00330 return _patch->num_faces();
00331 }
00332
00333
00334
00335