00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00034
00035
00036
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
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
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
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
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
00217
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
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
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
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 * )
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 )
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
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 );
00352 glVertex3dv( p1 );
00353 glNormal3dv( n2 );
00354 glVertex3dv( p2 );
00355 glNormal3dv( n3 );
00356 glVertex3dv( p3 );
00357
00358 glNormal3d( -n3[0], 0, -n3[2] );
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
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 * )
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
00429 if ( !estoy_listo ) {
00430 init(face, texto);
00431 estoy_listo = TRUE;
00432 }
00433
00434
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
00446 int i;
00447
00448 glPushMatrix();
00449 glRotatef(-90, 0, 0, 1);
00450 glEnable(GL_NORMALIZE);
00451
00452
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
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
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
00507
00508