Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

normals_texture.C

Go to the documentation of this file.
00001 /**********************************************************************
00002  * normals_texture.C
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  * VertNormalsTexture:
00022  *
00023  *      Draws the distinct normals at each vertex.
00024  *      (A vertex with adjacent crease edges has multiple normals.)
00025  **********************************************************************/
00026 // helper 
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    // set attributes for this mode
00046    glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
00047    glDisable(GL_LIGHTING);              // GL_ENABLE_BIT
00048    GL_COL(COLOR::red, alpha());        // GL_CURRENT_BIT
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    // length to use for showing normals:
00070    double scale = ((BMESH*)&*mesh)->get_bb().dim().length() / 50;
00071 
00072    // Get the Patch vertices:
00073    //   (expensive, but OK in a display list):
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    // end the display list here
00087    if (_dl.dl(v)) {
00088       _dl.close_dl(v);
00089 
00090       // the display list is built; now execute it
00091       BasicTexture::draw(v);
00092    }
00093 
00094    // restore gl state:
00095    glPopAttrib();
00096 
00097    return _patch->num_faces();
00098 }
00099 
00100 
00101 
00102 /*****************************************************
00103 draws uv gradient vectors as blue and green lines 
00104 
00105  ******************************************************/
00106 
00107 
00108 //this is a test of the automatic spherical texture generator
00109 //which is being used by *_EX shaders
00110 class UV_attrib  :  public VertAttrib<UVpt,UVvec>
00111 {
00112 public:
00113    
00114    UV_attrib()
00115    {
00116        auto_UV = new GLSphirTexCoordGen; //automatic generator
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    // set attributes for this mode
00154    glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
00155    glDisable(GL_LIGHTING);              // GL_ENABLE_BIT
00156    
00157    //change color so it doesn't get confused with normals
00158    GL_COL(COLOR::blue, alpha());        // GL_CURRENT_BIT
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    // length to use for showing normals:
00185    double scale = ((BMESH*)&*mesh)->get_bb().dim().length() / 50;
00186 
00187 
00188 
00189 
00190    // Get the Patch vertices:
00191    //   (expensive, but OK in a display list):
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      // Wtransf rotate( base_2, base_3, Wvec(0,0,0));
00220   
00221 
00222       for(int i=0; i<faces.num(); i++)
00223       {
00224       
00225 
00226          //getting the previously computed face gradients
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          //rotate to tangent plane
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       //just simple average for now
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    // end the display list here
00265    if (_dl.dl(v)) {
00266       _dl.close_dl(v);
00267 
00268       // the display list is built; now execute it
00269       BasicTexture::draw(v);
00270    }
00271 
00272    // restore gl state:
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; //uses the face pointer as a key
00306       }
00307 
00308 }
00309 
00310 
00311 /**********************************************************************
00312  * NormalsTexture:
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 /* end of file normals_texture.C */

Generated on Mon Sep 18 11:39:32 2006 for jot by  doxygen 1.4.4