Página principal | Jerarquía de la clase | Lista alfabética | Lista de componentes | Lista de archivos | Miembros de las clases | Archivos de los miembros | Páginas relacionadas

texto_3d.C

Ir a la documentación de este archivo.
00001 //===========================================================================
00002 //= texto_3d.cc                                          Septiembre de 1998 =
00003 //=-------------------------------------------------------------------------=
00004 //= Clase de representacion de texto 3D (basado en GLTT y FTfont)           =
00005 //=-------------------------------------------------------------------------=
00006 //= ADVERTENCIA: ESTE SOFTWARE NO ESTA CONCEBIDO NI DISENNADO PARA EL USO   =
00007 //= EN EQUIPO DE CONTROL EN LINEA EN ENTORNOS PELIGROSOS QUE REQUIERAN UN   =
00008 //= DESEMPENNO LIBRE DE FALLAS, COMO LA OPERACION DE PLANTAS NUCLEARES,     = 
00009 //= SISTEMAS DE NAVEGACION O COMUNICACION EN AVIONES, TRAFICO AEREO,        =
00010 //= EQUIPO MEDICO DEL CUAL DEPENDAN VIDAS HUMANAS O SISTEMAS DE ARMAMENTO,  =
00011 //= EN LOS CUALES UNA FALLA EN EL SOFTWARE PUEDA IMPLICAR DIRECTAMENTE LA   =
00012 //= MUERTE, DANNOS PERSONALES O DANNOS FISICOS Y/O AMBIENTALES GRAVES       =
00013 //= ("ACTIVIDADES DE ALGO RIESGO").                                         =
00014 //=-------------------------------------------------------------------------=
00015 //= Autor original: Oscar J. Chavarro G.  A.K.A. JEDILINK. Copyright (c),   =
00016 //= 1997 - 2003, oscarchavarro@hotmail.com                                  =
00017 //= AQUYNZA es software libre, y se rige bajo los terminos de la licencia   =
00018 //= LGPL de GNU (http://www.gnu.org). Para mayor informacion respecto a la  =
00019 //= licencia de uso, consulte el archivo ./doc/LICENCIA en la distribucion. =
00020 //===========================================================================
00021 
00022 #include "toolkits/geom/geometria.h"
00023 
00024 #ifdef VEL_ROSITA
00025     #include "toolkits/geom/texto_3d.h"
00026 #endif
00027 
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 
00032 //===========================================================================
00033 //= Constantes y macros                                                     =
00034 //===========================================================================
00035 
00036 // OJO: No sera bueno escribir otra macro con las cosas comunes de estas dos?
00037 
00038 #define PINTE_LA_VAINA_CC() \
00039         VECTOR base(-size.x/2, 0, size.z/2); \
00040         for( i = 0; i < text_length; i++ ) { \
00041             FTGlyphVectorizer &v = vec[i]; \
00042             int c; \
00043             for( c = 0; c < v.getNContours(); c++ ) { \
00044                 FTGlyphVectorizer::Contour* contour= v.getContour(c); \
00045                 if( contour == 0 ) continue; \
00046                 for( int j = 0; j < contour->nPoints; j++ ) { \
00047                     FTGlyphVectorizer::POINT *point= contour->points + j; \
00048                     double cx = -point->y; \
00049                     double cy = (base.x + point->x); \
00050                     double phi= sin(cy*RTF) * RTS * M_PI/2; \
00051                     double rcx= cx * cos(phi); \
00052                     double rcz= cx * sin(phi); \
00053                     double* p = (double*) point->data; \
00054                     double* n = p + 3; \
00055                     p[0]= rcx; \
00056                     p[1]= cy; \
00057                     p[2]= rcz + base.z; \
00058                     n[0]= -sin(phi); \
00059                     n[1]= 0; \
00060                     n[2]= cos(phi); \
00061                 } \
00062             } \
00063             trace_caras(i); \
00064             trace_bordes(v); \
00065             base.x += v.getAdvance()/100; \
00066         } 
00067 
00068 #define PINTE_LA_VAINA_SC() \
00069         VECTOR base(-size.x/2, 0, size.z/2); \
00070         for( i = 0; i < text_length; i++ ) { \
00071             FTGlyphVectorizer &v = vec[i]; \
00072             int c; \
00073             for( c = 0; c < v.getNContours(); c++ ) { \
00074                 FTGlyphVectorizer::Contour* contour= v.getContour(c); \
00075                 if( contour == 0 ) continue; \
00076                 for( int j = 0; j < contour->nPoints; j++ ) { \
00077                     FTGlyphVectorizer::POINT *point= contour->points + j; \
00078                     double cx = -point->y; \
00079                     double cy = (base.x + point->x); \
00080                     double phi= sin(cy*RTF) * RTS * M_PI/2; \
00081                     double rcx= cx * cos(phi); \
00082                     double rcz= cx * sin(phi); \
00083                     double* p = (double*) point->data; \
00084                     double* n = p + 3; \
00085                     p[0]= rcx; \
00086                     p[1]= cy; \
00087                     p[2]= rcz + base.z; \
00088                     n[0]= -sin(phi); \
00089                     n[1]= 0; \
00090                     n[2]= cos(phi); \
00091                 } \
00092             } \
00093             trace_bordes(v); \
00094             base.x += v.getAdvance()/100; \
00095         } 
00096 
00097 //===========================================================================
00098 //= Clase TEXTO_3D                                                          =
00099 //===========================================================================
00100 
00101 TEXTO_3D::TEXTO_3D(char *face_name, char *text, double fs)
00102 {
00103     RTS = 0.0;
00104     RTF = 0.0;
00105     font_size = fs;
00106     size.z = 0.3 * fs;
00107 #ifdef GLTT_ENABLED
00108     face = chequear_fuente(face_name);
00109 
00110     if ( !face ) {
00111         fprintf(stderr, 
00112             "<TEXTO_3D> ERROR FATAL: No pude abrir mi fuente de texto!\n");
00113         fflush(stderr);
00114         exit(0);
00115     }
00116 
00117     texto = new char[strlen(text)+1];
00118     strcpy(texto, text);
00119 
00120     archivo_ttf = new char[strlen(face_name)+1];
00121     strcpy(archivo_ttf, face_name);
00122 #endif
00123     estoy_listo = FALSE;
00124 }
00125 
00126 TEXTO_3D::~TEXTO_3D()
00127 {
00128     elim();
00129 }
00130 
00131 void
00132 TEXTO_3D::minmax(VECTOR *min, VECTOR *max)
00133 {
00134     min->x = -size.x/2;
00135     min->y = -size.y/2;
00136     min->z = -size.z/2;
00137     max->x = size.x/2;
00138     max->y = size.y/2;
00139     max->z = size.z/2;
00140 }
00141 
00142 #ifdef GLTT_ENABLED
00143 void
00144 TEXTO_3D::init(FTFace *f, char *text)
00151 {
00152     int i, j, c;
00153     double min_y = 1e20;
00154     double max_y =-1e20;
00155     double size_x = 0;
00156 
00157     face = f;
00158 
00159     //- 1. Create triangle lists for all characters -
00160     text_length = strlen(text);
00161 
00162     Tfont = new GLTTFont(face);
00163     if( !Tfont || !Tfont->create((int)(font_size * 220)) ) return;
00164     vec = new FTGlyphVectorizer[text_length];
00165     tri = new CARACTER_GLTT* [text_length];
00166 
00167     for( i = 0; i < text_length; i++ ) {
00168         tri[i] = new CARACTER_GLTT(vec + i);
00169     }
00170     //- -
00171 
00172     //- 2. Pre-compute min_y, max_y and size_x values for the string -
00173     for( i = 0; i < text_length; i++ ) {
00174         int ch = (unsigned char)text[i];
00175 
00176         FTGlyph *g = Tfont->getFont()->getGlyph(ch);
00177         if( !g ) continue;
00178 
00179         // Note that here is where the graphic representation 'vec[i]' is made
00180         FTGlyphVectorizer &v = vec[i];
00181         v.setPrecision(14);
00182         if( !v.init(g) ) continue;
00183 
00184         size_x += v.getAdvance();
00185 
00186         if( !v.vectorize() ) continue;
00187 
00188         for( c = 0; c < v.getNContours(); c++ ) {
00189             FTGlyphVectorizer::Contour* contour= v.getContour(c);
00190             if( contour == 0 ) continue;
00191             for( j = 0; j < contour->nPoints; ++j ) {
00192                 FTGlyphVectorizer::POINT* point= contour->points + j;
00193 
00194                 if( point->y < min_y ) min_y = point->y;
00195                 if( point->y > max_y ) max_y = point->y;
00196                 point->data= (void*) new double [ 6 ];
00197             }
00198         }
00199 
00200         CARACTER_GLTT* t = tri[i];
00201 
00202         if( !t->init(g) ) continue;
00203 
00204         t->count_them = GLTT_TRUE;
00205         t->nTriangles = 0;
00206         t->triangulate();
00207 
00208         t->count_them = GLTT_FALSE;
00209         t->alloc();
00210         t->nTriangles = 0;
00211         t->triangulate();
00212     }
00213     if( size_x == 0 ) exit(-1);
00214     //- -
00215 
00216     //- 3. Modify the height in y for all points -
00217     //double y_delta = (min_y+max_y)/2.0 + min_y + 50;
00218     min_y /= 100;    max_y /= 100;
00219     size_x /= 100;   size.x = size_x;
00220     size.y = max_y - min_y;
00221     for( i = 0; i < text_length; i++ ) {
00222         FTGlyphVectorizer &v = vec[i];
00223 
00224         for( c = 0; c < v.getNContours(); c++ ) {
00225             FTGlyphVectorizer::Contour *contour= v.getContour(c);
00226             if ( contour == 0 ) continue;
00227             for( j = 0; j < contour->nPoints; j++ ) {
00228                 FTGlyphVectorizer::POINT* point= contour->points + j;
00229                 //point->y -= y_delta;
00230                 point->x /= 100;
00231                 point->y /= 100;
00232                 point->y -= size.y/2;
00233             }
00234         }
00235     }
00236     //- - 
00237 }
00238 #endif
00239 
00240 void
00241 TEXTO_3D::elim(void)
00242 {
00243     //- Delete temporal triangles arrays -
00244 #ifdef GLTT_ENABLED
00245     int i;
00246 
00247     if ( texto ) {
00248         delete texto;
00249         texto = NULL;
00250     }
00251     if ( archivo_ttf ) {
00252         delete archivo_ttf;
00253         archivo_ttf = NULL;
00254     }
00255 
00256     // OJO: Esto porque?
00257     if ( !estoy_listo ) return;
00258 
00259     printf("Elimino texto...\n"); fflush(stdout);
00260     for( i = 0; i < text_length; i++ ) {
00261         delete tri[i];
00262 
00263         FTGlyphVectorizer &v = vec[i];
00264         for( int c = 0; c < v.getNContours(); c++ ) {
00265             FTGlyphVectorizer::Contour *contour = v.getContour(c);
00266             if( contour == 0 ) continue;
00267             for( int j = 0; j < contour->nPoints; j++ ) {
00268                 FTGlyphVectorizer::POINT *point = contour->points + j;
00269                 delete (FTGlyphVectorizer::POINT *)(point->data);
00270                 point->data = 0;
00271             }
00272         }
00273     }
00274     delete tri;
00275     delete [] vec;
00276     delete Tfont;
00277 
00278     //- -
00279 
00280     delete texto;
00281 #endif
00282 }
00283 
00284 void
00285 TEXTO_3D::anexar_textura(IMAGEN * /*img*/) 
00286 {
00287     static BOOLEAN ya = FALSE;
00288 
00289     if ( !ya ) {
00290         fprintf(stderr, 
00291             "<TEXTO_3D> ERROR: La operacion \"anexar_textura\" no "
00292             "ha sido implementada aun.\n");
00293         fflush(stderr);
00294         ya = TRUE;
00295     }
00296 }
00297 
00298 int
00299 TEXTO_3D::clasificar_punto(VECTOR /*p*/)
00300 {
00301     static BOOLEAN ya = FALSE;
00302 
00303     if ( !ya ) {
00304         fprintf(stderr, 
00305             "<TEXTO_3D> ERROR: La operacion \"clasificar_punto\" no "
00306             "ha sido implementada aun.\n");
00307         fflush(stderr);
00308         ya = TRUE;
00309     }
00310     return 0;
00311 }
00312 
00313 GEOMETRIA *
00314 TEXTO_3D::crear_copia(void)
00315 {
00316     static BOOLEAN ya = FALSE;
00317 
00318     if ( !ya ) {
00319         fprintf(stderr, 
00320             "<TEXTO_3D> ERROR: La operacion \"crear_copia\" no "
00321             "ha sido implementada aun.\n");
00322         fflush(stderr);
00323         ya = TRUE;
00324     }
00325     return 0;
00326 }
00327 
00328 #ifdef GLTT_ENABLED
00329 #ifdef GL_ENABLED
00330 void
00331 TEXTO_3D::trace_caras(int i)
00335 {
00336     TRIANGULO_GLTT* triangles= tri[i]->triangles;
00337     int nTriangles= tri[i]->nTriangles;
00338 
00339     //- Traza caras -------------------------------------------------------
00340     glBegin(GL_TRIANGLES);
00341     for( int j = 0; j < nTriangles; j++ ) {
00342         TRIANGULO_GLTT& t = triangles[j];
00343 
00344         double *p1 = ((double*) t.p1->data);
00345         double *p2 = ((double*) t.p2->data);
00346         double *p3 = ((double*) t.p3->data);
00347         double *n1 = p1 + 3;
00348         double *n2 = p2 + 3;
00349         double *n3 = p3 + 3;
00350 
00351         glNormal3dv( n1 );  // Cara del frente
00352         glVertex3dv( p1 );
00353         glNormal3dv( n2 );
00354         glVertex3dv( p2 );
00355         glNormal3dv( n3 );
00356         glVertex3dv( p3 );
00357 
00358         glNormal3d( -n3[0], 0, -n3[2] );   // Cara de atras
00359         glVertex3d( p3[0]-n3[0]*size.z,
00360                     p3[1],
00361                     p3[2]-n3[2]*size.z );
00362         glNormal3d( -n2[0], 0, -n2[2] );
00363         glVertex3d( p2[0]-n2[0]*size.z,
00364                     p2[1],
00365                     p2[2]-n2[2]*size.z );
00366         glNormal3d( -n1[0], 0, -n1[2] );
00367         glVertex3d( p1[0]-n1[0]*size.z,
00368                     p1[1],
00369                     p1[2]-n1[2]*size.z );
00370     }
00371     glEnd();
00372 }
00373 
00374 void
00375 TEXTO_3D::trace_bordes(FTGlyphVectorizer &v)
00379 {
00380     int c;
00381 
00382     //- Traza bordes ------------------------------------------------------
00383     for( c = 0; c < v.getNContours(); ++c ) {
00384         FTGlyphVectorizer::Contour* contour= v.getContour(c);
00385         if( contour == 0 ) continue;
00386         glBegin(GL_QUAD_STRIP);
00387         for( int j= 0; j <= contour->nPoints; ++j ) {
00388             int j1= (j < contour->nPoints) ? j : 0;
00389             int j0= (j1==0) ? (contour->nPoints-1) : (j1-1);
00390 
00391             FTGlyphVectorizer::POINT* point0= contour->points + j0;
00392             FTGlyphVectorizer::POINT* point1= contour->points + j1;
00393             double* p0= (double*) point0->data;
00394             double* p1= (double*) point1->data;
00395             double* e= p0 + 3;
00396             double vx= p1[0] - p0[0];
00397             double vy= p1[1] - p0[1];
00398             double vz= p1[2] - p0[2];
00399             double nx=                     - vy * e[2];
00400             double ny= e[2] * vx - vz * e[0];
00401             double nz= e[0] * vy ;
00402 
00403             glNormal3d(nx,ny,nz);
00404             glVertex3d( p0[0]-e[0]*size.z,
00405                                     p0[1],
00406                                     p0[2]-e[2]*size.z );
00407             glNormal3d(nx,ny,nz);
00408             glVertex3d( p0[0], p0[1], p0[2] );
00409         }
00410         glEnd();
00411     }
00412 }
00413 #endif // GL_ENABLED
00414 #endif // GLTT_ENABLED
00415 
00416 #ifdef GL_ENABLED
00417 void
00418 TEXTO_3D::pintar_gl(CALIDAD_VISUAL *Calidad, MATERIAL* Material,
00419                     CAMARA * /*Camara*/)
00422 {
00423 #ifndef GLTT_ENABLED
00424     fprintf(stderr, "<TEXTO_3D> - ERROR: No estoy activo!\n");
00425     fflush(stderr);
00426 #endif
00427 #ifdef GLTT_ENABLED
00428     //- Chequeo de precondicion -
00429     if ( !estoy_listo ) {
00430         init(face, texto);
00431         estoy_listo = TRUE;
00432     }
00433 
00434     //- Volumen envolvente - 
00435     if ( Calidad->con_cajas ) {
00436         glDisable(GL_LIGHTING);
00437 
00438         VECTOR p1(-size.x/2, -size.y/2, -size.z/2);
00439         VECTOR p2(size.x/2, size.y/2, size.z/2);
00440 
00441         glColor3f(0, 1, 0);
00442         pintar_paralelepipedo(p1, p2);
00443     }
00444 
00445     //- Pinte las letras 3D -
00446     int i;
00447 
00448     glPushMatrix();
00449     glRotatef(-90, 0, 0, 1);
00450     glEnable(GL_NORMALIZE);
00451 
00452     //- Pintado de bordes --------------------------------------------------
00453     COLOR cb(1, 0, 0);
00454 
00455     if ( Calidad->con_bordes ) {
00456         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00457         if ( !Calidad->con_caras ) glDisable(GL_CULL_FACE);
00458         Calidad->activar_bordes_gl(cb, Material);
00459         PINTE_LA_VAINA_SC();
00460     }
00461 
00462     //- Pintado de caras ---------------------------------------------------
00463     COLOR c(1, 1, 1);
00464 
00465     if ( Calidad->con_caras ) {
00466         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00467         Material->activar_gl();
00468         Calidad->activar_caras_gl(c, Material);
00469         ACTIVAR_POLYGON_OFFSET();
00470         if ( Calidad->con_caustics ) {
00471             Calidad->activar_textura_gl();
00472         }
00473         PINTE_LA_VAINA_CC();
00474         DESACTIVAR_POLYGON_OFFSET();
00475     }
00476 
00477     glDisable(GL_NORMALIZE);
00478     glPopMatrix();
00479   #endif // GLTT_ENABLED
00480 }
00481 #endif // GL_ENABLED
00482 
00483 void
00484 TEXTO_3D::pintar_aqz(FILE *fd)
00485 {
00486     fprintf(fd, "    // Pilas: No hay pintar_aqz... \n");
00487     fprintf(fd, "    geometria ESFERA 1 \"\"\n");
00488 }
00489 
00490 void
00491 TEXTO_3D::pintar_povray(FILE *fd)
00492 {
00493     fprintf(fd,
00494         "text {\n"
00495         "    ttf \"%s\" \"%s\" %f, 0\n"
00496         "    scale <%f, %f, %f>\n"
00497         "    translate <%f, %f, %f>\n",
00498         archivo_ttf, texto, size.z*2,
00499         // OJO: Esto de `3.3` toca revisarlo!
00500         font_size*3.3, font_size*3.3, font_size*3.3,
00501         -size.x/2, -size.y/2, -size.z/2
00502     );
00503 }
00504 
00505 //===========================================================================
00506 //= EOF                                                                     =
00507 //===========================================================================
00508 

Este archivo HTML ha sido generado automáticamente a partir del código fuente AQUYNZA. NO LO EDITE. Para mayor información contacte al autor.