├── KP-anim-modele ├── KP-control_gtk.prl ├── Makefile ├── README.txt ├── head_modified.blend ├── head_modified.blend1 ├── head_modified.blend2 ├── head_modified.mtl ├── head_modified.obj ├── head_modified_KP.obj ├── head_modified_KP_KF10.cpp ├── head_modified_highpoly.mtl ├── head_modified_highpoly.obj ├── head_modified_highpoly_KP.obj └── src ├── KP-anim-client.cpp ├── KP-anim-modele.cpp ├── Mesh-display-modele.cpp ├── glutil.h ├── texpng.cpp ├── texpng.h └── urotate.cpp /KP-anim-modele: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricfoucault/facial_animation/f83f3512d6bd16f6a879394e5a3534f62d3ac71e/KP-anim-modele -------------------------------------------------------------------------------- /KP-control_gtk.prl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | #*************************************************************************** 4 | # File: KP-control-gtk.prl 5 | # 6 | # Virtual Humans 7 | # Master in Computer Science 8 | # Christian Jacquemin, University Paris 11 9 | # 10 | # Copyright (C) 2008 University Paris 11 11 | # This file is provided without support, instruction, or implied 12 | # warranty of any kind. University Paris 11 makes no guarantee of its 13 | # fitness for a particular purpose and is not liable under any 14 | # circumstances for any damages or loss whatsoever arising from the use 15 | # or inability to use this file or items derived from it. 16 | #**************************************************************************** 17 | 18 | # http://www.gtk.org/tutorial1.2/ 19 | # http://gtk2-perl.sourceforge.net/doc/intro/ 20 | # http://gtk2-perl.sourceforge.net/doc/pod/ 21 | # http://gtk2-perl.sourceforge.net/doc/gtk2-perl-tut/ 22 | # http://pagesperso-orange.fr/gtk2-perl/Gtk2perl_tutoriel.html 23 | 24 | use strict ; 25 | 26 | use Gtk2 '-init' ; 27 | 28 | use constant TRUE => 1 ; 29 | use constant FALSE => 0 ; 30 | 31 | # This program generates an interface for the definition 32 | # of keyframes for a keypoint-based animation 33 | 34 | # the program takes as input a cpp file that contains 35 | # - 1 table of K strings associated with K keypoints 36 | # - 3 tables of K F-dimensional float arrays (F is the number of keyframes) 37 | # each table is associated with 1 coordinate 38 | # the format of the file is as follows for 4 keypoints and 10 frames 39 | 40 | # char tab_ID[4][16] = { "8.1" , "8.2" , "8.3" , "8.4" }; 41 | # float tab_KF_x[4][10] = { 42 | # { 0.01 , 0.02 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 } , 43 | # { 0.00 , 0.00 , 0.03 , 0.04 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 } , 44 | # { 0.00 , 0.00 , 0.00 , 0.00 , 0.05 , 0.06 , 0.00 , 0.00 , 0.00 , 0.00 } , 45 | # { 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.07 , 0.08 , 0.00 , 0.00 } 46 | # }; 47 | # float tab_KF_y[4][10] = { 48 | # { 0.09 , 0.08 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 } , 49 | # { 0.00 , 0.00 , 0.07 , 0.06 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 } , 50 | # { 0.00 , 0.00 , 0.00 , 0.00 , 0.05 , 0.04 , 0.00 , 0.00 , 0.00 , 0.00 } , 51 | # { 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.03 , 0.02 , 0.00 , 0.00 } 52 | # }; 53 | # float tab_KF_z[4][10] = { 54 | # { 0.04 , 0.05 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 } , 55 | # { 0.00 , 0.00 , 0.07 , 0.09 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 } , 56 | # { 0.00 , 0.00 , 0.00 , 0.00 , 0.01 , 0.03 , 0.00 , 0.00 , 0.00 , 0.00 } , 57 | # { 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.00 , 0.02 , 0.08 , 0.00 , 0.00 } 58 | # }; 59 | 60 | # the interface contains 2 menus to select a keypoint k and a frame number f 61 | # and 3 sliders to modify the x y z coordinates of the k-th keypoint 62 | # at frame f 63 | # each time a value is modified, a message is sent to the 64 | # animation application so that it can update the keyframe graphics. 65 | 66 | # a new data structure is automatically generated when quitting 67 | # the application. It never overlaps the existing data and 68 | # creates successive versions of the data. 69 | 70 | 71 | ############################################################### 72 | # SOCKET FOR UDP CONNECTION 73 | ############################################################### 74 | my $HOSTNAME = "127.0.0.1"; 75 | my $PORTNO = "1979"; 76 | use Socket; 77 | socket(SOCKET, PF_INET, SOCK_DGRAM, getprotobyname("udp")) 78 | or die "socket: $!"; 79 | my $ipaddr = inet_aton($HOSTNAME); 80 | my $portaddr = sockaddr_in($PORTNO, $ipaddr); 81 | 82 | 83 | ############################################################### 84 | # WORKING VARIABLES 85 | ############################################################### 86 | # list of key-point ID 87 | my @KP_ID_list; 88 | # current key-point ID 89 | my $Cur_KP_ID = ""; 90 | # number of keyframes 91 | my $Nb_Keyframes = 10; 92 | #current keyframe 93 | my $Cur_KF = 1; 94 | #keypoint positions 95 | my %KP_Pos_x; 96 | my %KP_Pos_y; 97 | my %KP_Pos_z; 98 | #message emission (postponed to avoid duplicates in case 99 | # of mutiple value assignments) 100 | my $message_output = TRUE; 101 | 102 | ############################################################### 103 | # LOADS EXISTING ANIMATION 104 | ############################################################### 105 | &load_KFs; 106 | 107 | ############################################################### 108 | ############################################################### 109 | # BUILDS THE INTERFACE AND ATTACHES CALLBACK FUNCTIONS 110 | ############################################################### 111 | ############################################################### 112 | # Window creation 113 | my $window = Gtk2::Window->new( "toplevel" ) ; 114 | $window->set_title( "Viseme editor" ) ; 115 | $window->set_default_size(300,300); 116 | $window->signal_connect( "destroy" , sub { Gtk2->main_quit ; } ) ; 117 | 118 | # A root vertical box that includes all the widgets 119 | my $box_root = Gtk2::VBox->new( FALSE, 0 ) ; 120 | $window->add( $box_root ) ; 121 | $box_root->show() ; 122 | 123 | ############################################################### 124 | # 3 SLIDERS: X, Y Z translation values 125 | ############################################################### 126 | # Adjustment creation: an adjustment defines the value and range of the slider 127 | # value, lower, upper, step_increment, page_increment, page_size 128 | # (page_size is only useful for scrollbar widgets) 129 | my $adj1 = Gtk2::Adjustment->new( 0.0 , -0.3 , 0.3 , 0.001 , 0.001 , 0.001 ) ; 130 | $adj1->signal_connect("value_changed",\&KP_transl_value,'x'); 131 | my $adj2 = Gtk2::Adjustment->new( 0.0 , -0.3 , 0.3 , 0.001 , 0.001 , 0.001 ) ; 132 | $adj2->signal_connect("value_changed",\&KP_transl_value,'y'); 133 | my $adj3 = Gtk2::Adjustment->new( 0.0 , -0.3 , 0.3 , 0.001 , 0.001 , 0.001 ) ; 134 | $adj3->signal_connect("value_changed",\&KP_transl_value,'z'); 135 | 136 | ############# 137 | # X translation of keypoint $Cur_KP_ID at keyframe $Cur_KF 138 | # A new horizontal box added to the vertical box and contains 2 widgets 139 | my $box_slider1 = Gtk2::HBox->new( FALSE, 10 ) ; 140 | $box_slider1->set_border_width( 10 ) ; 141 | $box_root->pack_start( $box_slider1, TRUE, TRUE, 0 ) ; 142 | $box_slider1->show() ; 143 | # a label 144 | my $label1 = Gtk2::Label->new( "x" ) ; 145 | $box_slider1->pack_start( $label1, FALSE, FALSE, 0 ) ; 146 | $label1->show() ; 147 | # An horizontal slider 148 | my $hor_scale1 = Gtk2::HScale->new( $adj1 ) ; 149 | $hor_scale1->set_digits( 3 ) ; 150 | $box_slider1->pack_start( $hor_scale1, TRUE, TRUE, 0 ) ; 151 | $hor_scale1->show() ; 152 | 153 | ############# 154 | # Y translation of keypoint $Cur_KP_ID at keyframe $Cur_KF 155 | # A new horizontal box added to the vertical box and contains 2 widgets 156 | my $box_slider2 = Gtk2::HBox->new( FALSE, 10 ) ; 157 | $box_slider2->set_border_width( 10 ) ; 158 | $box_root->pack_start( $box_slider2, TRUE, TRUE, 0 ) ; 159 | $box_slider2->show() ; 160 | # a label 161 | my $label2 = Gtk2::Label->new( "y" ) ; 162 | $box_slider2->pack_start( $label2, FALSE, FALSE, 0 ) ; 163 | $label2->show() ; 164 | # An horizontal slider 165 | my $hor_scale2 = Gtk2::HScale->new( $adj2 ) ; 166 | $hor_scale2->set_digits( 3 ) ; 167 | $box_slider2->pack_start( $hor_scale2, TRUE, TRUE, 0 ) ; 168 | $hor_scale2->show() ; 169 | 170 | ############# 171 | # Z translation of keypoint $Cur_KP_ID at keyframe $Cur_KF 172 | # A new horizontal box added to the vertical box and contains 2 widgets 173 | my $box_slider3 = Gtk2::HBox->new( FALSE, 10 ) ; 174 | $box_slider3->set_border_width( 10 ) ; 175 | $box_root->pack_start( $box_slider3, TRUE, TRUE, 0 ) ; 176 | $box_slider3->show() ; 177 | # a label 178 | my $label3 = Gtk2::Label->new( "z" ) ; 179 | $box_slider3->pack_start( $label3, FALSE, FALSE, 0 ) ; 180 | $label3->show() ; 181 | # An horizontal slider 182 | my $hor_scale3 = Gtk2::HScale->new( $adj3 ) ; 183 | $hor_scale3->set_digits( 3 ) ; 184 | $box_slider3->pack_start( $hor_scale3, TRUE, TRUE, 0 ) ; 185 | $hor_scale3->show() ; 186 | 187 | # A separator 188 | my $separator1 = Gtk2::HSeparator->new() ; 189 | $box_root->pack_start( $separator1, FALSE, TRUE, 0 ) ; 190 | $separator1->show() ; 191 | 192 | ###############################################################" 193 | # KP MENU + KF MENU + RESET BUTTON 194 | ###############################################################" 195 | 196 | # A new horizontal box added to the vertical box and contains a manu 197 | my $box_menu = Gtk2::HBox->new( FALSE, 10 ) ; 198 | $box_menu->set_border_width( 10 ) ; 199 | 200 | ############# 201 | # A keypoint menu 202 | my $opt = Gtk2::OptionMenu->new() ; 203 | my $menu = Gtk2::Menu->new() ; 204 | # There are as many menu items as keypoint IDs 205 | my $KP_ID = ""; 206 | my $item; 207 | foreach $KP_ID (@KP_ID_list) { 208 | if( !$Cur_KP_ID ) { 209 | $Cur_KP_ID = $KP_ID; 210 | } 211 | $item = make_menu_item( "Keypoint $KP_ID" , \&KP_ID_menu_select, $KP_ID ) ; 212 | $menu->append( $item ) ; 213 | } 214 | # Menu receives items and is placed in the horizontal box 215 | $opt->set_menu( $menu ) ; 216 | $box_menu->pack_start( $opt, TRUE, FALSE, 0 ) ; 217 | $opt->show() ; 218 | 219 | ############# 220 | # A keyframe menu 221 | my $optKF = Gtk2::OptionMenu->new() ; 222 | my $menuKF = Gtk2::Menu->new() ; 223 | # There are as many menu items as keyframe numbers 224 | my $itemKF; 225 | for( my $kf = 1 ; $kf <= $Nb_Keyframes ; $kf++ ) { 226 | $itemKF = make_menu_item( "Keyframe $kf" , \&KP_KF_menu_select, $kf ) ; 227 | $menuKF->append( $itemKF ) ; 228 | } 229 | # Menu receives items and is placed in the horizontal box 230 | $optKF->set_menu( $menuKF ) ; 231 | $box_menu->pack_start( $optKF, TRUE, FALSE, 0 ) ; 232 | $optKF->show() ; 233 | 234 | ############# 235 | # A reset button 236 | # resets the translation of keypoint $Cur_KP_ID at keyframe $Cur_KF 237 | # to ( 0 , 0 , 0 ) 238 | my $button_reset = Gtk2::Button->new_from_stock( "KP-reset" ) ; 239 | $button_reset->signal_connect( "clicked" , \&KP_reset ) ; 240 | $box_menu->pack_start( $button_reset, TRUE, FALSE, 0 ) ; 241 | $button_reset->can_default( TRUE ) ; 242 | $button_reset->show() ; 243 | 244 | $box_root->pack_start( $box_menu, FALSE, FALSE, 0 ) ; 245 | $box_menu->show() ; 246 | 247 | 248 | ###############################################################" 249 | # QUIT BUTTON 250 | ###############################################################" 251 | 252 | # A separator 253 | my $separator = Gtk2::HSeparator->new() ; 254 | $box_root->pack_start( $separator, FALSE, TRUE, 0 ) ; 255 | $separator->show() ; 256 | 257 | # Quit button 258 | my $button = Gtk2::Button->new_from_stock( "gtk-quit" ) ; 259 | $button->signal_connect( "clicked" , \&quit_and_save ) ; 260 | $box_root->pack_start( $button, FALSE, FALSE, 0 ) ; 261 | $button->can_default( TRUE ) ; 262 | $button->grab_default() ; 263 | $button->show() ; 264 | $window->show() ; 265 | 266 | KP_KF_menu_select( $itemKF , $Cur_KF ); 267 | 268 | ###############################################################" 269 | # MAIN LOOP 270 | ###############################################################" 271 | Gtk2->main ; 272 | 273 | ###############################################################" 274 | ###############################################################" 275 | # CALLBACK FUNCTIONS 276 | ###############################################################" 277 | ###############################################################" 278 | 279 | ### Value access for translation of keypoint $Cur_KP_ID at keyframe $Cur_KF 280 | sub get_value_KP_KF 281 | { 282 | my ( $ID , $kf , $coord ) = @_ ; 283 | my @table; 284 | if( $coord eq 'x' ) { 285 | @table = split( / / ,$KP_Pos_x{ $Cur_KP_ID } ); 286 | } 287 | elsif( $coord eq 'y' ) { 288 | @table = split( / / ,$KP_Pos_y{ $Cur_KP_ID } ); 289 | } 290 | elsif( $coord eq 'z' ) { 291 | @table = split( / / ,$KP_Pos_z{ $Cur_KP_ID } ); 292 | } 293 | return $table[$kf - 1]; 294 | } 295 | 296 | ### Keyframe menu selection: 297 | # Updates the x/y/z translations of keypoint $Cur_KP_ID at keyframe $Cur_KF 298 | # in the three sliders 299 | # Updates all the keypoint positions 300 | # at keyframe $Cur_KF for the graphic engine through message emissions. 301 | sub KP_KF_menu_select 302 | { 303 | my ( $item, $kf ) = @_ ; 304 | $Cur_KF = $kf; 305 | # print "Cur_KF $Cur_KF\n"; 306 | $message_output = FALSE; 307 | $adj1->set_value( get_value_KP_KF( $Cur_KP_ID , $Cur_KF , 'x' ) ); 308 | $adj2->set_value( get_value_KP_KF( $Cur_KP_ID , $Cur_KF , 'y' ) ); 309 | $adj3->set_value( get_value_KP_KF( $Cur_KP_ID , $Cur_KF , 'z' ) ); 310 | # triggers message emission for each keypoint 311 | foreach $KP_ID ( @KP_ID_list ) { 312 | my @valsx = split( / / , $KP_Pos_x{ $KP_ID } ); 313 | my @valsy = split( / / , $KP_Pos_y{ $KP_ID } ); 314 | my @valsz = split( / / , $KP_Pos_z{ $KP_ID } ); 315 | my $message = sprintf "%s %d %f %f %f" , $KP_ID , $Cur_KF , 316 | $valsx[$Cur_KF - 1] , $valsy[$Cur_KF - 1] , $valsz[$Cur_KF - 1] ; 317 | if( $message ) { 318 | my $lengthSent = send(SOCKET, $message, 0, $portaddr); 319 | # print $lengthSent . "\n" ; 320 | 321 | $lengthSent == length($message) 322 | or die "cannot send to $HOSTNAME ($PORTNO) $lengthSent: $!"; 323 | 324 | print "Sent: [$message]\n" ; 325 | } 326 | } 327 | } 328 | 329 | ### Keypoint menu selection: 330 | # Updates the x/y/z translations of keypoint $Cur_KP_ID at keyframe $Cur_KF 331 | # in the three sliders 332 | # Updates the $Cur_KP_ID keypoint positions 333 | # at keyframe $Cur_KF for the graphic engine through message emission. 334 | sub KP_ID_menu_select 335 | { 336 | my ( $item, $ID ) = @_ ; 337 | $Cur_KP_ID = $ID; 338 | # print "Cur_KP_ID $Cur_KP_ID\n"; 339 | $message_output = FALSE; 340 | $adj1->set_value( get_value_KP_KF( $Cur_KP_ID , $Cur_KF , 'x' ) ); 341 | $adj2->set_value( get_value_KP_KF( $Cur_KP_ID , $Cur_KF , 'y' ) ); 342 | $adj3->set_value( get_value_KP_KF( $Cur_KP_ID , $Cur_KF , 'z' ) ); 343 | # triggers message emission 344 | $message_output = TRUE; 345 | &KP_transl_value( $adj1 , 'x' ); 346 | } 347 | 348 | ### Keypoint translation slider: updates the $Cur_KP_ID keypoint positions 349 | # at keyframe $Cur_KF for the graphic engine through message emission. 350 | sub KP_transl_value 351 | { 352 | my ( $adjustment , $coord ) = @_ ; 353 | my @valsx = split( / / , $KP_Pos_x{ $Cur_KP_ID } ); 354 | my @valsy = split( / / , $KP_Pos_y{ $Cur_KP_ID } ); 355 | my @valsz = split( / / , $KP_Pos_z{ $Cur_KP_ID } ); 356 | if( $coord eq 'x' ) { 357 | $valsx[$Cur_KF - 1] = $adjustment->get_value; 358 | $KP_Pos_x{ $Cur_KP_ID } = join( " " , @valsx ); 359 | } 360 | elsif( $coord eq 'y' ) { 361 | $valsy[$Cur_KF - 1] = $adjustment->get_value; 362 | $KP_Pos_y{ $Cur_KP_ID } = join( " " , @valsy ); 363 | } 364 | elsif( $coord eq 'z' ) { 365 | $valsz[$Cur_KF - 1] = $adjustment->get_value; 366 | $KP_Pos_z{ $Cur_KP_ID } = join( " " , @valsz ); 367 | } 368 | if( $message_output ) { 369 | my $message = sprintf "%s %d %f %f %f" , $Cur_KP_ID , $Cur_KF , 370 | $valsx[$Cur_KF - 1] , $valsy[$Cur_KF - 1] , $valsz[$Cur_KF - 1] ; 371 | if( $message ) { 372 | my $lengthSent = send(SOCKET, $message, 0, $portaddr); 373 | # print $lengthSent . "\n" ; 374 | 375 | $lengthSent == length($message) 376 | or die "cannot send to $HOSTNAME ($PORTNO) $lengthSent: $!"; 377 | 378 | print "Sent: [$message]\n" ; 379 | } 380 | } 381 | } 382 | 383 | ### Keypoint reset button: 384 | # Resets to 0 the x/y/z translations of keypoint $Cur_KP_ID 385 | # at keyframe $Cur_KF in the three sliders 386 | # Resets to (0,0,0) the $Cur_KP_ID keypoint positions 387 | # at keyframe $Cur_KF for the graphic engine through message emission. 388 | sub KP_reset 389 | { 390 | my @valsx = split( / / , $KP_Pos_x{ $Cur_KP_ID } ); 391 | my @valsy = split( / / , $KP_Pos_y{ $Cur_KP_ID } ); 392 | my @valsz = split( / / , $KP_Pos_y{ $Cur_KP_ID } ); 393 | $valsx[$Cur_KF - 1] = 0.0; 394 | $valsy[$Cur_KF - 1] = 0.0; 395 | $valsz[$Cur_KF - 1] = 0.0; 396 | $KP_Pos_x{ $Cur_KP_ID } = join( " " , @valsx ); 397 | $KP_Pos_y{ $Cur_KP_ID } = join( " " , @valsy ); 398 | $KP_Pos_z{ $Cur_KP_ID } = join( " " , @valsz ); 399 | $message_output = FALSE; 400 | $adj1->set_value( 0 ); 401 | $adj2->set_value( 0 ); 402 | $adj3->set_value( 0 ); 403 | # triggers message emission 404 | $message_output = TRUE; 405 | &KP_transl_value( $adj1 , 'x' ); 406 | } 407 | 408 | # Menu item addition for menu construction 409 | sub make_menu_item 410 | { 411 | my ( $name, $callback, $data ) = @_ ; 412 | my $item ; 413 | $item = Gtk2::MenuItem->new( $name ) ; 414 | $item->signal_connect( "activate" , $callback, $data ) ; 415 | $item->show() ; 416 | return $item ; 417 | } 418 | 419 | # Loads the keypoint IDs and the tables of keypoint positions 420 | # at each keyframe from the .cpp tables (see file heading comments 421 | # for more details on this format) 422 | sub load_KFs { 423 | # default file name 424 | # my $KPFileName = "Anime_Girl_KP.obj"; 425 | my $KPFileName = "head_modified_KP.obj"; 426 | my $KP_ID = ""; 427 | my $item; 428 | my $index = 0; 429 | 430 | my $KPFileNameAux = $KPFileName; 431 | $KPFileNameAux =~ s/.obj//; 432 | $KPFileNameAux .= "_KF.cpp"; 433 | 434 | # reads the last output file 435 | # increments a version number until no existing file is found 436 | my $ID_file = 1; 437 | my $lastOutputFile = ""; 438 | while( -e $KPFileNameAux ) { 439 | $lastOutputFile = $KPFileNameAux; 440 | $KPFileNameAux =~ s/[0-9]*.cpp//; 441 | $KPFileNameAux .= "$ID_file.cpp"; 442 | $ID_file++; 443 | } 444 | if( !$lastOutputFile ) { 445 | while( !(-e $KPFileNameAux) ) { 446 | printf "Fichier $KPFileNameAux non trouve\n" ; 447 | printf "Nom du fichier de keyframes: "; 448 | $KPFileNameAux = ; 449 | chomp $KPFileNameAux; 450 | } 451 | $lastOutputFile = $KPFileNameAux; 452 | } 453 | 454 | # scans the file 455 | if( $lastOutputFile ) { 456 | my $coor; 457 | my $indKP; 458 | my $translation; 459 | my @translVect; 460 | open( FILEaux , "<$lastOutputFile" ) 461 | || die "Can't open file '$lastOutputFile'!"; 462 | print "Loading $lastOutputFile...\n\n"; 463 | while( ) { 464 | # reads and stores keypoint IDS 465 | if( /char tab_ID.*\{\s*(.*)\s*\}/ ) { 466 | my $KP_list = $1; 467 | $KP_list =~ s/\"//g; 468 | $KP_list =~ s/\s+$//g; 469 | @KP_ID_list = split( /\s*,\s*/ , $KP_list ); 470 | } 471 | 472 | # reads and stores number of keyframes $Nb_Keyframes and current 473 | # coordinates ( 'x', 'y', or 'z' ) 474 | elsif( /float tab_KF_([xyz])\[([0-9]+)\]\[([0-9]+)\]/ ) { 475 | $coor = $1; 476 | $Nb_Keyframes = $3; 477 | $indKP = 0; 478 | } 479 | 480 | # reads and stores x, y, or z translations of keypoint $indKP 481 | # at the $Nb_Keyframes keyframes 482 | elsif( /^\s*\{\s*(.*)\s*\}/ ) { 483 | $translation = $1; 484 | @translVect = split( /\s*,\s*/ , $translation ); 485 | if( $coor eq 'x' ) { 486 | $KP_Pos_x{ $KP_ID_list[$indKP] } 487 | = join( " " , @translVect ); 488 | } 489 | elsif( $coor eq 'y' ) { 490 | $KP_Pos_y{ $KP_ID_list[$indKP] } 491 | = join( " " , @translVect ); 492 | } 493 | elsif( $coor eq 'z' ) { 494 | $KP_Pos_z{ $KP_ID_list[$indKP] } 495 | = join( " " , @translVect ); 496 | } 497 | $indKP++; 498 | } 499 | } 500 | close( FILEaux ); 501 | } 502 | } 503 | 504 | # Saves the keypoint IDs and the tables of keypoint positions 505 | # at each keyframe through tables into a new .cpp file (see file 506 | # heading comments for more details on this format) 507 | sub quit_and_save { 508 | my $KP_ID; 509 | my $index = 0; 510 | # my $KPFileName = "Anime_Girl_KP_KF.cpp"; 511 | my $KPFileName = "head_modified_KP_KF.cpp"; 512 | 513 | # does not overwrite the input file 514 | # increments a version number until no existing file is found 515 | my $ID_file = 1; 516 | while( -e $KPFileName ) { 517 | $KPFileName =~ s/[0-9]*.cpp//; 518 | $KPFileName .= "$ID_file.cpp"; 519 | $ID_file++; 520 | } 521 | 522 | open( FILEaux , ">$KPFileName" ) 523 | || die "Can't open file '$KPFileName'!"; 524 | 525 | # writes keypoint IDS 526 | printf( FILEaux "char tab_ID[%d][16] = { \"%s\" };\n" , 527 | @KP_ID_list + 0 , join( "\" , \"" , @KP_ID_list ) ); 528 | 529 | # writes number of keyframes and writes x coordinates for each 530 | # keypoint at each keyframe 531 | $index = 0; 532 | printf( FILEaux "float tab_KF_x[%d][$Nb_Keyframes] = { \n" , 533 | @KP_ID_list + 0 ); 534 | foreach $KP_ID ( @KP_ID_list ) { 535 | my @valsx = split( / / , $KP_Pos_x{ $KP_ID } ); 536 | printf FILEaux " { %s } " , join( " , " , @valsx ) ; 537 | if( $index < @KP_ID_list - 1 ) { 538 | printf FILEaux " , \n"; 539 | } 540 | else { 541 | printf FILEaux "\n }; \n"; 542 | } 543 | $index++; 544 | } 545 | 546 | # writes number of keyframes and writes y coordinates for each 547 | # keypoint at each keyframe 548 | $index = 0; 549 | printf( FILEaux "float tab_KF_y[%d][$Nb_Keyframes] = { \n" , 550 | @KP_ID_list + 0 ); 551 | foreach $KP_ID ( @KP_ID_list ) { 552 | my @valsy = split( / / , $KP_Pos_y{ $KP_ID } ); 553 | printf FILEaux " { %s } " , join( " , " , @valsy ) ; 554 | if( $index < @KP_ID_list - 1 ) { 555 | printf FILEaux " , \n"; 556 | } 557 | else { 558 | printf FILEaux "\n }; \n"; 559 | } 560 | $index++; 561 | } 562 | 563 | # writes number of keyframes and writes z coordinates for each 564 | # keypoint at each keyframe 565 | $index = 0; 566 | printf( FILEaux "float tab_KF_z[%d][$Nb_Keyframes] = { \n" , 567 | @KP_ID_list + 0 ); 568 | foreach $KP_ID ( @KP_ID_list ) { 569 | my @valsz = split( / / , $KP_Pos_z{ $KP_ID } ); 570 | printf FILEaux " { %s } " , join( " , " , @valsz ) ; 571 | if( $index < @KP_ID_list - 1 ) { 572 | printf FILEaux " , \n"; 573 | } 574 | else { 575 | printf FILEaux "\n }; \n"; 576 | } 577 | $index++; 578 | } 579 | 580 | # closes output file 581 | close( FILEaux ); 582 | 583 | # quits the interface 584 | Gtk2->main_quit ; 585 | } 586 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricfoucault/facial_animation/f83f3512d6bd16f6a879394e5a3534f62d3ac71e/Makefile -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | Instructions 2 | ------------ 3 | 4 | To compile the program, run the following in the main project directory (where "Makefile" is): 5 | 6 | make KP-anim-modele 7 | 8 | The resulting program can be executed: 9 | 10 | ./KP-anim-modele 11 | 12 | The program should compile and run correctly both on Linux and Mac OSX. 13 | 14 | Usage 15 | ------------ 16 | 17 | Type 'enter' after executing the program to use the default mesh. The program will display the default mesh and wait for user input. You can interact with the program through keyboard input: 18 | 19 | > zoom in 20 | < zoom out 21 | 1 22 | 2 23 | … 24 | 8 animate the face to display one of the 8 faces: 25 | 1 neutral 26 | 2 happiness 27 | 3 sadness 28 | 4 surprise 29 | 5 anger 30 | 6 disgust 31 | 7 fear 32 | 8 default mesh (does not correspond to any emotion) 33 | + increment the animation duration by 0.25s (default duration: 1.0 s) 34 | - decrement the animation duration by 0.25s (default duration: 1.0 s) 35 | q use the easeInOutQuad easing function for the animation 36 | w use the linear easing function for the animation 37 | a use the inverse-distance weighting scheme to position vertices w.r.t key points 38 | s use the linear weighting scheme to position vertices w.r.t key points 39 | 40 | Alternatively, you can use the "high polygon" version of the mesh (after 1 level of subdivision surface has been applied), but I haven't designed the facial expression using this mesh, so I'm not sure about the quality of the results. To use this mesh, do: 41 | 42 | ./KP-anim-modele head_modified_highpoly.obj 43 | 44 | or type "head_modified_highpoly.obj" when prompted. 45 | 46 | Enjoy! 47 | 48 | 49 | Contact 50 | ------------ 51 | Cédric Foucault 52 | cedric.foucault@gmail.com 53 | -------------------------------------------------------------------------------- /head_modified.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricfoucault/facial_animation/f83f3512d6bd16f6a879394e5a3534f62d3ac71e/head_modified.blend -------------------------------------------------------------------------------- /head_modified.blend1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricfoucault/facial_animation/f83f3512d6bd16f6a879394e5a3534f62d3ac71e/head_modified.blend1 -------------------------------------------------------------------------------- /head_modified.blend2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricfoucault/facial_animation/f83f3512d6bd16f6a879394e5a3534f62d3ac71e/head_modified.blend2 -------------------------------------------------------------------------------- /head_modified.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'head_modified.blend' 2 | # Material Count: 1 3 | 4 | newmtl Material 5 | Ns 96.078431 6 | Ka 0.000000 0.000000 0.000000 7 | Kd 0.640000 0.640000 0.640000 8 | Ks 0.500000 0.500000 0.500000 9 | Ni 1.000000 10 | d 1.000000 11 | illum 2 12 | -------------------------------------------------------------------------------- /head_modified.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.69 (sub 0) OBJ File: 'head_modified.blend' 2 | # www.blender.org 3 | mtllib head_modified.mtl 4 | o Plane.001_Plane 5 | v 1.038782 0.465088 0.879050 6 | v 1.035427 0.337688 0.442714 7 | v 0.250310 -0.259488 0.892358 8 | v 0.098724 -0.244724 0.409461 9 | v 0.258143 0.175661 -1.262667 10 | v 0.328324 -0.119223 0.827375 11 | v 1.007893 0.269284 0.812160 12 | v 0.880479 1.006323 -0.354114 13 | v 0.067852 -0.182125 0.561870 14 | v 0.920925 0.333398 0.478558 15 | v 0.401586 0.062908 -0.529648 16 | v 0.166770 -0.227679 -0.415225 17 | v 0.233659 -0.149453 -0.660414 18 | v 0.412203 0.080263 -0.567348 19 | v 0.362577 -0.037160 -0.518819 20 | v 0.188936 -0.148128 -0.477260 21 | v 0.221178 -0.126438 -0.591410 22 | v 0.360582 -0.032766 -0.534501 23 | v 0.473492 0.036593 -0.327783 24 | v 0.108726 -0.180198 -0.142810 25 | v 0.556410 0.230774 -0.571338 26 | v 0.272750 0.000952 -0.828285 27 | v 0.060464 -0.296160 0.323072 28 | v 0.268375 0.002990 -1.113648 29 | v 0.664844 0.044224 -0.022647 30 | v 0.756698 0.527207 -0.539281 31 | v 0.659822 -0.037320 0.934278 32 | v 0.415474 -0.073102 0.416423 33 | v 0.542436 -0.026709 0.483292 34 | v 0.680270 -0.026011 0.981829 35 | v 0.265782 -0.171254 -0.444235 36 | v 0.269442 -0.118842 -0.491989 37 | v 0.174735 -0.180931 -0.135419 38 | v 0.213076 -0.077294 -0.010692 39 | v 1.050956 0.636636 0.607317 40 | v 0.144612 -0.137321 0.653431 41 | v 0.891008 0.338337 0.620702 42 | v 0.297110 0.001685 0.742499 43 | v 0.763616 0.183694 0.798286 44 | v 0.417323 0.006662 0.548475 45 | v 0.801688 0.233688 0.593638 46 | v 0.598952 0.025882 0.822145 47 | v 0.599787 0.085633 0.530203 48 | v 0.258451 0.024875 0.624799 49 | v 0.899419 0.256846 0.635118 50 | v 0.398921 -0.046006 0.717042 51 | v 0.765852 0.152897 0.723597 52 | v 0.431417 -0.023252 0.607382 53 | v 0.797382 0.175446 0.636136 54 | v 0.606190 -0.019620 0.751522 55 | v 0.610667 0.003093 0.598790 56 | v 0.282323 -0.018228 0.644223 57 | v 0.844562 0.221239 0.669715 58 | v 0.121918 -0.408602 -0.083281 59 | v 0.089278 -0.475509 0.088569 60 | v 0.179017 -0.375880 -0.070727 61 | v 0.237715 -0.366968 0.003637 62 | v 0.110386 -0.166047 0.075643 63 | v 0.152405 -0.156634 0.084024 64 | v 0.109572 -0.241726 0.110298 65 | v 0.138602 -0.234025 0.111207 66 | v 0.268692 0.002027 -0.925381 67 | v 0.551484 0.083145 -0.307286 68 | v 0.645143 0.358939 -0.551752 69 | v 0.247870 -0.167991 -0.095040 70 | v 0.132615 -0.486049 0.000010 71 | v 0.218198 -0.424887 -0.022770 72 | v 0.341844 -0.278070 0.000789 73 | v 0.068309 -0.405595 0.187654 74 | v 0.208320 -0.342203 -0.078016 75 | v 0.100491 -0.333828 -0.112070 76 | v 0.174493 -0.197726 0.094807 77 | v 0.077505 -0.213376 0.099235 78 | v 0.275554 -0.285228 -0.076531 79 | v 0.965847 0.852755 -0.108862 80 | v 0.361230 -0.034568 -0.527741 81 | v 0.394228 0.075637 -0.544761 82 | v 0.561013 0.153488 -0.437984 83 | v 0.810482 0.328709 -0.233247 84 | v 0.647139 0.133933 -0.355432 85 | v 0.602055 0.740010 -0.941187 86 | v 0.331268 -0.086852 -0.606852 87 | v 0.301687 -0.083963 -0.560605 88 | v 0.371856 0.155242 -0.738938 89 | v 0.522793 0.363373 -0.835047 90 | v 0.446710 0.258607 -0.768043 91 | v 1.091611 0.711071 1.350650 92 | v 0.258143 0.595159 -1.232610 93 | v 1.051218 1.582571 -0.259149 94 | v 1.105229 1.358812 0.246477 95 | v 0.810030 1.315086 -0.724123 96 | v 0.305872 -0.103104 1.867813 97 | v 0.750180 0.137519 1.728396 98 | v 1.201802 1.010975 0.995933 99 | v 1.177755 1.449565 0.584180 100 | v 1.047447 1.169456 1.728425 101 | v 0.290673 0.637039 2.490415 102 | v 0.684102 0.819160 2.317236 103 | v 1.197686 1.427531 1.396338 104 | v 1.258830 1.660837 0.860173 105 | v 1.098791 2.036084 1.983755 106 | v 0.316131 2.134333 2.650162 107 | v 0.806297 2.066031 2.440491 108 | v 1.263734 1.977723 1.512344 109 | v 1.241489 1.926358 0.905451 110 | v 1.018713 2.653426 1.283248 111 | v 0.408097 2.993211 1.877322 112 | v 0.753123 2.866677 1.605019 113 | v 1.155566 2.344692 1.046019 114 | v 1.190201 2.128688 0.793917 115 | v 0.897816 2.728660 0.604775 116 | v 0.537143 3.034137 0.661403 117 | v 0.741091 2.919511 0.671692 118 | v 1.056018 2.470720 0.571021 119 | v 1.123117 2.241039 0.416437 120 | v 0.836579 2.327832 -0.259016 121 | v 0.577920 2.568347 -0.259760 122 | v 0.724183 2.466046 -0.249194 123 | v 0.946173 2.130434 -0.168263 124 | v 1.075167 1.929497 -0.109090 125 | v 0.816048 2.269421 -0.758180 126 | v 0.562222 2.644525 -0.791976 127 | v 0.725744 2.466437 -0.739160 128 | v 0.792050 2.008228 -0.736931 129 | v 0.814141 1.670379 -0.715846 130 | v 0.258143 1.143932 -1.033878 131 | v 0.741769 1.289235 -0.891498 132 | v 0.791804 2.338727 -1.089019 133 | v 0.494542 2.718850 -1.071267 134 | v 0.714973 2.506481 -1.107204 135 | v 0.788418 2.045094 -1.084267 136 | v 0.800374 1.704811 -1.046571 137 | v 0.280740 1.308893 -1.564281 138 | v 0.651888 1.484084 -1.433019 139 | v 0.902225 2.366821 -1.302083 140 | v 0.473845 2.785616 -1.358588 141 | v 0.739083 2.564050 -1.339219 142 | v 0.930102 2.064867 -1.331062 143 | v 0.895222 1.704605 -1.341659 144 | v 0.413501 0.068982 -0.510290 145 | v 0.420653 0.080263 -0.570168 146 | v 0.145097 -0.275516 -0.354757 147 | v 0.254092 -0.168796 -0.721885 148 | v 0.265986 -0.204832 -0.396865 149 | v 0.427815 0.075637 -0.544914 150 | v 0.345443 -0.059962 -0.654282 151 | v 0.646658 -0.038308 0.347801 152 | v 0.701314 0.115707 0.479541 153 | v 0.337213 -0.077464 -0.481316 154 | v 0.318170 -0.079603 -0.504819 155 | v 0.376272 -0.090969 -0.254180 156 | v 0.491833 -0.023053 0.079814 157 | v 0.719177 0.158964 0.549044 158 | v 0.725908 0.107753 0.610370 159 | v 0.401796 -0.075143 -0.127281 160 | v 0.347622 -0.073288 -0.447409 161 | v 1.022584 1.536724 -0.255422 162 | v 1.096767 1.593734 0.286829 163 | v 1.129972 1.649091 0.447203 164 | v 1.307566 1.633311 0.729311 165 | v 1.216087 1.916615 0.853875 166 | v 1.320556 2.103529 0.755360 167 | v 1.228430 2.207319 0.413371 168 | v 1.180038 1.869901 -0.083121 169 | v 1.113437 1.658967 0.367940 170 | v 1.276173 1.719513 0.738211 171 | v 1.351897 1.984041 0.758677 172 | v 1.269417 2.072214 0.336924 173 | v 1.221452 1.687812 0.138397 174 | v 1.077874 1.882417 0.194974 175 | v 0.990454 1.678541 0.271251 176 | v 1.408795 1.788405 0.803409 177 | v 1.198768 1.992958 0.511217 178 | v 1.118656 2.066701 0.401037 179 | v 1.162190 2.002605 0.705813 180 | v 1.151701 1.623502 0.507390 181 | v 1.087971 1.541394 0.244796 182 | v 1.020627 1.588063 0.058547 183 | v 1.194470 1.877558 0.774345 184 | v 1.086091 1.806733 0.149259 185 | v 1.192906 1.712737 0.717229 186 | v 1.092499 1.572098 0.331148 187 | v 0.939513 1.697963 0.181213 188 | v 0.970568 1.718916 0.222072 189 | v 1.086974 1.868691 0.356821 190 | v 0.847304 1.563709 0.308779 191 | v 0.694319 1.598573 0.145487 192 | v 0.725373 1.710527 0.226416 193 | v 0.841779 1.860302 0.334452 194 | v -1.038782 0.465088 0.879050 195 | v -0.000000 -0.277826 0.872838 196 | v -1.035427 0.337688 0.442714 197 | v -0.000000 -0.256618 0.467242 198 | v -0.250310 -0.259488 0.892358 199 | v -0.098724 -0.244724 0.409461 200 | v 0.000000 0.166371 -1.274369 201 | v -0.258143 0.175661 -1.262667 202 | v -0.000000 -0.286886 0.773760 203 | v -0.328324 -0.119223 0.827375 204 | v -1.007893 0.269284 0.812160 205 | v -0.880479 1.006323 -0.354114 206 | v -0.067852 -0.182125 0.561870 207 | v -0.920925 0.333398 0.478558 208 | v -0.000000 -0.221523 0.555863 209 | v -0.401586 0.062908 -0.529648 210 | v 0.000000 -0.197075 -0.429524 211 | v -0.166770 -0.227679 -0.415225 212 | v 0.000000 -0.203425 -0.705536 213 | v -0.233659 -0.149453 -0.660414 214 | v -0.412203 0.080263 -0.567348 215 | v -0.362577 -0.037160 -0.518819 216 | v 0.000000 -0.165401 -0.458699 217 | v -0.188936 -0.148128 -0.477260 218 | v 0.000000 -0.151499 -0.625639 219 | v -0.221178 -0.126438 -0.591410 220 | v -0.360582 -0.032766 -0.534501 221 | v -0.473492 0.036593 -0.327783 222 | v -0.108726 -0.180198 -0.142810 223 | v -0.556410 0.230774 -0.571338 224 | v 0.000000 0.006105 -0.828640 225 | v -0.272750 0.000952 -0.828285 226 | v 0.000000 -0.207601 -0.184649 227 | v -0.060464 -0.296160 0.323072 228 | v -0.268375 0.002990 -1.113648 229 | v -0.000000 -0.313097 0.330681 230 | v -0.664844 0.044224 -0.022647 231 | v -0.756698 0.527207 -0.539281 232 | v 0.000000 0.005456 -1.104032 233 | v -0.659822 -0.037320 0.934278 234 | v -0.415474 -0.073102 0.416423 235 | v -0.542436 -0.026709 0.483292 236 | v -0.680270 -0.026011 0.981829 237 | v -0.265782 -0.171254 -0.444235 238 | v -0.269442 -0.118842 -0.491989 239 | v -0.174735 -0.180931 -0.135419 240 | v -0.213076 -0.077294 -0.010692 241 | v -1.050956 0.636636 0.607317 242 | v -0.144612 -0.137321 0.653431 243 | v -0.891008 0.338337 0.620702 244 | v -0.000000 -0.234009 0.681061 245 | v -0.297110 0.001685 0.742499 246 | v -0.763616 0.183694 0.798286 247 | v -0.417323 0.006662 0.548475 248 | v -0.801688 0.233688 0.593638 249 | v -0.598952 0.025882 0.822145 250 | v -0.599787 0.085633 0.530203 251 | v -0.258451 0.024875 0.624799 252 | v -0.899419 0.256846 0.635118 253 | v -0.398921 -0.046006 0.717042 254 | v -0.765852 0.152897 0.723597 255 | v -0.431417 -0.023252 0.607382 256 | v -0.797382 0.175446 0.636136 257 | v -0.606190 -0.019620 0.751522 258 | v -0.610667 0.003093 0.598790 259 | v -0.282323 -0.018228 0.644223 260 | v -0.844562 0.221239 0.669715 261 | v -0.121918 -0.408602 -0.083281 262 | v 0.000000 -0.443501 -0.083997 263 | v -0.089278 -0.475509 0.088569 264 | v 0.000000 -0.505450 0.079177 265 | v -0.179017 -0.375880 -0.070727 266 | v -0.237715 -0.366968 0.003637 267 | v -0.110386 -0.166047 0.075643 268 | v -0.152405 -0.156634 0.084024 269 | v -0.109572 -0.241726 0.110298 270 | v -0.138602 -0.234025 0.111207 271 | v -0.268692 0.002027 -0.925381 272 | v -0.551484 0.083145 -0.307286 273 | v -0.645143 0.358939 -0.551752 274 | v 0.000000 0.005763 -0.958389 275 | v -0.247870 -0.167991 -0.095040 276 | v -0.132615 -0.486049 0.000010 277 | v 0.000000 -0.517691 0.000182 278 | v -0.218198 -0.424887 -0.022770 279 | v -0.341844 -0.278070 0.000789 280 | v 0.000000 -0.367929 -0.129623 281 | v -0.068309 -0.405595 0.187654 282 | v -0.208320 -0.342203 -0.078016 283 | v -0.100491 -0.333828 -0.112070 284 | v 0.000000 -0.412674 0.199522 285 | v -0.174493 -0.197726 0.094807 286 | v -0.077505 -0.213376 0.099235 287 | v -0.275554 -0.285228 -0.076531 288 | v -0.965847 0.852755 -0.108862 289 | v -0.361230 -0.034568 -0.527741 290 | v -0.394228 0.075637 -0.544761 291 | v -0.561013 0.153488 -0.437984 292 | v -0.810482 0.328709 -0.233247 293 | v -0.647139 0.133933 -0.355432 294 | v -0.602055 0.740010 -0.941187 295 | v -0.331268 -0.086852 -0.606852 296 | v -0.301687 -0.083963 -0.560605 297 | v -0.371856 0.155242 -0.738938 298 | v -0.522793 0.363373 -0.835047 299 | v -0.446710 0.258607 -0.768043 300 | v -1.091611 0.711071 1.350650 301 | v -0.258143 0.595159 -1.232610 302 | v -1.051218 1.582571 -0.259149 303 | v -1.105229 1.358812 0.246477 304 | v -0.810030 1.315086 -0.724123 305 | v -0.000000 -0.166772 1.905169 306 | v -0.305872 -0.103104 1.867813 307 | v -0.750180 0.137519 1.728396 308 | v -1.201802 1.010975 0.995933 309 | v -1.177755 1.449565 0.584180 310 | v -1.047447 1.169456 1.728425 311 | v -0.000000 0.540066 2.538182 312 | v -0.290673 0.637039 2.490415 313 | v -0.684102 0.819160 2.317236 314 | v -1.197686 1.427531 1.396338 315 | v -1.258830 1.660837 0.860173 316 | v -1.098791 2.036084 1.983755 317 | v -0.000000 2.025711 2.767323 318 | v -0.316131 2.134333 2.650162 319 | v -0.806297 2.066031 2.440491 320 | v -1.263734 1.977723 1.512344 321 | v -1.241489 1.926358 0.905451 322 | v -1.018713 2.653426 1.283248 323 | v -0.000000 3.110739 2.070234 324 | v -0.408097 2.993211 1.877322 325 | v -0.753123 2.866677 1.605019 326 | v -1.155566 2.344692 1.046019 327 | v -1.190201 2.128688 0.793917 328 | v -0.897816 2.728660 0.604775 329 | v -0.000000 3.093846 0.664516 330 | v -0.537143 3.034137 0.661403 331 | v -0.741091 2.919511 0.671692 332 | v -1.056018 2.470720 0.571021 333 | v -1.123117 2.241039 0.416437 334 | v -0.836579 2.327832 -0.259016 335 | v -0.000000 2.654266 -0.219341 336 | v -0.577920 2.568347 -0.259760 337 | v -0.724183 2.466046 -0.249194 338 | v -0.946173 2.130434 -0.168263 339 | v -1.075167 1.929497 -0.109090 340 | v -0.816048 2.269421 -0.758180 341 | v -0.000000 2.782751 -0.787896 342 | v -0.562222 2.644525 -0.791976 343 | v -0.725744 2.466437 -0.739160 344 | v -0.792050 2.008228 -0.736931 345 | v -0.814141 1.670379 -0.715846 346 | v -0.258143 1.143932 -1.033878 347 | v -0.741769 1.289235 -0.891498 348 | v -0.791804 2.338727 -1.089019 349 | v -0.000000 2.867374 -1.111004 350 | v -0.494542 2.718850 -1.071267 351 | v -0.714973 2.506481 -1.107204 352 | v -0.788418 2.045094 -1.084267 353 | v -0.800374 1.704811 -1.046571 354 | v -0.280740 1.308893 -1.564281 355 | v -0.651888 1.484084 -1.433019 356 | v -0.902225 2.366821 -1.302083 357 | v -0.000000 2.973602 -1.346790 358 | v -0.473845 2.785616 -1.358588 359 | v -0.739083 2.564050 -1.339219 360 | v -0.930102 2.064867 -1.331062 361 | v -0.895222 1.704605 -1.341659 362 | v 0.000000 0.555777 -1.261018 363 | v 0.000000 1.066637 -1.097452 364 | v 0.000000 1.301116 -1.579350 365 | v -0.413501 0.068982 -0.510290 366 | v -0.420653 0.080263 -0.570168 367 | v 0.000000 -0.178695 -0.773256 368 | v -0.145097 -0.275516 -0.354757 369 | v -0.254092 -0.168796 -0.721885 370 | v 0.000000 -0.226406 -0.377623 371 | v -0.265986 -0.204832 -0.396865 372 | v -0.427815 0.075637 -0.544914 373 | v -0.345443 -0.059962 -0.654282 374 | v -0.646658 -0.038308 0.347801 375 | v -0.701314 0.115707 0.479541 376 | v -0.337213 -0.077464 -0.481316 377 | v -0.318170 -0.079603 -0.504819 378 | v -0.376272 -0.090969 -0.254180 379 | v -0.491833 -0.023053 0.079814 380 | v -0.719177 0.158964 0.549044 381 | v -0.725908 0.107753 0.610370 382 | v -0.401796 -0.075143 -0.127281 383 | v -0.347622 -0.073288 -0.447409 384 | v -1.022584 1.536724 -0.255422 385 | v -1.096767 1.593734 0.286829 386 | v -1.129972 1.649091 0.447203 387 | v -1.307566 1.633311 0.729311 388 | v -1.216087 1.916615 0.853875 389 | v -1.320556 2.103529 0.755360 390 | v -1.228430 2.207319 0.413371 391 | v -1.180038 1.869901 -0.083121 392 | v -1.113437 1.658967 0.367940 393 | v -1.276173 1.719513 0.738211 394 | v -1.351897 1.984041 0.758677 395 | v -1.269417 2.072214 0.336924 396 | v -1.221452 1.687812 0.138397 397 | v -1.077874 1.882417 0.194974 398 | v -0.990454 1.678541 0.271251 399 | v -1.408795 1.788405 0.803409 400 | v -1.198768 1.992958 0.511217 401 | v -1.118656 2.066701 0.401037 402 | v -1.162190 2.002605 0.705813 403 | v -1.151701 1.623502 0.507390 404 | v -1.087971 1.541394 0.244796 405 | v -1.020627 1.588063 0.058547 406 | v -1.194470 1.877558 0.774345 407 | v -1.086091 1.806733 0.149259 408 | v -1.192906 1.712737 0.717229 409 | v -1.092499 1.572098 0.331148 410 | v -0.939513 1.697963 0.181213 411 | v -0.970568 1.718916 0.222072 412 | v -1.086974 1.868691 0.356821 413 | v -0.847304 1.563709 0.308779 414 | v -0.694319 1.598573 0.145487 415 | v -0.725373 1.710527 0.226416 416 | v -0.841779 1.860302 0.334452 417 | vn 0.000000 0.975860 -0.218268 418 | vn -0.454451 0.861202 -0.227515 419 | vn -0.473525 0.855922 -0.207709 420 | vn -0.355235 0.898099 0.259133 421 | vn -0.572741 0.790857 -0.215583 422 | vn -0.718223 0.695761 -0.004273 423 | vn 0.000000 0.999908 0.012940 424 | vn -0.254707 0.880459 0.399823 425 | vn -0.442793 0.558397 0.701468 426 | vn -0.940062 0.338054 0.044313 427 | vn -0.974914 0.219092 0.038423 428 | vn -0.589404 0.585345 -0.556719 429 | vn -0.619098 0.692679 -0.369945 430 | vn -0.514695 0.849910 -0.112735 431 | vn 0.000000 0.941252 0.337687 432 | vn -0.551927 0.814264 0.179693 433 | vn -0.532121 0.787866 0.309946 434 | vn -0.549547 0.753777 0.360240 435 | vn -0.658742 0.752312 -0.005005 436 | vn -0.955107 0.286325 -0.075655 437 | vn -0.821070 0.556993 0.124729 438 | vn -0.445387 0.848384 0.286081 439 | vn -0.818506 0.314707 0.480575 440 | vn -0.754875 0.553117 0.352397 441 | vn -0.659247 0.609488 0.440360 442 | vn 0.000000 0.744926 0.667104 443 | vn -0.100650 0.739982 0.665029 444 | vn -0.041942 0.625806 0.778850 445 | vn -0.429518 0.861568 0.270547 446 | vn 0.000000 0.739280 0.673360 447 | vn -0.213538 0.923643 -0.318217 448 | vn 0.000000 0.986602 0.162969 449 | vn -0.123844 0.991943 0.026368 450 | vn -0.840358 0.460952 0.285134 451 | vn -0.705649 0.670278 -0.229652 452 | vn -0.599127 0.742784 -0.298863 453 | vn 0.000000 0.999298 -0.037416 454 | vn -0.233749 0.898954 -0.370463 455 | vn -0.361339 0.855037 -0.371838 456 | vn -0.917517 0.357748 0.173721 457 | vn -0.649068 0.743522 0.160680 458 | vn -0.737175 0.455000 0.499496 459 | vn -0.708609 0.489212 0.508438 460 | vn -0.572466 0.818232 0.051973 461 | vn -0.578570 0.812586 0.070040 462 | vn -0.548021 0.827479 0.122105 463 | vn -0.457747 0.888974 0.013611 464 | vn 0.000000 0.999969 -0.000977 465 | vn -0.619831 0.689383 0.374859 466 | vn -0.583148 0.119907 0.803430 467 | vn 0.203101 0.216193 0.954985 468 | vn -0.654805 0.731956 0.188116 469 | vn -0.775933 0.606494 0.173254 470 | vn -0.931608 0.188574 0.310678 471 | vn -0.904416 0.187841 0.383038 472 | vn -0.910001 0.393506 0.130375 473 | vn -0.811884 0.515488 -0.273995 474 | vn -0.398419 0.912717 0.090518 475 | vn -0.448378 0.299600 0.842128 476 | vn 0.000000 0.351360 0.936216 477 | vn -0.460738 0.802301 0.379467 478 | vn 0.000000 0.926481 -0.376293 479 | vn -0.580370 0.702994 -0.410993 480 | vn -0.812738 0.117679 0.570574 481 | vn -0.569842 0.805689 -0.161565 482 | vn -0.278451 0.898618 -0.339000 483 | vn -0.649129 0.755730 0.086428 484 | vn -0.392224 0.698935 0.597980 485 | vn -0.271358 0.651367 0.708580 486 | vn -0.422132 0.704581 -0.570360 487 | vn -0.998291 0.049959 -0.029908 488 | vn -0.566698 0.575549 -0.589526 489 | vn -0.388226 0.909635 0.147649 490 | vn -0.661794 0.593951 -0.457350 491 | vn -0.796258 0.603473 -0.041810 492 | vn 0.000000 0.975616 0.219428 493 | vn -0.710074 0.692892 0.125065 494 | vn -0.582415 0.674093 0.454237 495 | vn -0.892209 0.415265 -0.177435 496 | vn -0.420759 0.873928 -0.243294 497 | vn -0.384167 0.912931 0.137608 498 | vn -0.275713 0.787007 -0.551909 499 | vn 0.015319 0.835306 0.549572 500 | vn -0.401776 0.895199 -0.192755 501 | vn -0.621982 0.762640 -0.177535 502 | vn 0.191582 0.678733 -0.708955 503 | vn -0.247289 0.617698 0.746524 504 | vn -0.591357 0.712333 0.377911 505 | vn -0.621774 0.566946 0.540343 506 | vn 0.000000 0.961913 0.273293 507 | vn -0.441755 0.879330 0.177709 508 | vn -0.419416 0.279061 0.863826 509 | vn 0.032136 -0.005463 0.999451 510 | vn -0.741264 0.146855 0.654927 511 | vn -0.818995 0.190863 0.541063 512 | vn 0.000000 0.794305 -0.607471 513 | vn 0.000000 0.923978 -0.382366 514 | vn 0.000000 0.409742 0.912198 515 | vn 0.000000 0.627216 0.778802 516 | vn 0.764916 0.211890 0.608234 517 | vn -0.236518 -0.346782 0.907590 518 | vn -0.044435 0.979400 0.196844 519 | vn -0.412946 0.905423 0.098239 520 | vn 0.353465 0.810846 0.466384 521 | vn 0.251808 -0.135075 0.958281 522 | vn -0.855312 0.187964 0.482742 523 | vn -0.588031 0.796838 0.138676 524 | vn 0.000000 0.931669 0.363231 525 | vn -0.849300 0.438734 0.293558 526 | vn -0.442366 0.765557 -0.467116 527 | vn -0.766717 0.574633 0.286233 528 | vn -0.590564 0.769189 0.243965 529 | vn 0.000000 0.857356 -0.514695 530 | vn 0.000000 0.884732 0.466048 531 | vn -0.666923 0.153829 -0.729075 532 | vn -0.565813 0.730522 0.382305 533 | vn -0.816065 0.493759 0.300302 534 | vn -0.946928 -0.004944 0.321299 535 | vn -0.327647 -0.158635 0.931364 536 | vn -0.983856 0.048830 0.172124 537 | vn -0.986206 0.165410 0.003113 538 | vn -0.938505 0.274392 -0.209387 539 | vn -0.710776 0.604144 -0.360210 540 | vn -0.374889 0.813166 -0.445143 541 | vn -0.913358 0.195929 -0.356883 542 | vn -0.680441 0.285165 -0.675008 543 | vn 0.000000 0.882443 -0.470382 544 | vn -0.373821 0.363598 -0.853236 545 | vn -0.982177 0.055971 0.179266 546 | vn -0.972015 0.163518 -0.168584 547 | vn 0.000000 0.446974 -0.894528 548 | vn -0.304544 -0.349590 -0.886013 549 | vn -0.629017 -0.255165 -0.734275 550 | vn -0.882168 -0.201880 -0.425428 551 | vn -0.967864 -0.163518 -0.190893 552 | vn -0.987274 0.064394 0.145268 553 | vn 0.000000 -0.172674 -0.984954 554 | vn -0.487655 -0.768822 -0.413587 555 | vn -0.625446 -0.728965 -0.278176 556 | vn -0.815699 -0.568041 -0.109287 557 | vn -0.940428 -0.339885 0.005554 558 | vn -0.976959 -0.122593 0.174566 559 | vn -0.978210 -0.146184 0.147374 560 | vn 0.000000 -0.837367 -0.546587 561 | vn -0.309915 -0.930113 0.196997 562 | vn -0.611866 -0.777337 0.146092 563 | vn -0.761925 -0.615131 0.202582 564 | vn -0.861873 -0.463637 0.205390 565 | vn -0.935881 -0.268441 0.228095 566 | vn 0.000000 -0.972900 0.231178 567 | vn -0.397320 -0.907956 0.133091 568 | vn -0.696524 -0.694357 0.180853 569 | vn -0.833644 -0.522782 0.178076 570 | vn -0.880856 -0.358745 0.308817 571 | vn -0.937040 -0.189398 0.293283 572 | vn 0.000000 -0.990356 0.138371 573 | vn 0.000000 -0.975921 -0.217994 574 | vn -0.522385 -0.848292 -0.086459 575 | vn -0.979583 -0.182073 0.084933 576 | vn -0.976897 -0.034791 0.210822 577 | vn -0.921079 0.163915 0.353099 578 | vn -0.817164 0.444594 0.366802 579 | vn -0.989776 0.006958 0.142399 580 | vn -0.944090 -0.256111 -0.207434 581 | vn -0.966552 -0.036225 -0.253792 582 | vn 0.000000 -0.942503 -0.334147 583 | vn -0.832667 -0.553575 -0.013062 584 | vn -0.504746 -0.849239 -0.154912 585 | vn -0.802087 -0.583789 -0.125706 586 | vn -0.503683 -0.844385 -0.182533 587 | vn 0.000000 -0.939311 -0.343066 588 | vn -0.987854 0.018891 -0.154149 589 | vn -0.952970 0.286913 -0.097616 590 | vn -0.889312 -0.015021 -0.457054 591 | vn -0.814624 -0.328482 -0.478003 592 | vn -0.682910 -0.670527 -0.289874 593 | vn -0.315806 0.396283 0.862087 594 | vn -0.232106 0.920937 0.313053 595 | vn 0.000000 0.312082 0.950041 596 | vn 0.000000 -0.168798 0.985626 597 | vn -0.000000 0.941854 0.336024 598 | vn -0.459609 0.770379 0.441847 599 | vn 0.000000 0.805750 0.592242 600 | vn -0.637196 0.547110 0.542819 601 | vn -0.687124 -0.664083 -0.294595 602 | vn -0.475997 -0.836573 0.271096 603 | vn -0.362712 -0.782586 -0.505875 604 | vn -0.986969 -0.041169 0.155339 605 | vn -0.903928 0.243995 0.351207 606 | vn -0.765709 0.567370 0.302866 607 | vn 0.740623 -0.538011 -0.402448 608 | vn 0.178838 0.251778 0.951109 609 | vn -0.753685 -0.173345 -0.633931 610 | vn -0.226020 -0.741539 0.631672 611 | vn -0.814844 0.338298 -0.470656 612 | vn -0.596454 0.755272 -0.271554 613 | vn 0.592334 0.750786 -0.292245 614 | vn -0.901212 -0.040468 0.431440 615 | vn -0.069369 -0.994293 0.080721 616 | vn -0.871853 -0.291421 -0.393567 617 | vn -0.871883 0.162450 0.461928 618 | vn -0.983062 -0.173284 0.059145 619 | vn 0.823054 -0.085910 -0.561388 620 | vn -0.985961 0.159978 0.047517 621 | vn -0.965606 -0.084597 0.245766 622 | vn 0.519150 -0.201361 -0.830592 623 | vn -0.835078 0.334025 -0.437086 624 | vn -0.746178 0.301492 0.593524 625 | vn -0.603412 0.677755 0.420118 626 | vn 0.783471 -0.590503 0.193426 627 | vn -0.575549 0.816523 0.045015 628 | vn 0.154942 -0.339183 -0.927854 629 | vn 0.506272 0.683920 0.525285 630 | vn 0.018372 -0.974364 -0.224128 631 | vn -0.883175 -0.053407 -0.465957 632 | vn -0.351482 -0.923643 0.152715 633 | vn -0.413160 0.861019 0.296457 634 | vn 0.473525 0.855922 -0.207709 635 | vn 0.355235 0.898099 0.259133 636 | vn 0.718223 0.695761 -0.004273 637 | vn 0.572741 0.790857 -0.215583 638 | vn 0.442793 0.558397 0.701468 639 | vn 0.940062 0.338054 0.044313 640 | vn 0.589404 0.585345 -0.556719 641 | vn 0.974914 0.219092 0.038423 642 | vn 0.619098 0.692679 -0.369945 643 | vn 0.514695 0.849910 -0.112735 644 | vn 0.551927 0.814264 0.179693 645 | vn 0.549547 0.753777 0.360240 646 | vn 0.532121 0.787866 0.309946 647 | vn 0.658742 0.752312 -0.005005 648 | vn 0.955107 0.286325 -0.075655 649 | vn 0.821070 0.556993 0.124729 650 | vn 0.754875 0.553117 0.352397 651 | vn 0.818506 0.314707 0.480575 652 | vn 0.659247 0.609488 0.440360 653 | vn 0.000000 0.677494 0.735528 654 | vn 0.041942 0.625806 0.778850 655 | vn 0.429518 0.861568 0.270547 656 | vn 0.213538 0.923643 -0.318217 657 | vn 0.123844 0.991943 0.026368 658 | vn 0.840358 0.460952 0.285134 659 | vn 0.705649 0.670278 -0.229652 660 | vn 0.599127 0.742784 -0.298863 661 | vn 0.233749 0.898954 -0.370463 662 | vn 0.917517 0.357748 0.173721 663 | vn 0.361339 0.855037 -0.371838 664 | vn 0.649068 0.743522 0.160680 665 | vn 0.459609 0.770379 0.441847 666 | vn 0.708609 0.489212 0.508438 667 | vn 0.572466 0.818232 0.051973 668 | vn 0.548021 0.827479 0.122105 669 | vn 0.578570 0.812586 0.070040 670 | vn 0.457747 0.888974 0.013611 671 | vn 0.619831 0.689383 0.374859 672 | vn 0.583148 0.119907 0.803430 673 | vn 0.654805 0.731956 0.188116 674 | vn -0.203101 0.216193 0.954985 675 | vn 0.775933 0.606494 0.173254 676 | vn 0.816065 0.493759 0.300302 677 | vn 0.931608 0.188574 0.310678 678 | vn 0.910001 0.393506 0.130375 679 | vn 0.904416 0.187841 0.383038 680 | vn 0.398419 0.912717 0.090518 681 | vn 0.811884 0.515488 -0.273995 682 | vn 0.448378 0.299600 0.842128 683 | vn 0.460738 0.802301 0.379467 684 | vn 0.580370 0.702994 -0.410993 685 | vn 0.812738 0.117679 0.570574 686 | vn 0.849300 0.438734 0.293558 687 | vn 0.454451 0.861202 -0.227515 688 | vn 0.569842 0.805689 -0.161565 689 | vn 0.401776 0.895199 -0.192755 690 | vn 0.278451 0.898618 -0.339000 691 | vn 0.254707 0.880459 0.399823 692 | vn 0.100650 0.739982 0.665029 693 | vn 0.392224 0.698935 0.597980 694 | vn 0.271358 0.651367 0.708580 695 | vn 0.422132 0.704581 -0.570360 696 | vn 0.442366 0.765557 -0.467116 697 | vn 0.566698 0.575549 -0.589526 698 | vn 0.661794 0.593951 -0.457350 699 | vn 0.796258 0.603473 -0.041810 700 | vn 0.710074 0.692892 0.125065 701 | vn 0.582415 0.674093 0.454237 702 | vn 0.892209 0.415265 -0.177435 703 | vn 0.420759 0.873928 -0.243294 704 | vn 0.384167 0.912931 0.137608 705 | vn -0.191582 0.678733 -0.708955 706 | vn 0.275713 0.787007 -0.551909 707 | vn -0.015319 0.835306 0.549572 708 | vn 0.247289 0.617698 0.746524 709 | vn 0.729039 0.624819 -0.279469 710 | vn 0.621982 0.762640 -0.177535 711 | vn -0.892121 0.396454 -0.216665 712 | vn 0.637196 0.547110 0.542819 713 | vn 0.621774 0.566946 0.540342 714 | vn 0.419416 0.279061 0.863826 715 | vn 0.441755 0.879330 0.177709 716 | vn -0.032136 -0.005463 0.999451 717 | vn 0.741264 0.146855 0.654927 718 | vn 0.818995 0.190863 0.541063 719 | vn -0.764916 0.211890 0.608234 720 | vn -0.251808 -0.135075 0.958281 721 | vn 0.236518 -0.346782 0.907590 722 | vn 0.044435 0.979400 0.196844 723 | vn -0.353465 0.810846 0.466384 724 | vn 0.412946 0.905423 0.098239 725 | vn 0.855312 0.187964 0.482742 726 | vn 0.998291 0.049959 -0.029908 727 | vn 0.766717 0.574633 0.286233 728 | vn 0.590564 0.769189 0.243965 729 | vn 0.445387 0.848384 0.286081 730 | vn 0.666923 0.153829 -0.729075 731 | vn 0.565813 0.730522 0.382305 732 | vn 0.588031 0.796838 0.138676 733 | vn 0.774773 0.475070 0.417174 734 | vn 0.737175 0.455000 0.499496 735 | vn 0.946928 -0.004944 0.321299 736 | vn 0.327647 -0.158635 0.931364 737 | vn 0.921079 0.163915 0.353099 738 | vn 0.983856 0.048830 0.172124 739 | vn 0.982177 0.055971 0.179266 740 | vn 0.986206 0.165410 0.003113 741 | vn 0.938505 0.274392 -0.209387 742 | vn 0.710776 0.604144 -0.360210 743 | vn 0.374889 0.813166 -0.445143 744 | vn 0.972015 0.163518 -0.168584 745 | vn 0.913358 0.195929 -0.356883 746 | vn 0.680441 0.285165 -0.675008 747 | vn 0.373821 0.363598 -0.853236 748 | vn 0.987274 0.064394 0.145268 749 | vn 0.304544 -0.349590 -0.886013 750 | vn 0.629017 -0.255165 -0.734275 751 | vn 0.882168 -0.201880 -0.425428 752 | vn 0.967864 -0.163518 -0.190893 753 | vn 0.976959 -0.122593 0.174566 754 | vn 0.487655 -0.768822 -0.413587 755 | vn 0.625446 -0.728965 -0.278176 756 | vn 0.815699 -0.568011 -0.109287 757 | vn 0.940428 -0.339885 0.005554 758 | vn 0.978210 -0.146184 0.147374 759 | vn 0.309915 -0.930113 0.196997 760 | vn 0.611866 -0.777337 0.146092 761 | vn 0.761925 -0.615131 0.202582 762 | vn 0.861873 -0.463637 0.205390 763 | vn 0.935881 -0.268441 0.228095 764 | vn 0.397320 -0.907956 0.133091 765 | vn 0.696524 -0.694357 0.180853 766 | vn 0.833644 -0.522782 0.178076 767 | vn 0.880856 -0.358745 0.308817 768 | vn 0.937040 -0.189398 0.293283 769 | vn 0.522385 -0.848292 -0.086459 770 | vn 0.832667 -0.553575 -0.013062 771 | vn 0.979583 -0.182073 0.084933 772 | vn 0.989776 0.006958 0.142399 773 | vn 0.976897 -0.034791 0.210822 774 | vn 0.315806 0.396283 0.862087 775 | vn 0.817164 0.444594 0.366802 776 | vn 0.966552 -0.036225 -0.253792 777 | vn 0.944090 -0.256111 -0.207434 778 | vn 0.987854 0.018891 -0.154149 779 | vn 0.504746 -0.849239 -0.154912 780 | vn 0.802087 -0.583789 -0.125706 781 | vn 0.682910 -0.670528 -0.289874 782 | vn 0.503683 -0.844385 -0.182533 783 | vn 0.590861 0.722902 0.358184 784 | vn 0.952970 0.286913 -0.097616 785 | vn 0.889312 -0.015021 -0.457054 786 | vn 0.814624 -0.328482 -0.478003 787 | vn 0.232106 0.920937 0.313053 788 | vn 0.649129 0.755730 0.086428 789 | vn 0.388226 0.909635 0.147649 790 | vn 0.591357 0.712333 0.377911 791 | vn 0.687155 -0.664083 -0.294595 792 | vn 0.362712 -0.782586 -0.505875 793 | vn 0.475997 -0.836573 0.271096 794 | vn 0.986969 -0.041169 0.155339 795 | vn 0.983062 -0.173284 0.059145 796 | vn 0.765709 0.567370 0.302866 797 | vn -0.740623 -0.538011 -0.402448 798 | vn -0.178838 0.251778 0.951109 799 | vn 0.753685 -0.173315 -0.633931 800 | vn -0.519150 -0.201361 -0.830592 801 | vn 0.226020 -0.741539 0.631672 802 | vn -0.592334 0.750786 -0.292245 803 | vn 0.814844 0.338298 -0.470656 804 | vn 0.596454 0.755272 -0.271554 805 | vn 0.903928 0.243995 0.351207 806 | vn 0.069369 -0.994293 0.080721 807 | vn 0.901212 -0.040468 0.431440 808 | vn 0.871853 -0.291421 -0.393567 809 | vn 0.871883 0.162450 0.461928 810 | vn 0.985961 0.159978 0.047517 811 | vn 0.965606 -0.084597 0.245766 812 | vn 0.835078 0.334025 -0.437086 813 | vn 0.746178 0.301492 0.593524 814 | vn -0.823054 -0.085910 -0.561388 815 | vn -0.018372 -0.974364 -0.224128 816 | vn -0.783471 -0.590503 0.193426 817 | vn 0.575549 0.816523 0.045015 818 | vn 0.413160 0.861019 0.296457 819 | vn -0.506302 0.683920 0.525254 820 | vn 0.603412 0.677755 0.420118 821 | vn -0.154942 -0.339183 -0.927854 822 | vn 0.883175 -0.053407 -0.465957 823 | vn 0.351482 -0.923643 0.152715 824 | vn 0.000000 0.838476 -0.544938 825 | vn -0.774774 0.475070 0.417174 826 | vn 0.892121 0.396454 -0.216665 827 | vn -0.729039 0.624819 -0.279469 828 | vn -0.590861 0.722902 0.358184 829 | usemtl Material 830 | s 1 831 | f 204//1 9//2 4//3 832 | f 145//4 141//5 77//6 833 | f 191//7 3//8 6//9 834 | f 37//10 35//11 10//12 835 | f 148//13 10//12 147//14 836 | f 240//15 36//16 204//1 837 | f 6//9 27//17 38//18 838 | f 30//19 1//20 27//17 839 | f 156//21 140//22 11//23 840 | f 149//24 11//23 150//25 841 | f 206//26 12//27 16//28 842 | f 143//29 363//30 13//31 843 | f 366//32 142//33 206//26 844 | f 146//34 143//29 82//35 845 | f 82//35 13//31 83//36 846 | f 13//31 208//37 17//38 847 | f 77//6 14//39 76//40 848 | f 80//41 64//42 21//43 849 | f 155//44 63//45 151//46 850 | f 62//47 270//48 22//49 851 | f 74//50 70//51 67//52 852 | f 86//53 62//47 22//49 853 | f 75//54 8//55 79//56 854 | f 147//14 2//57 152//58 855 | f 5//59 196//60 24//61 856 | f 193//62 4//3 23//63 857 | f 81//64 5//59 24//61 858 | f 9//2 29//65 4//3 859 | f 29//65 9//2 40//66 860 | f 3//8 30//19 27//17 861 | f 142//33 144//67 31//68 862 | f 12//27 31//68 32//69 863 | f 69//70 68//71 57//72 864 | f 4//3 28//73 34//74 865 | f 7//75 1//20 35//11 866 | f 198//76 6//9 240//15 867 | f 148//13 29//65 153//77 868 | f 9//2 36//16 40//66 869 | f 7//75 37//10 39//78 870 | f 37//10 10//12 45//79 871 | f 36//16 6//9 44//80 872 | f 27//17 7//75 42//81 873 | f 38//18 42//81 50//82 874 | f 40//66 44//80 48//83 875 | f 43//84 40//66 48//83 876 | f 39//78 45//79 53//85 877 | f 44//80 38//18 46//86 878 | f 153//77 43//84 51//87 879 | f 42//81 39//78 50//82 880 | f 45//79 41//88 49//89 881 | f 273//90 66//91 54//92 882 | f 66//91 67//52 56//93 883 | f 71//94 54//92 73//95 884 | f 280//96 69//70 260//97 885 | f 71//94 276//98 258//99 886 | f 72//100 73//95 60//101 887 | f 33//102 20//103 59//104 888 | f 54//92 56//93 61//105 889 | f 70//51 33//102 59//104 890 | f 79//56 26//106 80//41 891 | f 152//58 25//107 63//45 892 | f 24//61 228//108 62//47 893 | f 68//71 74//50 67//52 894 | f 85//109 24//61 86//53 895 | f 260//97 55//110 66//91 896 | f 55//110 57//72 67//52 897 | f 65//111 33//102 70//51 898 | f 23//63 34//74 68//71 899 | f 20//103 71//94 58//112 900 | f 225//113 23//63 69//70 901 | f 20//103 222//114 276//98 902 | f 59//104 58//112 73//95 903 | f 56//93 70//51 72//100 904 | f 34//74 65//111 74//50 905 | f 140//22 145//4 77//6 906 | f 11//23 77//6 15//115 907 | f 63//45 80//41 19//116 908 | f 2//57 75//54 25//107 909 | f 25//107 79//56 63//45 910 | f 141//5 146//34 82//35 911 | f 14//39 82//35 83//36 912 | f 64//42 86//53 84//117 913 | f 8//55 81//64 85//109 914 | f 26//106 85//109 86//53 915 | f 8//55 75//54 89//118 916 | f 5//59 81//64 88//119 917 | f 81//64 8//55 89//118 918 | f 90//120 35//11 94//121 919 | f 75//54 2//57 90//120 920 | f 35//11 1//20 87//122 921 | f 30//19 3//8 93//123 922 | f 1//20 30//19 93//123 923 | f 3//8 191//7 92//124 924 | f 94//121 87//122 96//125 925 | f 93//123 92//124 98//126 926 | f 87//122 93//123 96//125 927 | f 92//124 301//127 97//128 928 | f 95//129 94//121 99//130 929 | f 97//128 307//131 102//132 930 | f 98//126 97//128 103//133 931 | f 96//125 98//126 101//134 932 | f 99//130 96//125 104//135 933 | f 100//136 99//130 104//135 934 | f 102//132 313//137 107//138 935 | f 103//133 102//132 108//139 936 | f 101//134 103//133 106//140 937 | f 104//135 101//134 109//141 938 | f 105//142 104//135 110//143 939 | f 107//138 319//144 112//145 940 | f 108//139 107//138 113//146 941 | f 106//140 108//139 111//147 942 | f 109//141 106//140 114//148 943 | f 110//143 109//141 115//149 944 | f 112//145 325//150 117//151 945 | f 113//146 112//145 118//152 946 | f 111//147 113//146 116//153 947 | f 114//148 111//147 119//154 948 | f 115//149 114//148 120//155 949 | f 117//151 331//156 337//157 950 | f 118//152 117//151 122//158 951 | f 116//153 118//152 121//159 952 | f 119//154 116//153 121//159 953 | f 120//155 119//154 125//160 954 | f 88//119 91//161 127//162 955 | f 125//160 91//161 120//155 956 | f 124//163 121//159 128//164 957 | f 125//160 124//163 131//165 958 | f 122//158 337//157 345//166 959 | f 123//167 122//158 129//168 960 | f 121//159 123//167 130//169 961 | f 130//169 129//168 136//170 962 | f 129//168 345//166 353//171 963 | f 127//162 132//172 139//173 964 | f 132//172 131//165 138//174 965 | f 131//165 128//164 135//175 966 | f 128//164 130//169 137//176 967 | f 126//177 127//162 133//178 968 | f 91//161 125//160 132//172 969 | f 5//59 88//119 196//60 970 | f 126//177 359//179 358//180 971 | f 133//178 360//181 126//177 972 | f 78//182 21//43 141//5 973 | f 151//46 19//116 140//22 974 | f 22//49 220//183 363//30 975 | f 222//114 20//103 366//32 976 | f 84//117 22//49 143//29 977 | f 20//103 33//102 144//67 978 | f 19//116 78//182 145//4 979 | f 21//43 84//117 146//34 980 | f 29//65 148//13 28//73 981 | f 144//67 156//21 149//24 982 | f 31//68 149//24 150//25 983 | f 65//111 155//44 33//102 984 | f 28//73 147//14 34//74 985 | f 10//12 148//13 153//77 986 | f 41//88 153//77 154//184 987 | f 34//74 152//58 65//111 988 | f 33//102 151//46 156//21 989 | f 175//185 174//186 162//187 990 | f 177//188 176//189 159//190 991 | f 178//191 177//188 157//192 992 | f 179//193 175//185 162//187 993 | f 180//194 178//191 157//192 994 | f 181//195 179//193 160//196 995 | f 176//189 181//195 160//196 996 | f 174//186 180//194 164//197 997 | f 159//190 160//196 165//198 998 | f 162//187 163//199 167//200 999 | f 164//197 157//192 170//201 1000 | f 158//202 171//203 169//204 1001 | f 159//190 165//198 158//202 1002 | f 164//197 170//201 168//205 1003 | f 161//206 172//207 160//196 1004 | f 172//207 161//206 167//200 1005 | f 166//208 172//207 165//198 1006 | f 168//205 173//209 172//207 1007 | f 169//204 173//209 168//205 1008 | f 171//203 165//198 182//210 1009 | f 110//143 115//149 174//186 1010 | f 90//120 95//129 176//189 1011 | f 89//118 90//120 177//188 1012 | f 105//142 110//143 179//193 1013 | f 120//155 89//118 180//194 1014 | f 100//136 105//142 181//195 1015 | f 95//129 100//136 176//189 1016 | f 115//149 120//155 174//186 1017 | f 185//211 183//212 187//213 1018 | f 165//198 173//209 185//211 1019 | f 173//209 169//204 185//211 1020 | f 169//204 171//203 184//214 1021 | f 188//215 186//216 189//217 1022 | f 183//212 184//214 187//213 1023 | f 184//214 182//210 188//215 1024 | f 182//210 185//211 186//216 1025 | f 204//1 193//62 195//218 1026 | f 368//219 286//220 362//221 1027 | f 191//7 198//76 199//222 1028 | f 239//223 203//224 237//225 1029 | f 371//226 370//227 203//224 1030 | f 240//15 204//1 238//228 1031 | f 199//222 241//229 229//230 1032 | f 232//231 229//230 190//232 1033 | f 379//233 372//234 205//235 1034 | f 372//234 373//236 205//235 1035 | f 206//26 212//237 213//238 1036 | f 365//239 209//240 363//30 1037 | f 366//32 206//26 364//241 1038 | f 369//242 291//243 365//239 1039 | f 291//243 292//244 209//240 1040 | f 209//240 215//245 208//37 1041 | f 286//220 285//246 210//247 1042 | f 289//248 287//249 219//250 1043 | f 378//251 374//252 268//253 1044 | f 267//254 221//255 270//48 1045 | f 283//256 274//257 278//258 1046 | f 295//259 293//260 221//255 1047 | f 284//261 288//262 201//263 1048 | f 370//227 375//264 192//265 1049 | f 197//266 224//267 196//60 1050 | f 193//62 225//113 223//268 1051 | f 290//269 294//270 224//267 1052 | f 202//271 195//218 231//272 1053 | f 231//272 246//273 243//274 1054 | f 194//275 199//222 229//230 1055 | f 364//241 207//276 233//277 1056 | f 207//276 213//238 234//278 1057 | f 277//279 259//280 262//281 1058 | f 195//218 223//268 236//282 1059 | f 200//283 239//223 237//225 1060 | f 198//76 240//15 199//222 1061 | f 371//226 376//284 231//272 1062 | f 202//271 243//274 238//228 1063 | f 200//283 242//285 239//223 1064 | f 239//223 248//286 203//224 1065 | f 238//228 247//287 199//222 1066 | f 229//230 245//288 200//283 1067 | f 241//229 249//289 253//290 1068 | f 243//274 251//291 247//287 1069 | f 246//273 254//292 251//291 1070 | f 242//285 250//293 256//294 1071 | f 247//287 255//295 249//289 1072 | f 376//284 377//296 254//292 1073 | f 245//288 253//290 242//285 1074 | f 248//286 256//294 252//297 1075 | f 273//90 258//99 257//298 1076 | f 272//299 257//298 261//300 1077 | f 279//301 282//302 257//298 1078 | f 280//96 260//97 277//279 1079 | f 279//301 257//298 258//99 1080 | f 281//303 266//304 265//305 1081 | f 235//306 264//307 218//308 1082 | f 257//298 265//305 266//304 1083 | f 278//258 281//303 264//307 1084 | f 288//262 289//248 227//309 1085 | f 375//264 378//251 268//253 1086 | f 224//267 267//254 228//108 1087 | f 275//310 262//281 274//257 1088 | f 294//270 295//259 224//267 1089 | f 260//97 273//90 272//299 1090 | f 259//280 272//299 274//257 1091 | f 271//311 283//256 278//258 1092 | f 223//268 277//279 275//310 1093 | f 218//308 263//312 279//301 1094 | f 225//113 280//96 277//279 1095 | f 218//308 279//301 276//98 1096 | f 264//307 281//303 282//302 1097 | f 261//300 266//304 281//303 1098 | f 236//282 275//310 283//256 1099 | f 361//313 205//235 286//220 1100 | f 205//235 211//314 286//220 1101 | f 268//253 217//315 289//248 1102 | f 192//265 226//316 284//261 1103 | f 226//316 268//253 288//262 1104 | f 362//221 210//247 291//243 1105 | f 210//247 216//317 292//244 1106 | f 269//318 219//250 293//260 1107 | f 201//263 227//309 294//270 1108 | f 227//309 269//318 295//259 1109 | f 201//263 298//319 284//261 1110 | f 197//266 297//320 290//269 1111 | f 290//269 300//321 298//319 1112 | f 299//322 305//323 304//324 1113 | f 284//261 299//322 192//265 1114 | f 237//225 304//324 296//325 1115 | f 232//231 303//326 194//275 1116 | f 190//232 296//325 303//326 1117 | f 194//275 302//327 191//7 1118 | f 304//324 310//328 306//329 1119 | f 303//326 309//330 302//327 1120 | f 296//325 306//329 303//326 1121 | f 302//327 308//331 301//127 1122 | f 305//323 311//332 310//328 1123 | f 308//331 314//333 307//131 1124 | f 309//330 315//334 308//331 1125 | f 306//329 312//335 309//330 1126 | f 310//328 316//336 306//329 1127 | f 311//332 317//337 316//336 1128 | f 314//333 320//338 313//137 1129 | f 315//334 321//339 314//333 1130 | f 312//335 318//340 315//334 1131 | f 316//336 322//341 312//335 1132 | f 317//337 323//342 316//336 1133 | f 320//338 326//343 319//144 1134 | f 321//339 327//344 320//338 1135 | f 318//340 324//345 321//339 1136 | f 322//341 328//346 318//340 1137 | f 323//342 329//347 322//341 1138 | f 326//343 332//348 325//150 1139 | f 327//344 333//349 326//343 1140 | f 324//345 330//350 327//344 1141 | f 328//346 334//351 324//345 1142 | f 329//347 335//352 328//346 1143 | f 332//348 338//353 337//157 1144 | f 333//349 339//354 338//353 1145 | f 330//350 336//355 333//349 1146 | f 334//351 340//356 336//355 1147 | f 335//352 341//357 334//351 1148 | f 297//320 342//358 343//359 1149 | f 341//357 335//352 300//321 1150 | f 340//356 348//360 344//361 1151 | f 341//357 349//362 348//360 1152 | f 338//353 346//363 345//166 1153 | f 339//354 347//364 346//363 1154 | f 336//355 344//361 347//364 1155 | f 347//364 355//365 354//366 1156 | f 346//363 354//366 353//171 1157 | f 343//359 351//367 357//368 1158 | f 349//362 357//368 356//369 1159 | f 348//360 356//369 352//370 1160 | f 344//361 352//370 355//365 1161 | f 342//358 350//371 343//359 1162 | f 300//321 343//359 349//362 1163 | f 197//266 196//60 297//320 1164 | f 342//358 297//320 358//180 1165 | f 350//371 342//358 360//181 1166 | f 287//249 368//219 362//221 1167 | f 374//252 379//233 361//313 1168 | f 221//255 365//239 363//30 1169 | f 222//114 366//32 218//308 1170 | f 293//260 369//242 365//239 1171 | f 218//308 364//241 367//372 1172 | f 217//315 361//313 368//219 1173 | f 219//250 362//221 369//242 1174 | f 231//272 230//373 371//226 1175 | f 367//372 233//277 372//234 1176 | f 233//277 234//278 373//236 1177 | f 271//311 235//306 378//251 1178 | f 230//373 236//282 370//227 1179 | f 203//224 244//374 376//284 1180 | f 244//374 252//297 377//296 1181 | f 236//282 271//311 375//264 1182 | f 235//306 367//372 379//233 1183 | f 398//375 385//376 397//377 1184 | f 400//378 381//379 382//380 1185 | f 401//381 380//382 400//378 1186 | f 402//383 384//384 385//376 1187 | f 403//385 387//386 380//382 1188 | f 404//387 383//388 402//383 1189 | f 399//389 382//380 383//388 1190 | f 397//377 386//390 387//386 1191 | f 382//380 388//391 383//388 1192 | f 385//376 390//392 386//390 1193 | f 387//386 393//393 380//382 1194 | f 381//379 380//382 392//394 1195 | f 382//380 381//379 388//391 1196 | f 387//386 386//390 391//395 1197 | f 384//384 383//388 395//396 1198 | f 395//396 390//392 384//384 1199 | f 389//397 388//391 395//396 1200 | f 391//395 390//392 395//396 1201 | f 392//394 393//393 391//395 1202 | f 394//398 407//399 405//400 1203 | f 323//342 398//375 397//377 1204 | f 299//322 400//378 399//389 1205 | f 298//319 401//381 400//378 1206 | f 317//337 402//383 323//342 1207 | f 335//352 403//385 298//319 1208 | f 311//332 404//387 317//337 1209 | f 305//323 399//389 311//332 1210 | f 329//347 397//377 335//352 1211 | f 408//401 412//402 410//403 1212 | f 388//391 405//400 408//401 1213 | f 396//404 408//401 392//394 1214 | f 392//394 406//405 407//399 1215 | f 411//406 410//403 412//402 1216 | f 406//405 410//403 407//399 1217 | f 407//399 411//406 405//400 1218 | f 405//400 409//407 408//401 1219 | f 193//62 204//1 4//3 1220 | f 141//5 14//39 77//6 1221 | f 198//76 191//7 6//9 1222 | f 35//11 2//57 10//12 1223 | f 10//12 2//57 147//14 1224 | f 36//16 9//2 204//1 1225 | f 27//17 42//81 38//18 1226 | f 1//20 7//75 27//17 1227 | f 149//24 156//21 11//23 1228 | f 11//23 15//115 150//25 1229 | f 212//237 206//26 16//28 1230 | f 363//30 208//37 13//31 1231 | f 142//33 12//27 206//26 1232 | f 143//29 13//31 82//35 1233 | f 13//31 17//38 83//36 1234 | f 208//37 214//408 17//38 1235 | f 14//39 18//409 76//40 1236 | f 78//182 80//41 21//43 1237 | f 63//45 19//116 151//46 1238 | f 270//48 220//183 22//49 1239 | f 70//51 56//93 67//52 1240 | f 84//117 86//53 22//49 1241 | f 8//55 26//106 79//56 1242 | f 2//57 25//107 152//58 1243 | f 196//60 228//108 24//61 1244 | f 225//113 193//62 23//63 1245 | f 85//109 81//64 24//61 1246 | f 29//65 28//73 4//3 1247 | f 43//84 29//65 40//66 1248 | f 6//9 3//8 27//17 1249 | f 12//27 142//33 31//68 1250 | f 16//28 12//27 32//69 1251 | f 55//110 69//70 57//72 1252 | f 23//63 4//3 34//74 1253 | f 37//10 7//75 35//11 1254 | f 6//9 36//16 240//15 1255 | f 29//65 43//84 153//77 1256 | f 36//16 44//80 40//66 1257 | f 37//10 45//79 39//78 1258 | f 10//12 41//88 45//79 1259 | f 6//9 38//18 44//80 1260 | f 7//75 39//78 42//81 1261 | f 46//86 38//18 50//82 1262 | f 44//80 52//410 48//83 1263 | f 51//87 43//84 48//83 1264 | f 47//411 39//78 53//85 1265 | f 52//410 44//80 46//86 1266 | f 154//184 153//77 51//87 1267 | f 39//78 47//411 50//82 1268 | f 53//85 45//79 49//89 1269 | f 258//99 273//90 54//92 1270 | f 54//92 66//91 56//93 1271 | f 54//92 60//101 73//95 1272 | f 69//70 55//110 260//97 1273 | f 54//92 71//94 258//99 1274 | f 61//105 72//100 60//101 1275 | f 20//103 58//112 59//104 1276 | f 60//101 54//92 61//105 1277 | f 72//100 70//51 59//104 1278 | f 26//106 64//42 80//41 1279 | f 155//44 152//58 63//45 1280 | f 228//108 270//48 62//47 1281 | f 57//72 68//71 67//52 1282 | f 24//61 62//47 86//53 1283 | f 273//90 260//97 66//91 1284 | f 66//91 55//110 67//52 1285 | f 74//50 65//111 70//51 1286 | f 69//70 23//63 68//71 1287 | f 71//94 73//95 58//112 1288 | f 280//96 225//113 69//70 1289 | f 71//94 20//103 276//98 1290 | f 72//100 59//104 73//95 1291 | f 61//105 56//93 72//100 1292 | f 68//71 34//74 74//50 1293 | f 11//23 140//22 77//6 1294 | f 77//6 76//40 15//115 1295 | f 80//41 78//182 19//116 1296 | f 75//54 79//56 25//107 1297 | f 79//56 80//41 63//45 1298 | f 14//39 141//5 82//35 1299 | f 18//409 14//39 83//36 1300 | f 21//43 64//42 84//117 1301 | f 26//106 8//55 85//109 1302 | f 64//42 26//106 86//53 1303 | f 75//54 90//120 89//118 1304 | f 81//64 91//161 88//119 1305 | f 91//161 81//64 89//118 1306 | f 95//129 90//120 94//121 1307 | f 2//57 35//11 90//120 1308 | f 94//121 35//11 87//122 1309 | f 3//8 92//124 93//123 1310 | f 87//122 1//20 93//123 1311 | f 191//7 301//127 92//124 1312 | f 99//130 94//121 96//125 1313 | f 92//124 97//128 98//126 1314 | f 93//123 98//126 96//125 1315 | f 301//127 307//131 97//128 1316 | f 100//136 95//129 99//130 1317 | f 307//131 313//137 102//132 1318 | f 97//128 102//132 103//133 1319 | f 98//126 103//133 101//134 1320 | f 96//125 101//134 104//135 1321 | f 105//142 100//136 104//135 1322 | f 313//137 319//144 107//138 1323 | f 102//132 107//138 108//139 1324 | f 103//133 108//139 106//140 1325 | f 101//134 106//140 109//141 1326 | f 104//135 109//141 110//143 1327 | f 319//144 325//150 112//145 1328 | f 107//138 112//145 113//146 1329 | f 108//139 113//146 111//147 1330 | f 106//140 111//147 114//148 1331 | f 109//141 114//148 115//149 1332 | f 325//150 331//156 117//151 1333 | f 112//145 117//151 118//152 1334 | f 113//146 118//152 116//153 1335 | f 111//147 116//153 119//154 1336 | f 114//148 119//154 120//155 1337 | f 122//158 117//151 337//157 1338 | f 123//167 118//152 122//158 1339 | f 118//152 123//167 121//159 1340 | f 124//163 119//154 121//159 1341 | f 119//154 124//163 125//160 1342 | f 126//177 88//119 127//162 1343 | f 91//161 89//118 120//155 1344 | f 131//165 124//163 128//164 1345 | f 132//172 125//160 131//165 1346 | f 129//168 122//158 345//166 1347 | f 130//169 123//167 129//168 1348 | f 128//164 121//159 130//169 1349 | f 137//176 130//169 136//170 1350 | f 136//170 129//168 353//171 1351 | f 134//412 127//162 139//173 1352 | f 139//173 132//172 138//174 1353 | f 138//174 131//165 135//175 1354 | f 135//175 128//164 137//176 1355 | f 127//162 134//412 133//178 1356 | f 127//162 91//161 132//172 1357 | f 88//119 358//180 196//60 1358 | f 88//119 126//177 358//180 1359 | f 360//181 359//179 126//177 1360 | f 145//4 78//182 141//5 1361 | f 156//21 151//46 140//22 1362 | f 143//29 22//49 363//30 1363 | f 20//103 142//33 366//32 1364 | f 146//34 84//117 143//29 1365 | f 142//33 20//103 144//67 1366 | f 140//22 19//116 145//4 1367 | f 141//5 21//43 146//34 1368 | f 148//13 147//14 28//73 1369 | f 31//68 144//67 149//24 1370 | f 32//69 31//68 150//25 1371 | f 155//44 151//46 33//102 1372 | f 147//14 152//58 34//74 1373 | f 41//88 10//12 153//77 1374 | f 49//89 41//88 154//184 1375 | f 152//58 155//44 65//111 1376 | f 144//67 33//102 156//21 1377 | f 174//186 163//199 162//187 1378 | f 158//202 177//188 159//190 1379 | f 177//188 158//202 157//192 1380 | f 161//206 179//193 162//187 1381 | f 164//197 180//194 157//192 1382 | f 179//193 161//206 160//196 1383 | f 159//190 176//189 160//196 1384 | f 163//199 174//186 164//197 1385 | f 160//196 166//208 165//198 1386 | f 163//199 168//205 167//200 1387 | f 157//192 169//204 170//201 1388 | f 157//192 158//202 169//204 1389 | f 165//198 171//203 158//202 1390 | f 163//199 164//197 168//205 1391 | f 172//207 166//208 160//196 1392 | f 161//206 162//187 167//200 1393 | f 172//207 173//209 165//198 1394 | f 167//200 168//205 172//207 1395 | f 170//201 169//204 168//205 1396 | f 184//214 171//203 182//210 1397 | f 175//185 110//143 174//186 1398 | f 177//188 90//120 176//189 1399 | f 178//191 89//118 177//188 1400 | f 110//143 175//185 179//193 1401 | f 89//118 178//191 180//194 1402 | f 105//142 179//193 181//195 1403 | f 100//136 181//195 176//189 1404 | f 120//155 180//194 174//186 1405 | f 189//217 185//211 187//213 1406 | f 182//210 165//198 185//211 1407 | f 169//204 183//212 185//211 1408 | f 183//212 169//204 184//214 1409 | f 187//213 188//215 189//217 1410 | f 184//214 188//215 187//213 1411 | f 182//210 186//216 188//215 1412 | f 185//211 189//217 186//216 1413 | f 202//271 204//1 195//218 1414 | f 286//220 210//247 362//221 1415 | f 194//275 191//7 199//222 1416 | f 203//224 192//265 237//225 1417 | f 370//227 192//265 203//224 1418 | f 204//1 202//271 238//228 1419 | f 241//229 245//288 229//230 1420 | f 229//230 200//283 190//232 1421 | f 361//313 379//233 205//235 1422 | f 373//236 211//314 205//235 1423 | f 207//276 206//26 213//238 1424 | f 209//240 208//37 363//30 1425 | f 206//26 207//276 364//241 1426 | f 291//243 209//240 365//239 1427 | f 292//244 215//245 209//240 1428 | f 215//245 214//408 208//37 1429 | f 285//246 216//317 210//247 1430 | f 269//318 289//248 219//250 1431 | f 374//252 217//315 268//253 1432 | f 221//255 220//183 270//48 1433 | f 274//257 261//300 278//258 1434 | f 267//254 295//259 221//255 1435 | f 288//262 227//309 201//263 1436 | f 375//264 226//316 192//265 1437 | f 224//267 228//108 196//60 1438 | f 195//218 193//62 223//268 1439 | f 197//266 290//269 224//267 1440 | f 195//218 230//373 231//272 1441 | f 202//271 231//272 243//274 1442 | f 232//231 194//275 229//230 1443 | f 367//372 364//241 233//277 1444 | f 233//277 207//276 234//278 1445 | f 275//310 277//279 262//281 1446 | f 230//373 195//218 236//282 1447 | f 190//232 200//283 237//225 1448 | f 240//15 238//228 199//222 1449 | f 376//284 246//273 231//272 1450 | f 243//274 247//287 238//228 1451 | f 242//285 248//286 239//223 1452 | f 248//286 244//374 203//224 1453 | f 247//287 241//229 199//222 1454 | f 245//288 242//285 200//283 1455 | f 245//288 241//229 253//290 1456 | f 251//291 255//295 247//287 1457 | f 243//274 246//273 251//291 1458 | f 248//286 242//285 256//294 1459 | f 241//229 247//287 249//289 1460 | f 246//273 376//284 254//292 1461 | f 253//290 250//293 242//285 1462 | f 244//374 248//286 252//297 1463 | f 272//299 273//90 257//298 1464 | f 274//257 272//299 261//300 1465 | f 282//302 265//305 257//298 1466 | f 260//97 259//280 277//279 1467 | f 276//98 279//301 258//99 1468 | f 282//302 281//303 265//305 1469 | f 264//307 263//312 218//308 1470 | f 261//300 257//298 266//304 1471 | f 235//306 278//258 264//307 1472 | f 289//248 269//318 227//309 1473 | f 226//316 375//264 268//253 1474 | f 267//254 270//48 228//108 1475 | f 283//256 275//310 274//257 1476 | f 295//259 267//254 224//267 1477 | f 259//280 260//97 272//299 1478 | f 262//281 259//280 274//257 1479 | f 235//306 271//311 278//258 1480 | f 236//282 223//268 275//310 1481 | f 263//312 282//302 279//301 1482 | f 223//268 225//113 277//279 1483 | f 222//114 218//308 276//98 1484 | f 263//312 264//307 282//302 1485 | f 278//258 261//300 281//303 1486 | f 271//311 236//282 283//256 1487 | f 368//219 361//313 286//220 1488 | f 211//314 285//246 286//220 1489 | f 217//315 287//249 289//248 1490 | f 226//316 288//262 284//261 1491 | f 268//253 289//248 288//262 1492 | f 369//242 362//221 291//243 1493 | f 291//243 210//247 292//244 1494 | f 295//259 269//318 293//260 1495 | f 290//269 201//263 294//270 1496 | f 294//270 227//309 295//259 1497 | f 298//319 299//322 284//261 1498 | f 297//320 300//321 290//269 1499 | f 201//263 290//269 298//319 1500 | f 237//225 299//322 304//324 1501 | f 299//322 237//225 192//265 1502 | f 190//232 237//225 296//325 1503 | f 303//326 302//327 194//275 1504 | f 232//231 190//232 303//326 1505 | f 302//327 301//127 191//7 1506 | f 296//325 304//324 306//329 1507 | f 309//330 308//331 302//327 1508 | f 306//329 309//330 303//326 1509 | f 308//331 307//131 301//127 1510 | f 304//324 305//323 310//328 1511 | f 314//333 313//137 307//131 1512 | f 315//334 314//333 308//331 1513 | f 312//335 315//334 309//330 1514 | f 316//336 312//335 306//329 1515 | f 310//328 311//332 316//336 1516 | f 320//338 319//144 313//137 1517 | f 321//339 320//338 314//333 1518 | f 318//340 321//339 315//334 1519 | f 322//341 318//340 312//335 1520 | f 323//342 322//341 316//336 1521 | f 326//343 325//150 319//144 1522 | f 327//344 326//343 320//338 1523 | f 324//345 327//344 321//339 1524 | f 328//346 324//345 318//340 1525 | f 329//347 328//346 322//341 1526 | f 332//348 331//156 325//150 1527 | f 333//349 332//348 326//343 1528 | f 330//350 333//349 327//344 1529 | f 334//351 330//350 324//345 1530 | f 335//352 334//351 328//346 1531 | f 331//156 332//348 337//157 1532 | f 332//348 333//349 338//353 1533 | f 336//355 339//354 333//349 1534 | f 330//350 334//351 336//355 1535 | f 341//357 340//356 334//351 1536 | f 300//321 297//320 343//359 1537 | f 335//352 298//319 300//321 1538 | f 336//355 340//356 344//361 1539 | f 340//356 341//357 348//360 1540 | f 337//157 338//353 345//166 1541 | f 338//353 339//354 346//363 1542 | f 339//354 336//355 347//364 1543 | f 346//363 347//364 354//366 1544 | f 345//166 346//363 353//171 1545 | f 349//362 343//359 357//368 1546 | f 348//360 349//362 356//369 1547 | f 344//361 348//360 352//370 1548 | f 347//364 344//361 355//365 1549 | f 350//371 351//367 343//359 1550 | f 341//357 300//321 349//362 1551 | f 196//60 358//180 297//320 1552 | f 359//179 342//358 358//180 1553 | f 342//358 359//179 360//181 1554 | f 219//250 287//249 362//221 1555 | f 217//315 374//252 361//313 1556 | f 220//183 221//255 363//30 1557 | f 366//32 364//241 218//308 1558 | f 221//255 293//260 365//239 1559 | f 235//306 218//308 367//372 1560 | f 287//249 217//315 368//219 1561 | f 293//260 219//250 369//242 1562 | f 230//373 370//227 371//226 1563 | f 379//233 367//372 372//234 1564 | f 372//234 233//277 373//236 1565 | f 235//306 374//252 378//251 1566 | f 236//282 375//264 370//227 1567 | f 371//226 203//224 376//284 1568 | f 376//284 244//374 377//296 1569 | f 271//311 378//251 375//264 1570 | f 374//252 235//306 379//233 1571 | f 385//376 386//390 397//377 1572 | f 399//389 400//378 382//380 1573 | f 380//382 381//379 400//378 1574 | f 398//375 402//383 385//376 1575 | f 401//381 403//385 380//382 1576 | f 383//388 384//384 402//383 1577 | f 404//387 399//389 383//388 1578 | f 403//385 397//377 387//386 1579 | f 388//391 389//397 383//388 1580 | f 390//392 391//395 386//390 1581 | f 393//393 392//394 380//382 1582 | f 394//398 381//379 392//394 1583 | f 381//379 394//398 388//391 1584 | f 393//393 387//386 391//395 1585 | f 383//388 389//397 395//396 1586 | f 390//392 385//376 384//384 1587 | f 388//391 396//404 395//396 1588 | f 396//404 391//395 395//396 1589 | f 396//404 392//394 391//395 1590 | f 388//391 394//398 405//400 1591 | f 329//347 323//342 397//377 1592 | f 305//323 299//322 399//389 1593 | f 299//322 298//319 400//378 1594 | f 402//383 398//375 323//342 1595 | f 403//385 401//381 298//319 1596 | f 404//387 402//383 317//337 1597 | f 399//389 404//387 311//332 1598 | f 397//377 403//385 335//352 1599 | f 406//405 408//401 410//403 1600 | f 396//404 388//391 408//401 1601 | f 408//401 406//405 392//394 1602 | f 394//398 392//394 407//399 1603 | f 409//407 411//406 412//402 1604 | f 410//403 411//406 407//399 1605 | f 411//406 409//407 405//400 1606 | f 409//407 412//402 408//401 1607 | -------------------------------------------------------------------------------- /head_modified_KP.obj: -------------------------------------------------------------------------------- 1 | # head1 Facial animation keypoints 2 | # 3 | o Plane.001_Plane 4 | kp 4.1 5 | v 0.32832 -0.11922 0.82737 6 | kp 4.2 7 | v -0.32832 -0.11922 0.82737 8 | kp 4.3 9 | v 0.68027 -0.02601 0.98183 10 | kp 4.4 11 | v -0.68027 -0.02601 0.98183 12 | kp 4.5 13 | v 1.00789 0.26928 0.81216 14 | kp 4.6 15 | v -1.00789 0.26928 0.81216 16 | kp 3.1 17 | v 0.60619 -0.01962 0.75152 18 | kp 3.2 19 | v -0.60619 -0.01962 0.75152 20 | kp 3.3 21 | v 0.61067 0.00309 0.59879 22 | kp 3.4 23 | v -0.61067 0.00309 0.59879 24 | kp 3.7 25 | v 0.84456 0.22124 0.66971 26 | kp 3.8 27 | v -0.84456 0.22124 0.66971 28 | kp 3.11 29 | v 0.28232 -0.01823 0.64422 30 | kp 3.12 31 | v -0.28232 -0.01823 0.64422 32 | kp 5.3 33 | v 0.64666 -0.03831 0.3478 34 | kp 5.4 35 | v -0.64666 -0.03831 0.3478 36 | kp 9.13 37 | v 0.06046 -0.29616 0.32307 38 | kp 9.14 39 | v -0.06046 -0.29616 0.32307 40 | kp 9.5 41 | v 0.27555 -0.28523 -0.07653 42 | kp 9.4 43 | v -0.27555 -0.28523 -0.07653 44 | kp 8.1 45 | v 0.0 -0.19708 -0.42952 46 | kp 8.2 47 | v 0.0 -0.20343 -0.70554 48 | kp 8.3 49 | v 0.39423 0.07564 -0.54476 50 | kp 8.4 51 | v -0.39423 0.07564 -0.54476 52 | kp 8.5 53 | v 0.26578 -0.17125 -0.44423 54 | kp 8.6 55 | v -0.26578 -0.17125 -0.44423 56 | kp 8.7 57 | v 0.33127 -0.08685 -0.60685 58 | kp 8.8 59 | v -0.33127 -0.08685 -0.60685 60 | kp 2.10 61 | v 0.0 0.00546 -1.10403 62 | kp 2.1 63 | v 0.0 0.16637 -1.27437 64 | 65 | -------------------------------------------------------------------------------- /head_modified_KP_KF10.cpp: -------------------------------------------------------------------------------- 1 | char tab_ID[NB_ANIM_KPS][16] = { "4.1" , "4.2" , "4.3" , "4.4" , "4.5" , "4.6" , "3.1" , "3.2" , "3.3" , "3.4" , "3.7" , "3.8" , "3.11" , "3.12" , "5.3" , "5.4" , "9.13" , "9.14" , "9.5" , "9.4" , "8.1" , "8.2" , "8.3" , "8.4" , "8.5" , "8.6" , "8.7" , "8.8" , "2.10" , "2.1" }; 2 | char *emotion[NB_ANIM_KFS][16] = {"neutral", "happiness", "sadness", "surprise", "anger", "disgust", "fear" "default"}; 3 | float tab_KF_x[NB_ANIM_KPS][NB_ANIM_KFS] = { 4 | { 0 , 0 , 0 , 0 , -0.04 , 0 , -0.078 } , 5 | { 0 , 0 , 0 , 0 , 0.04 , 0 , 0.078 } , 6 | { 0 , 0 , -0.04 , 0 , -0.1 , 0 , 0 } , 7 | { 0 , 0 , 0.04 , 0 , -0.1 , 0 , 0 } , 8 | { 0 , 0 , 0 , 0 , 0 , 0 } , 9 | { 0 , 0 , 0 , 0 , 0 , 0 } , 10 | { 0 , 0 , 0 , 0 , 0 , 0 , 0 } , 11 | { 0 , 0 , 0 , 0 , 0 , 0 , 0 } , 12 | { 0 , 0 , 0 , 0 , 0 , 0 , 0 } , 13 | { 0 , 0 , 0 , 0 , 0 , 0 , 0 } , 14 | { 0 , 0 , 0 , 0 , 0 , 0 } , 15 | { 0 , 0 , 0 , 0 , 0 , 0 } , 16 | { 0 } , 17 | { 0 , 0 } , 18 | { 0 , 0 , 0 , 0 , 0 , 0 } , 19 | { 0 , 0 } , 20 | { 0 , 0 , 0 , 0 , 0 , 0 } , 21 | { 0 , 0 , 0 , 0 , 0 , 0 } , 22 | { 0 , 0 , -0.002 , 0 , 0.04 , -0.035 } , 23 | { 0 , 0 , 0 , 0 , -0.04 , 0.035 } , 24 | { 0 , 0 , 0 , 0 , 0 , 0 } , 25 | { 0 , 0 , 0 , 0 , 0 , 0 , 0 } , 26 | { 0 , 0.193 , 0 , 0 , -0.047 , 0 , 0.06 } , 27 | { 0 , -0.193 , 0 , 0 , 0.05 , 0 , -0.06 } , 28 | { 0 , 0.025 , 0 , 0 , 0 , 0 } , 29 | { 0 , -0.025 , 0 , 0 , 0 } , 30 | { 0 , 0 , 0 , 0 , 0 , 0 , 0 } , 31 | { 0 , 0 , 0 , 0 , 0 , 0 , 0 } , 32 | { 0 , 0 , 0 , 0 , 0 , 0 } , 33 | { 0 , 0 , 0 , 0 , 0 , 0 } 34 | }; 35 | float tab_KF_y[NB_ANIM_KPS][NB_ANIM_KFS] = { 36 | { 0 , 0 , 0 } , 37 | { 0 , 0 , 0 } , 38 | { 0 , 0 } , 39 | { 0 , 0 } , 40 | { 0 , 0 } , 41 | { 0 , 0 , 0 } , 42 | { } , 43 | { } , 44 | { } , 45 | { } , 46 | { } , 47 | { } , 48 | { } , 49 | { } , 50 | { 0 , 0 } , 51 | { 0 , 0 } , 52 | { } , 53 | { 0 , 0 , 0 , 0 , 0 , 0 } , 54 | { } , 55 | { } , 56 | { 0 , 0 , 0 } , 57 | { 0 , 0 , 0.006 , 0 , 0 } , 58 | { 0 , 0.03 , 0 } , 59 | { 0 , 0.03 } , 60 | { 0 , 0 , 0 } , 61 | { 0 , 0 , 0 } , 62 | { 0 , 0 , 0.002 , 0 } , 63 | { 0 , 0 , 0.002 } , 64 | { 0 , 0 , 0 } , 65 | { 0 , 0 , 0 } 66 | }; 67 | float tab_KF_z[NB_ANIM_KPS][NB_ANIM_KFS] = { 68 | { 0 , 0 , 0.07 , 0.12 , -0.108 , -0.07 , 0.13 } , 69 | { 0 , 0 , 0.07 , 0.12 , -0.108 , -0.07 , 0.13 } , 70 | { 0 , 0 , 0 , 0.08 , -0.1 , -0.11 , 0.03 } , 71 | { 0 , 0 , 0 , 0.08 , -0.1 , -0.11 , 0.03 } , 72 | { 0 , 0.032 , 0 , 0.04 , 0.06 , -0.056 } , 73 | { 0 , 0.032 , 0 , 0.04 , 0.06 , -0.056 } , 74 | { 0 , -0.025 , -0.036 , 0.05 , -0.01 , -0.035 , 0.042 } , 75 | { 0 , -0.025 , -0.036 , 0.05 , -0.01 , -0.035 , 0.042 } , 76 | { 0 , 0.025 , 0.035 , 0 , 0.044 , 0.055 , 0.035 } , 77 | { 0 , 0.025 , 0.035 , 0 , 0.044 , 0.055 , 0.035 } , 78 | { 0 , 0 , 0 , 0 , 0 , 0 } , 79 | { } , 80 | { } , 81 | { } , 82 | { 0 , 0.06 , 0 , 0 , 0 , 0 } , 83 | { 0 , 0.06 } , 84 | { 0 , 0 , 0 , 0 , 0 , 0 } , 85 | { 0 , 0 , 0 , 0 , 0 , 0 } , 86 | { 0 , 0 , 0 } , 87 | { 0 , 0 , 0 , 0 , 0 , 0 } , 88 | { -0.05 , -0.03 , -0.03 , 0 , -0.06 , -0.02 } , 89 | { 0.15 , 0 , 0.105 , -0.11 , -0.02 , 0.183 , 0.064 } , 90 | { 0.05 , 0.135 , -0.085 , 0 , 0 , 0.1 , 0 } , 91 | { 0.05 , 0.135 , -0.084 , 0 , 0 , 0.1 , 0 } , 92 | { 0 , 0 , 0 , 0 , -0.01 , 0 } , 93 | { 0 , 0 , 0 , 0 , -0.01 } , 94 | { 0.15 , 0 , 0.06 , -0.102 , 0 , 0.17 , 0.04 } , 95 | { 0.15 , 0 , 0.06 , -0.102 , 0 , 0.17 , 0.04 } , 96 | { 0 , 0 , 0.1 , -0.03 , -0.018 , 0.03 } , 97 | { 0 , 0 , 0.008 , -0.03 , -0.018 , 0.055 } 98 | }; 99 | -------------------------------------------------------------------------------- /head_modified_highpoly.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'head_modified.blend' 2 | # Material Count: 1 3 | 4 | newmtl Material 5 | Ns 96.078431 6 | Ka 0.000000 0.000000 0.000000 7 | Kd 0.640000 0.640000 0.640000 8 | Ks 0.500000 0.500000 0.500000 9 | Ni 1.000000 10 | d 1.000000 11 | illum 2 12 | -------------------------------------------------------------------------------- /head_modified_highpoly_KP.obj: -------------------------------------------------------------------------------- 1 | # head1 Facial animation keypoints 2 | # 3 | o Plane.001_Plane 4 | kp 4.1 5 | v 0.32832 -0.11922 0.82737 6 | kp 4.2 7 | v -0.32832 -0.11922 0.82737 8 | kp 4.3 9 | v 0.68027 -0.02601 0.98183 10 | kp 4.4 11 | v -0.68027 -0.02601 0.98183 12 | kp 4.5 13 | v 1.00789 0.26928 0.81216 14 | kp 4.6 15 | v -1.00789 0.26928 0.81216 16 | kp 3.1 17 | v 0.60619 -0.01962 0.75152 18 | kp 3.2 19 | v -0.60619 -0.01962 0.75152 20 | kp 3.3 21 | v 0.61067 0.00309 0.59879 22 | kp 3.4 23 | v -0.61067 0.00309 0.59879 24 | kp 3.7 25 | v 0.84456 0.22124 0.66971 26 | kp 3.8 27 | v -0.84456 0.22124 0.66971 28 | kp 3.11 29 | v 0.28232 -0.01823 0.64422 30 | kp 3.12 31 | v -0.28232 -0.01823 0.64422 32 | kp 5.3 33 | v 0.64666 -0.03831 0.3478 34 | kp 5.4 35 | v -0.64666 -0.03831 0.3478 36 | kp 9.13 37 | v 0.06046 -0.29616 0.32307 38 | kp 9.14 39 | v -0.06046 -0.29616 0.32307 40 | kp 9.5 41 | v 0.27555 -0.28523 -0.07653 42 | kp 9.4 43 | v -0.27555 -0.28523 -0.07653 44 | kp 8.1 45 | v 0.0 -0.19708 -0.42952 46 | kp 8.2 47 | v 0.0 -0.20343 -0.70554 48 | kp 8.3 49 | v 0.39423 0.07564 -0.54476 50 | kp 8.4 51 | v -0.39423 0.07564 -0.54476 52 | kp 8.5 53 | v 0.26578 -0.17125 -0.44423 54 | kp 8.6 55 | v -0.26578 -0.17125 -0.44423 56 | kp 8.7 57 | v 0.33127 -0.08685 -0.60685 58 | kp 8.8 59 | v -0.33127 -0.08685 -0.60685 60 | kp 2.10 61 | v 0.0 0.00546 -1.10403 62 | kp 2.1 63 | v 0.0 0.16637 -1.27437 64 | 65 | -------------------------------------------------------------------------------- /src/KP-anim-client.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | File: KP-anim-client.cpp 3 | 4 | Virtual Humans 5 | Master in Computer Science 6 | Christian Jacquemin, University Paris 11 7 | 8 | Copyright (C) 2008 University Paris 11 9 | This file is provided without support, instruction, or implied 10 | warranty of any kind. University Paris 11 makes no guarantee of its 11 | fitness for a particular purpose and is not liable under any 12 | circumstances for any damages or loss whatsoever arising from the use 13 | or inability to use this file or items derived from it. 14 | ******************************************************************************/ 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #ifdef __APPLE__ 24 | #include 25 | #elif __linux 26 | #include 27 | #endif 28 | #include 29 | #include /* Sam Leffler's libtiff library. */ 30 | 31 | #include 32 | #include 33 | #ifndef _WIN32 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #else 41 | //#define socklen_t int 42 | #include 43 | #include 44 | //#include 45 | #endif 46 | 47 | /// HOST ADDRESS 48 | class vc_MySocketAddresse { 49 | public: 50 | bool d_valid; 51 | sockaddr_in d_sockAddresse; 52 | int port; 53 | char host[100]; 54 | char host_IP[100]; 55 | 56 | vc_MySocketAddresse() { 57 | memset((char *)&d_sockAddresse,0,sizeof(d_sockAddresse)); 58 | *host = 0; 59 | *host_IP = 0; 60 | d_valid = false; 61 | } 62 | 63 | ~vc_MySocketAddresse(void) { 64 | } 65 | 66 | void IPAdd() { 67 | // gets the string that represents the address "a.b.c.d" 68 | char* s = inet_ntoa( d_sockAddresse.sin_addr ); 69 | if( s == NULL ) 70 | printf( "Erreur: IPAdd() ne peut convertir l'adresse.\n" ); 71 | else 72 | strcpy( host_IP, s ); 73 | } 74 | 75 | void InitFromResolver(char *_host, const int _port) { 76 | struct hostent *hostinfo; 77 | 78 | strcpy( host , _host ); 79 | port=_port; 80 | d_sockAddresse.sin_family=AF_INET; 81 | d_sockAddresse.sin_port=htons(port); 82 | 83 | hostinfo=gethostbyname(host); 84 | if (hostinfo==NULL) { 85 | fprintf( stdout , "Unknown host %s \n", _host); 86 | memset((char *)&d_sockAddresse,0,sizeof(d_sockAddresse)); 87 | d_valid = false; 88 | return; 89 | } 90 | 91 | d_sockAddresse.sin_addr=*(struct in_addr*)hostinfo->h_addr; 92 | IPAdd(); 93 | d_valid = true; 94 | } 95 | 96 | void TestUDPConnection( void ) { 97 | vc_MySocketAddresse sock; 98 | char nam[100]; 99 | 100 | gethostname(nam, 100); 101 | printf( "%s\n" , nam ); 102 | sock.InitFromResolver(nam, 3120); 103 | 104 | char* s = inet_ntoa(sock.d_sockAddresse.sin_addr); 105 | 106 | printf( "%s\n" , s ); 107 | } 108 | }; 109 | 110 | 111 | ////////////////////////////////////////////////////////////////// 112 | // MAIN 113 | ////////////////////////////////////////////////////////////////// 114 | 115 | int main(int argc, char **argv) 116 | { 117 | // local server address 118 | unsigned int Local_server_port = 1979; 119 | 120 | // local server socket 121 | int SocketToLocalServer = -1; 122 | 123 | /////////////////////////////// 124 | // local server creation 125 | struct sockaddr_in localServAddr; 126 | 127 | #ifndef _WIN32 128 | int SocketToLocalServerFlags; 129 | /* socket creation */ 130 | SocketToLocalServer = socket(AF_INET, SOCK_DGRAM, 0); 131 | 132 | if(SocketToLocalServer < 0) { 133 | printf( "Error: udp server cannot open socket to local server!\n" ); 134 | throw(0); 135 | } 136 | else { 137 | // Read the socket's flags 138 | SocketToLocalServerFlags = fcntl(SocketToLocalServer, F_GETFL, 0); 139 | // Sets the socket's flags to non-blocking 140 | SocketToLocalServerFlags |= O_NONBLOCK; 141 | int ret = fcntl(SocketToLocalServer, F_SETFL, SocketToLocalServerFlags ); 142 | if(ret < 0) { 143 | printf( "Error: udp server cannot set flag to non-blocking: %s!" , 144 | strerror(errno) ); 145 | throw(0); 146 | } 147 | } 148 | #else 149 | // socket creation 150 | SocketToLocalServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 151 | 152 | if(SocketToLocalServer < 0) { 153 | printf( "Error: udp server cannot open socket to local server!\n" ); 154 | throw(0); 155 | } 156 | else { 157 | // Read the socket's flags 158 | unsigned long onoff=1; 159 | 160 | if (ioctlsocket(SocketToLocalServer, FIONBIO, &onoff) != 0){ 161 | printf( "Error: udp server cannot set flag to non-blocking: %s!" , 162 | strerror(errno) ); 163 | throw(0); 164 | } 165 | } 166 | #endif 167 | 168 | // bind local server port 169 | localServAddr.sin_family = AF_INET; 170 | localServAddr.sin_addr.s_addr = htonl(INADDR_ANY); 171 | localServAddr.sin_port = htons(Local_server_port); 172 | 173 | int rc = bind (SocketToLocalServer, 174 | (struct sockaddr *) &localServAddr,sizeof(localServAddr)); 175 | if(rc < 0) { 176 | printf( "Error: cannot bind locat port number %d!" , Local_server_port ); 177 | throw(0); 178 | } 179 | printf("udp server: waiting for data on port UDP %u\n", Local_server_port); 180 | 181 | while( true ) { 182 | 183 | // reads incoming UDP messages 184 | if( SocketToLocalServer >= 0 ) { 185 | char message[1024]; 186 | // init message buffer: Null values 187 | memset(message,0x0,1024); 188 | 189 | // receive message 190 | int n = recv(SocketToLocalServer, message, 1024, 0); 191 | if( n >= 0 ) { 192 | // scans the message and extract string & float values 193 | char KP_ID[256]; 194 | int Keyframe; 195 | float KP_translation[3]; 196 | // printf( "Message size %d\n" , n ); 197 | // printf( "Rec.: [%s]\n" , message ); 198 | sscanf( message , "%s %d %f %f %f" , KP_ID , &Keyframe , 199 | KP_translation , KP_translation + 1 , KP_translation + 2 ); 200 | printf( "ID [%s] KF [%d] tr (%.3f,%.3f,%.3f)\n" , KP_ID , Keyframe , 201 | KP_translation[0] , KP_translation[1] , KP_translation[2] ); 202 | } 203 | } 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /src/KP-anim-modele.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricfoucault/facial_animation/f83f3512d6bd16f6a879394e5a3534f62d3ac71e/src/KP-anim-modele.cpp -------------------------------------------------------------------------------- /src/Mesh-display-modele.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | File: Mesh-display-modele.cpp 3 | 4 | Virtual Humans 5 | Master in Computer Science 6 | Christian Jacquemin, University Paris 11 7 | 8 | Copyright (C) 2008 University Paris 11 9 | This file is provided without support, instruction, or implied 10 | warranty of any kind. University Paris 11 makes no guarantee of its 11 | fitness for a particular purpose and is not liable under any 12 | circumstances for any damages or loss whatsoever arising from the use 13 | or inability to use this file or items derived from it. 14 | ******************************************************************************/ 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #ifdef __APPLE__ 24 | #include 25 | #elif __linux 26 | #include 27 | #endif 28 | #include 29 | 30 | #include "texpng.h" 31 | #include 32 | 33 | #define KEY_ESC 27 34 | 35 | #define WINDOW_WIDTH 700 36 | #define WINDOW_HEIGHT 700 37 | 38 | #define NBMAXVERTICES 300000 39 | #define NBMAXFACES 100000 40 | #define NBMAXMESH 30 41 | 42 | #define STRINGSIZE 80 43 | 44 | enum DisplayType{ SURFACE = 0 , MESH , FULL , EmptyDisplayType }; 45 | 46 | DisplayType TypeOfSurfaceDisplay = MESH; 47 | 48 | // light properties of infinite light sources 49 | static GLfloat ambient_light0[4] = { 0.35 , 0.35 , 0.35 , 1.0 }; 50 | static GLfloat diffuse_light0[4] = { 0.7 , 0.7 , 0.7 , 1.0 }; 51 | static GLfloat specular_light0[4] = { 0.1 , 0.1 , 0.1 , 1.0 }; 52 | 53 | static GLfloat ambient_light1[4] = { 0.35 , 0.35 , 0.35 , 1.0 }; 54 | static GLfloat diffuse_light1[4] = { 1.0 , 1.0 , 1.0 , 1.0 }; 55 | static GLfloat specular_light1[4] = { 0.1 , 0.1 , 0.1 , 1.0 }; 56 | 57 | static GLfloat ambient_light2[4] = { 0.35 , 0.35 , 0.35 , 1.0 }; 58 | static GLfloat diffuse_light2[4] = { 0.50 , 0.50 , 0.50 , 1.0 }; 59 | static GLfloat specular_light2[4] = { 0.1 , 0.1 , 0.1 , 1.0 }; 60 | 61 | // infinite light direction i+k 62 | GLfloat light_position0[4] = { 4.0 , 0.0 , 6.0 , 0.0 }; 63 | // infinite light direction -i+k 64 | GLfloat light_position1[4] = { -1.0 , 0.0 , 1.0 , 0.0 }; 65 | // infinite light direction j-0.5k 66 | GLfloat light_position2[4] = { 0.0 , 1.0 , -0.5 , 0.0 }; 67 | 68 | // material properties: silver 69 | float Ambient_silver[4] = {.19225, .19225, .19225, 1.0}; 70 | float Diffuse_silver[4] = {.50754, .50754, .50754, 1.0}; 71 | float Specular_silver[4] = {.508273, .508273, .508273, 1.0}; 72 | float Emission_silver[4] = {.0, .0, .0, .0}; 73 | float Shininess_silver = 51.2; 74 | 75 | float angle_x = -90, angle_y = 0; 76 | int mouse_pos_x = 0, mouse_pos_y = 0; 77 | int MeshID = -1; 78 | 79 | // tiff screenshots 80 | int ScreenShot = false; 81 | int ShotRank = 0; 82 | int MaxRank = 300; 83 | 84 | int Trace = false; 85 | float Zoom = 0.3; 86 | char MeshFileName[STRINGSIZE]; 87 | char MaterialFileName[STRINGSIZE]; 88 | 89 | int main(int argc, char **argv); 90 | 91 | void parse_mesh_obj( char *fileName ); 92 | 93 | void displayFace( int indFace ); 94 | void make_mesh( void ); 95 | 96 | void init_scene( void ); 97 | void initGL( void ); 98 | 99 | void window_display( void ); 100 | void window_reshape(GLsizei width, GLsizei height); 101 | void window_key(unsigned char key, int x, int y); 102 | void window_mouseFunc(int button, int state, int x, int y); 103 | void window_motionFunc(int x, int y); 104 | void window_idle( void ); 105 | void window_special_key(int key, int x, int y); 106 | 107 | void render_scene( void ); 108 | 109 | class Vector { 110 | public: 111 | float x, y, z; 112 | Vector( void ) { 113 | init(); 114 | }; 115 | ~Vector( void ) { 116 | }; 117 | void init( void ) { 118 | x = 0; 119 | y = 0; 120 | z = 0; 121 | }; 122 | void normalize( void ) { 123 | if( x == 0 && y == 0 && z == 0 ) { 124 | return; 125 | } 126 | float norm = 1.0 / sqrt( x*x + y*y + z*z ); 127 | x *= norm; 128 | y *= norm; 129 | z *= norm; 130 | } 131 | // 1 vector 132 | float prodScal( Vector &v2 ) { 133 | return x * v2.x + y * v2.y + z * v2.z; 134 | } 135 | // average 136 | void averageVectors( Vector *vectors , int nbVectors ) { 137 | x = 0; y = 0; z = 0; 138 | if( nbVectors <= 0 ) { 139 | return; 140 | } 141 | for( int ind = 0 ; ind < nbVectors ; ind++ ) { 142 | x += vectors[ ind ].x; 143 | y += vectors[ ind ].y; 144 | z += vectors[ ind ].z; 145 | } 146 | float inv = 1.0 / (float)nbVectors; 147 | x *= inv; 148 | y *= inv; 149 | z *= inv; 150 | } 151 | void operator*=(double d) { 152 | x *= d; 153 | y *= d; 154 | z *= d; 155 | } 156 | void operator+=(Vector& v) { 157 | x += v.x; 158 | y += v.y; 159 | z += v.z; 160 | } 161 | }; 162 | 163 | class Point { 164 | public: 165 | float x, y, z; 166 | Point( void ) { 167 | init(); 168 | }; 169 | ~Point( void ) { 170 | }; 171 | void init( void ) { 172 | x = 0; 173 | y = 0; 174 | z = 0; 175 | }; 176 | void operator=(Point& v) { 177 | x = v.x; 178 | y = v.y; 179 | z = v.z; 180 | } 181 | void operator*=(double d) { 182 | x *= d; 183 | y *= d; 184 | z *= d; 185 | } 186 | void operator+=(Vector& v) { 187 | x += v.x; 188 | y += v.y; 189 | z += v.z; 190 | } 191 | void operator*(double f) { 192 | x = f * x; 193 | y = f * y; 194 | z = f * z; 195 | } 196 | int operator==(Point& v) { 197 | return((x == v.x) && (y == v.y) && (z == v.z)); 198 | } 199 | float distance(Point& p) { 200 | float dx, dy, dz; 201 | dx = p.x - x; 202 | dy = p.y - y; 203 | dz = p.z - z; 204 | return sqrt(dx*dx + dy*dy + dz*dz); 205 | } 206 | }; 207 | 208 | class Vertex { 209 | public: 210 | // coordinates 211 | Point location; 212 | Vertex( void ) { 213 | location.init(); 214 | }; 215 | ~Vertex( void ) { 216 | }; 217 | }; 218 | 219 | class Face { 220 | public: 221 | int indVertex1; 222 | int indVertex2; 223 | int indVertex3; 224 | int indNormal1; 225 | int indNormal2; 226 | int indNormal3; 227 | Face( void ) { 228 | indNormal1 = -1; 229 | indNormal2 = -1; 230 | indNormal3 = -1; 231 | indVertex1 = -1; 232 | indVertex2 = -1; 233 | indVertex3 = -1; 234 | } 235 | ~Face( void ) { 236 | }; 237 | }; 238 | 239 | class Mesh { 240 | public: 241 | char *id; 242 | char *matId; 243 | int indFaceIni; 244 | int indFaceEnd; 245 | Mesh( void ) { 246 | id = new char[STRINGSIZE]; 247 | id[0] = 0; 248 | matId = new char[STRINGSIZE]; 249 | matId[0] = 0; 250 | indFaceIni = 0; 251 | indFaceEnd = 0; 252 | } 253 | ~Mesh( void ) { 254 | delete [] id; 255 | delete [] matId; 256 | } 257 | }; 258 | 259 | ////////////////////////////////////////////////////////////////// 260 | // MESH TABLES 261 | ////////////////////////////////////////////////////////////////// 262 | 263 | Vertex *TabVertices = NULL; 264 | Face *TabFaces = NULL; 265 | Vector *TabNormals = NULL; 266 | Mesh *TabMeshes = NULL; 267 | int NbMeshes = 0; 268 | int NbVertices = 0; 269 | int NbFaces = 0; 270 | int NbNormals = 0; 271 | 272 | ////////////////////////////////////////////////////////////////// 273 | // MAIN EVENT LOOP 274 | ////////////////////////////////////////////////////////////////// 275 | 276 | int main(int argc, char **argv) 277 | { 278 | if( argc >=2 ) { 279 | strcpy( MeshFileName , argv[1] ); 280 | } 281 | else { 282 | printf( "Mesh file (SimpleShape-Facetted.obj):" ); 283 | fflush( stdin ); 284 | fgets( MeshFileName , STRINGSIZE , stdin ); 285 | if( *MeshFileName == '\n' ) { 286 | strcpy( MeshFileName , "SimpleShape-Facetted.obj" ); ; 287 | } 288 | else { 289 | MeshFileName[ strlen( MeshFileName ) - 1 ] = 0; 290 | } 291 | } 292 | printf( "Mesh file (%s)\n" , MeshFileName ); 293 | 294 | // GLUT initialization 295 | glutInit(&argc, argv); 296 | glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); 297 | 298 | // window intialization 299 | glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); 300 | glutInitWindowPosition(0, 0); 301 | glutCreateWindow("Meshes"); 302 | 303 | // OpenGL and scene initialization 304 | initGL(); 305 | init_scene(); 306 | 307 | // GLUT callbacks 308 | // for drawing 309 | glutDisplayFunc(&window_display); 310 | // for window resize 311 | glutReshapeFunc(&window_reshape); 312 | // for keyboard events 313 | glutKeyboardFunc(&window_key); 314 | // for mouse clicks 315 | glutMouseFunc(&window_mouseFunc); 316 | // for mouse drags 317 | glutMotionFunc(&window_motionFunc); 318 | // for special keys 319 | glutSpecialFunc(&window_special_key); 320 | 321 | if( ScreenShot ) { 322 | glutIdleFunc(&window_idle); 323 | } 324 | 325 | // main event loop 326 | glutMainLoop(); 327 | 328 | return 1; 329 | } 330 | 331 | ////////////////////////////////////////////////////////////////// 332 | // MESH PARSING 333 | ////////////////////////////////////////////////////////////////// 334 | 335 | // OBJ file parsing (Alias Wavefront ASCII format) 336 | void parse_mesh_obj( FILE *file ) 337 | { 338 | char tag[256]; 339 | char line[256]; 340 | char ch; 341 | 342 | // Two comment lines 343 | // # Blender3D v244 OBJ File: Anime_Girl.blend 344 | // # www.blender3d.org 345 | fgets ( line, 256, file ); 346 | fgets ( line, 256, file ); 347 | 348 | // material name 349 | fgets ( line, 256, file ); 350 | sscanf ( line, "%s %s", 351 | tag, 352 | MaterialFileName ); 353 | // printf( "MaterialFileName %s %s\n" , tag , MaterialFileName ); 354 | 355 | // mesh ID 356 | fgets ( line, 256, file ); 357 | sscanf ( line, "%s", tag ); 358 | 359 | while( strcmp( tag , "o" ) == 0 ) { 360 | // while( strcmp( tag , "v" ) == 0 ) { 361 | if( NbMeshes > NBMAXMESH ) { 362 | printf( "Error: Excessive number of Meshes\n" ); 363 | throw 0; 364 | } 365 | 366 | // mesh ID 367 | sscanf ( line, "%s %s", 368 | tag , 369 | TabMeshes[ NbMeshes ].id ); 370 | printf( "Mesh ID #%d %s\n" , NbMeshes , TabMeshes[ NbMeshes ].id ); 371 | 372 | // next tag 373 | fgets ( line, 256, file ); 374 | sscanf ( line, "%s", tag ); 375 | 376 | // Scan for Verts in this mesh 377 | while( strcmp( tag , "v" ) == 0 ) { 378 | if( NbVertices > NBMAXVERTICES ) { 379 | printf( "Error: Excessive number of vertices\n" ); 380 | throw 0; 381 | } 382 | sscanf ( line, "%s %f %f %f", 383 | tag, 384 | &(TabVertices[NbVertices].location.x), 385 | &(TabVertices[NbVertices].location.y), 386 | &(TabVertices[NbVertices].location.z) ); 387 | // printf( "vertex %f %f %f\n" , TabVertices[NbVertices].location.x, 388 | // TabVertices[NbVertices].location.y, 389 | // TabVertices[NbVertices].location.z ); 390 | NbVertices++; 391 | fgets ( line, 256, file ); 392 | sscanf ( line, "%s", tag ); 393 | } 394 | 395 | // Scan for Norms in this mesh 396 | while( strcmp( tag , "vn" ) == 0 ) { 397 | sscanf ( line, "%s %f %f %f", 398 | tag , 399 | &(TabNormals[NbNormals].x), 400 | &(TabNormals[NbNormals].y), 401 | &(TabNormals[NbNormals].z) ); 402 | // printf( "normal %f %f %f\n" , TabNormals[NbNormals].x, 403 | // TabNormals[NbNormals].y, 404 | // TabNormals[NbNormals].z ); 405 | NbNormals++; 406 | fgets ( line, 256, file ); 407 | sscanf ( line, "%s", tag ); 408 | } 409 | 410 | // Scan for Mat in this mesh 411 | if( strcmp( tag , "usemtl" ) == 0 ) { 412 | sscanf ( line, "%s %s", 413 | tag , 414 | TabMeshes[ NbMeshes ].matId ); 415 | // printf( "Mesh %d mat %s\n" , NbMeshes , TabMeshes[ NbMeshes ].matId ); 416 | fgets ( line, 256, file ); 417 | sscanf ( line, "%s", tag ); 418 | } 419 | 420 | TabMeshes[NbMeshes].indFaceIni = NbFaces; 421 | // printf( "Mesh #%d face ini %d\n" , NbMeshes , TabMeshes[NbMeshes].indFaceIni ); 422 | 423 | // Scan for Faces in this mesh 424 | while( strcmp( tag , "f" ) == 0 425 | || strcmp( tag , "usemtl" ) == 0 426 | || strcmp( tag , "s" ) == 0 ) { 427 | if( NbFaces > NBMAXFACES ) { 428 | printf( "Error: Excessive number of faces\n" ); 429 | throw 0; 430 | } 431 | 432 | // Scan for Mat in this mesh 433 | // currently only one mat per mesh 434 | if( strcmp( tag , "usemtl" ) == 0 ) { 435 | sscanf ( line, "%s", 436 | TabMeshes[ NbMeshes ].matId ); 437 | // printf( "mat %s" , line ); 438 | } 439 | // Scan for Smooth boolean in this mesh 440 | else if( strcmp( tag , "s" ) == 0 ) { 441 | sscanf ( line, "%s", tag ); 442 | } 443 | // Scan for a Face in this mesh 444 | else { 445 | sscanf( line, "%s %d//%d %d//%d %d//%d", 446 | tag, 447 | &(TabFaces[NbFaces].indVertex1), 448 | &(TabFaces[NbFaces].indNormal1), 449 | &(TabFaces[NbFaces].indVertex2), 450 | &(TabFaces[NbFaces].indNormal2), 451 | &(TabFaces[NbFaces].indVertex3), 452 | &(TabFaces[NbFaces].indNormal3) ); 453 | // indices start from 1 in OBJ format 454 | // we make start from 0 for C++ 455 | TabFaces[NbFaces].indVertex1--; 456 | TabFaces[NbFaces].indVertex2--; 457 | TabFaces[NbFaces].indVertex3--; 458 | TabFaces[NbFaces].indNormal1--; 459 | TabFaces[NbFaces].indNormal2--; 460 | TabFaces[NbFaces].indNormal3--; 461 | // printf( "face %d %d %d %d %d %d\n" , 462 | // TabFaces[NbFaces].indVertex1, 463 | // TabFaces[NbFaces].indNormal1, 464 | // TabFaces[NbFaces].indVertex2, 465 | // TabFaces[NbFaces].indNormal2, 466 | // TabFaces[NbFaces].indVertex3, 467 | // TabFaces[NbFaces].indNormal3 ); 468 | if( TabFaces[NbFaces].indVertex1 >= 0 469 | && TabFaces[NbFaces].indVertex2 >= 0 470 | && TabFaces[NbFaces].indVertex3 >= 0 471 | && TabFaces[NbFaces].indNormal1 >= 0 472 | && TabFaces[NbFaces].indNormal2 >= 0 473 | && TabFaces[NbFaces].indNormal3 >= 0 ) { 474 | NbFaces++; 475 | } 476 | } 477 | 478 | if( !fgets ( line, 256, file ) ) { 479 | TabMeshes[NbMeshes].indFaceEnd = NbFaces; 480 | printf( "Mesh #%d %s Faces %d-%d\n" , NbMeshes , 481 | TabMeshes[ NbMeshes ].id , 482 | TabMeshes[ NbMeshes ].indFaceIni , 483 | TabMeshes[ NbMeshes ].indFaceEnd ); 484 | NbMeshes++; 485 | return; 486 | } 487 | sscanf ( line, "%s", tag ); 488 | } 489 | 490 | TabMeshes[NbMeshes].indFaceEnd = NbFaces; 491 | printf( "Mesh #%d %s Faces %d-%d\n" , NbMeshes , 492 | TabMeshes[ NbMeshes ].id , 493 | TabMeshes[ NbMeshes ].indFaceIni , 494 | TabMeshes[ NbMeshes ].indFaceEnd ); 495 | NbMeshes++; 496 | } 497 | } 498 | 499 | ////////////////////////////////////////////////////////////////// 500 | // MESH DISPLAY 501 | // TODO 502 | ////////////////////////////////////////////////////////////////// 503 | 504 | // face display 505 | 506 | void displayFace( int indFace ) { 507 | // TODO 508 | } 509 | 510 | // transforms the mesh into a Display List 511 | 512 | void make_mesh( void ) { 513 | glNewList(MeshID, GL_COMPILE); 514 | for( int ind = 0 ; ind < NbMeshes ; ind++ ) { 515 | // displays wireframe + surface 516 | if( TypeOfSurfaceDisplay == FULL ) { 517 | // TODO 518 | } 519 | // displays wireframe 520 | else if( TypeOfSurfaceDisplay == MESH ) { 521 | // TODO 522 | } 523 | // displays surface 524 | else { 525 | // TODO 526 | } 527 | } 528 | glEndList(); 529 | } 530 | 531 | ////////////////////////////////////////////////////////////////// 532 | // INTIALIZATIONS 533 | ////////////////////////////////////////////////////////////////// 534 | 535 | // OpenGL intialization 536 | 537 | GLvoid initGL( void ) 538 | { 539 | // 3 light sources 540 | glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_light0); 541 | glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_light0); 542 | glLightfv(GL_LIGHT0, GL_SPECULAR, specular_light0); 543 | glLightfv(GL_LIGHT0, GL_POSITION, light_position0); 544 | 545 | glLightfv(GL_LIGHT1, GL_AMBIENT, ambient_light1); 546 | glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse_light1); 547 | glLightfv(GL_LIGHT1, GL_SPECULAR, specular_light1); 548 | glLightfv(GL_LIGHT1, GL_POSITION, light_position1); 549 | 550 | glLightfv(GL_LIGHT2, GL_AMBIENT, ambient_light2); 551 | glLightfv(GL_LIGHT2, GL_DIFFUSE, diffuse_light2); 552 | glLightfv(GL_LIGHT2, GL_SPECULAR, specular_light2); 553 | glLightfv(GL_LIGHT2, GL_POSITION, light_position2); 554 | 555 | // Gouraud shading 556 | glShadeModel( GL_SMOOTH ); 557 | 558 | // two side surface lighting 559 | glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); 560 | 561 | // BG color 562 | glClearColor( 1, 1, 1, 1 ); 563 | 564 | // z-buffer 565 | glEnable(GL_DEPTH_TEST); 566 | 567 | // lighting 568 | glEnable(GL_LIGHTING); 569 | glEnable(GL_LIGHT0); 570 | glEnable(GL_LIGHT1); 571 | glEnable(GL_LIGHT2); 572 | 573 | // automatic normal normalization 574 | glEnable(GL_NORMALIZE); 575 | } 576 | 577 | // scene initialization 578 | 579 | void init_scene( void ) 580 | { 581 | TabVertices = new Vertex[ NBMAXVERTICES ]; 582 | TabFaces = new Face[ NBMAXFACES ]; 583 | TabNormals = new Vector[ NBMAXVERTICES ]; 584 | TabMeshes = new Mesh[ NBMAXMESH ]; 585 | 586 | NbMeshes = 0; 587 | NbVertices = 0; 588 | NbFaces = 0; 589 | NbNormals = 0; 590 | 591 | // parses the mesh (obj format) 592 | FILE * fileMesh = fopen( MeshFileName , "r" ); 593 | if( !fileMesh ) { 594 | printf( "File %s not found\n" , MeshFileName ); 595 | exit(0); 596 | } 597 | parse_mesh_obj( fileMesh ); 598 | fclose( fileMesh ); 599 | 600 | // Display List compiling 601 | MeshID = glGenLists(1); 602 | make_mesh(); 603 | 604 | } 605 | 606 | ////////////////////////////////////////////////////////////////// 607 | // GLUT CALL-BACKS 608 | ////////////////////////////////////////////////////////////////// 609 | 610 | // glut call-back: window display 611 | 612 | GLvoid window_display( void ) 613 | { 614 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 615 | glLoadIdentity(); 616 | glScalef( Zoom , Zoom , Zoom ); 617 | 618 | render_scene(); 619 | 620 | glFlush(); 621 | } 622 | 623 | // glut call-back: window resize 624 | 625 | GLvoid window_reshape(GLsizei width, GLsizei height) 626 | { 627 | glViewport(0, 0, width, height); 628 | 629 | glMatrixMode(GL_PROJECTION); 630 | glLoadIdentity(); 631 | glOrtho(-1.2, 1.2, -1.2, 1.2, -10.2, 10.2); 632 | 633 | // model view drawing 634 | glMatrixMode(GL_MODELVIEW); 635 | } 636 | 637 | // glut call-back: keyboard events 638 | 639 | GLvoid window_key(unsigned char key, int x, int y) 640 | { 641 | switch (key) { 642 | case '<': 643 | Zoom /= 1.1; 644 | glutPostRedisplay(); 645 | break; 646 | case '>': 647 | Zoom *= 1.1; 648 | glutPostRedisplay(); 649 | break; 650 | case 'm': 651 | case 'M': 652 | if( TypeOfSurfaceDisplay != MESH ) { 653 | TypeOfSurfaceDisplay = MESH; 654 | make_mesh(); 655 | glutPostRedisplay(); 656 | } 657 | break; 658 | case 's': 659 | case 'S': 660 | if( TypeOfSurfaceDisplay != SURFACE ) { 661 | TypeOfSurfaceDisplay = SURFACE; 662 | make_mesh(); 663 | glutPostRedisplay(); 664 | } 665 | break; 666 | case 'f': 667 | case 'F': 668 | if( TypeOfSurfaceDisplay != FULL ) { 669 | TypeOfSurfaceDisplay = FULL; 670 | make_mesh(); 671 | glutPostRedisplay(); 672 | } 673 | break; 674 | case KEY_ESC: 675 | exit(1); 676 | break; 677 | default: 678 | printf ("La touche %d n'est pas active.\n", key); 679 | break; 680 | } 681 | } 682 | 683 | // glut call-back: mouse click events 684 | 685 | GLvoid window_mouseFunc(int button, int state, int x, int y) 686 | { 687 | if (state == GLUT_DOWN && button == GLUT_LEFT_BUTTON) { 688 | mouse_pos_x = x; 689 | mouse_pos_y = y; 690 | } 691 | } 692 | 693 | // glut call-back: mouse drag events 694 | 695 | GLvoid window_motionFunc(int x, int y) 696 | { 697 | angle_x += y - mouse_pos_y; 698 | angle_y += x - mouse_pos_x; 699 | 700 | mouse_pos_x = x; 701 | mouse_pos_y = y; 702 | 703 | glutPostRedisplay(); 704 | } 705 | 706 | // glut call-back: update function called at each frame 707 | 708 | GLvoid window_idle( void ) 709 | { 710 | angle_x += 1.5; 711 | angle_y += 1.5; 712 | 713 | glutPostRedisplay(); 714 | 715 | // file output 716 | if( ScreenShot ) { 717 | char filename[256]; 718 | char description[256]; 719 | 720 | glReadBuffer(GL_BACK); 721 | sprintf( filename , "tmp/tmp%d.png" , ShotRank ); 722 | sprintf( description , "PNG rendering" , ShotRank ); 723 | writepng(filename, description, 0,0, 724 | WINDOW_WIDTH,WINDOW_HEIGHT); 725 | fprintf( stdout , "%s\n" , description ); 726 | ShotRank++; 727 | if( ShotRank > MaxRank ) { 728 | ScreenShot = false; 729 | glutIdleFunc(NULL); 730 | } 731 | } 732 | } 733 | 734 | // glut call-back: special key processing 735 | 736 | void window_special_key(int key, int x, int y) 737 | { 738 | switch (key) { 739 | default: 740 | printf ("special key %d is not active.\n", key); 741 | break; 742 | } 743 | } 744 | 745 | ////////////////////////////////////////////////////////////////// 746 | // INTERACTIVE SCENE RENDERING 747 | ////////////////////////////////////////////////////////////////// 748 | 749 | void render_scene( void ) 750 | { 751 | glPushMatrix(); 752 | glRotatef(angle_x, 1, 0, 0); 753 | glRotatef(angle_y, 0, 0, 1); 754 | 755 | // axes xx yy & zz 756 | glEnable( GL_COLOR_MATERIAL ); 757 | glColor3f( 1.0 , 0.0 , 0.0 ); 758 | // glBegin( GL_LINES ); 759 | // glVertex3f( -10.0 , 0.0 , 0.0 ); 760 | // glVertex3f( 10.0 , 0.0 , 0.0 ); 761 | // glVertex3f( 0.0 , -10.0 , 0.0 ); 762 | // glVertex3f( 0.0 , 10.0 , 0.0 ); 763 | // glVertex3f( 0.0 , 0.0 , -10.0 ); 764 | // glVertex3f( 0.0 , 0.0 , 10.0 ); 765 | // glEnd(); 766 | 767 | glTranslatef(1.438, 2.702, -2); 768 | glCallList(MeshID); 769 | 770 | glPopMatrix(); 771 | 772 | glutSwapBuffers(); 773 | } 774 | 775 | -------------------------------------------------------------------------------- /src/glutil.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * gutil.h 4 | * 5 | * FUNCTION: 6 | * Provide utilities that allow rotation to occur 7 | * around any axis. 8 | * 9 | * HISTORY: 10 | * created by Linas Vepstas 1990 11 | * added single & double precision, June 1991, Linas Vepstas 12 | */ 13 | 14 | #ifndef __GUTIL_H__ 15 | #define __GUTIL_H__ 16 | 17 | 18 | /* Rotation Utilities */ 19 | extern void rot_axis_f (); 20 | extern void rot_about_axis_f (); 21 | extern void rot_omega_f (); 22 | extern void urot_axis_f (); 23 | extern void urot_about_axis_f (); 24 | extern void urot_omega_f (); 25 | 26 | /* viewpoint functions */ 27 | extern void uview_direction_d (); 28 | extern void uview_direction_f (); 29 | extern void uviewpoint_d (); 30 | extern void uviewpoint_f (); 31 | 32 | /* Rotation Utilities */ 33 | extern void rot_axis_f (float omega, float axis[3]); 34 | extern void rot_about_axis_f (float angle, float axis[3]); 35 | extern void rot_omega_f (float axis[3]); 36 | extern void urot_axis_f (float m[16], float omega, float axis[3]); 37 | extern void urot_about_axis_f (float m[16], float angle, float axis[3]); 38 | extern void urot_omega_f (float m[16], float axis[3]); 39 | 40 | /* viewpoint functions */ 41 | extern void uview_direction_f (float m[16], /* returned */ 42 | float v21[3], /* input */ 43 | float up[3]); /* input */ 44 | 45 | 46 | extern void uviewpoint_f (float m[16], /* returned */ 47 | float v1[3], /* input */ 48 | float v2[3], /* input */ 49 | float up[3]); /* input */ 50 | 51 | 52 | /* ------------------- end of file ---------------------- */ 53 | #endif 54 | -------------------------------------------------------------------------------- /src/texpng.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | File: texpng.cpp 3 | 4 | Virtual Humans 5 | Master in Computer Science 6 | Christian Jacquemin, University Paris 11 7 | 8 | This file is provided without support, instruction, or implied 9 | warranty of any kind. University Paris 11 makes no guarantee of its 10 | fitness for a particular purpose and is not liable under any 11 | circumstances for any damages or loss whatsoever arising from the use 12 | or inability to use this file or items derived from it. 13 | ******************************************************************************/ 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "texpng.h" 21 | #include "ctype.h" 22 | 23 | #define png_infopp_NULL (png_infopp)NULL 24 | #define int_p_NULL (int*)NULL 25 | 26 | /* Pixels in this bitmap structure are stored as BGR. */ 27 | typedef struct _RGBPixel { 28 | unsigned char blue; 29 | unsigned char green; 30 | unsigned char red; 31 | } RGBPixel; 32 | 33 | /* Structure for containing decompressed bitmaps. */ 34 | typedef struct _RGBBitmap { 35 | RGBPixel *pixels; 36 | size_t width; 37 | size_t height; 38 | size_t bytewidth; 39 | unsigned char bytes_per_pixel; 40 | } RGBBitmap; 41 | 42 | ///////////////////////////////// LOAD PNG \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 43 | ///// 44 | ///// This loads the PNG file and returns its data in a tImagePNG struct 45 | ///// 46 | ///////////////////////////////// LOAD PNG \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 47 | 48 | // This is the interesting function here. It sets up a PNG image as a texture. 49 | void loadPngTex(char * fname , struct tImagePNG * pImagePNG , int *hasAlpha ) 50 | { 51 | FILE *fp; 52 | 53 | // The header of the file will be saved in here 54 | char buf[PNG_BYTES_TO_CHECK]; 55 | 56 | // Open the file and check correct opening 57 | /* Open the prospective PNG file. */ 58 | if ((fp = fopen(fname, "rb")) == NULL) { 59 | printf( "Error: Could not open the texture file [%s]!" , fname ); 60 | exit( 0 ); 61 | } 62 | 63 | // Read the PNG header, which is 8 bytes long. 64 | /* Read in some of the signature bytes */ 65 | if (fread(buf, 1, PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK) { 66 | printf( "Error: Incorrect PNG texture file [%s]!" , fname ); 67 | exit( 0 ); 68 | } 69 | 70 | // Check whether the file is a PNG file 71 | // png_sig_cmp() checks the given PNG header and returns 0 if it could 72 | // be the start of a PNG file. We can use 8 bytes at max for 73 | // this comparison. 74 | if(png_sig_cmp((png_byte*)buf, (png_size_t)0, PNG_BYTES_TO_CHECK) != 0) { 75 | fclose( fp ); 76 | printf( "Error: Not a PNG file [%s]!" , fname ); 77 | exit( 0 ); 78 | } 79 | 80 | // Create / initialize the png_struct 81 | // The png_struct isn't directly accessed by the user (us). 82 | // We will later create a png_info from this to get access to the 83 | // PNG's infos. 84 | // The three 0's in the arg list could be pointers to user defined error 85 | // handling functions. 0 means we don't want to specify them, but use 86 | // libPNG's default error handling instead. 87 | png_infop info_ptr; 88 | png_structp png_ptr 89 | = png_create_read_struct(PNG_LIBPNG_VER_STRING, 90 | NULL , NULL , NULL ); 91 | if(!png_ptr) { 92 | fclose( fp ); 93 | printf( "Error: Couldn't create PNG read structure [%s]!" , fname ); 94 | exit( 0 ); 95 | } 96 | 97 | // Create / initialize the png_info 98 | // The png_info grants the user access to the PNG infos. 99 | info_ptr = png_create_info_struct(png_ptr); 100 | if(!info_ptr) { 101 | // We need to destroy the read_struct 102 | png_destroy_read_struct(&png_ptr, NULL, NULL); 103 | fclose( fp ); 104 | printf( "Error: Couldn't create PNG info structure [%s]!" , fname ); 105 | exit( 0 ); 106 | } 107 | 108 | // Setup error handler 109 | // This sets the point libPNG jumps back to is an error occurs. 110 | if (setjmp(png_jmpbuf(png_ptr))) { 111 | /* Free all of the memory associated with the png_ptr and info_ptr */ 112 | png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); 113 | fclose(fp); 114 | /* If we get here, we had a problem reading the file */ 115 | printf( "Error: Couldn't setup PNG error handler [%s]!" , fname ); 116 | exit( 0 ); 117 | } 118 | 119 | /* Set up the input control if you are using standard C streams */ 120 | png_init_io(png_ptr, fp); 121 | 122 | // This tells libPNG that we have already read 8 bytes from the start 123 | // of the file (for the header check above). 124 | png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); 125 | 126 | // This reads the PNG file into the read and info structs 127 | png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); 128 | 129 | // Get some basic infos about the image 130 | pImagePNG->sizeX = png_get_image_width(png_ptr, info_ptr); // width in px 131 | pImagePNG->sizeY = png_get_image_height(png_ptr, info_ptr); // height in px 132 | int bit_depth = png_get_bit_depth(png_ptr, info_ptr); // bits per pixel 133 | 134 | // Color type - we'll handle RGB and RGBA (with Alpha) 135 | int cType = png_get_color_type(png_ptr, info_ptr); 136 | 137 | // We now calculate the *bytes* per pixel from the color type and the 138 | // bits per pixel. 139 | if((cType == PNG_COLOR_TYPE_RGB) && (bit_depth == 8)) { 140 | pImagePNG->bytesPerPixel = 3; 141 | *hasAlpha = 0; 142 | } 143 | else if((cType == PNG_COLOR_TYPE_RGB_ALPHA) && (bit_depth == 8)) { 144 | pImagePNG->bytesPerPixel = 4; 145 | *hasAlpha = 1; 146 | } 147 | else { 148 | /* clean up after the read, and free any memory allocated - REQUIRED */ 149 | png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); 150 | fclose( fp ); 151 | printf( "Error: PNG image [%s] type is unsupported!" , fname ); 152 | exit( 0 ); 153 | } 154 | 155 | // Returns a pointer to the array of array of png_bytes that holds the 156 | // image data. 157 | png_byte **imageData = png_get_rows(png_ptr, info_ptr); 158 | 159 | // This will hold our image 160 | unsigned int rowbytes = png_get_rowbytes(png_ptr, info_ptr); 161 | pImagePNG->data = (GLubyte*)malloc(pImagePNG->sizeY * rowbytes * sizeof(GLubyte)); 162 | 163 | int i,j; 164 | for( i = 0 ; i < pImagePNG->sizeY ; i++ ) { 165 | memcpy(&pImagePNG->data[(pImagePNG->sizeY - i - 1) * rowbytes], 166 | imageData[i], rowbytes); 167 | } 168 | 169 | // Free the memory we used - we don't need it anymore 170 | /* clean up after the read, and free any memory allocated - REQUIRED */ 171 | png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); 172 | fclose( fp ); 173 | } 174 | 175 | ///////////////////////////// CREATE TEXTURE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 176 | ///// 177 | ///// This creates a texture in OpenGL that we can use as a texture map 178 | ///// 179 | ///////////////////////////// CREATE TEXTURE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 180 | 181 | void ReverseImage( int width , int height , unsigned char *data , int bytesPerPixel ) { 182 | unsigned char *dataaux = (unsigned char*)malloc(width * height * bytesPerPixel * sizeof(unsigned char)); 183 | int indrow; 184 | for( indrow = 0 ; indrow < height ; indrow++ ) { 185 | memcpy(&dataaux[indrow * width * bytesPerPixel], 186 | &data[(height - indrow - 1) * width * bytesPerPixel], width * bytesPerPixel); 187 | } 188 | for( indrow = 0 ; indrow < height ; indrow++ ) { 189 | memcpy(&data[indrow * width * bytesPerPixel], 190 | &dataaux[indrow * width * bytesPerPixel], width * bytesPerPixel); 191 | } 192 | free(dataaux); 193 | } 194 | 195 | // The image dimensions must be powers of 2. 196 | void CheckImageDimensions( int sizeX , int sizeY , char * strFileName) { 197 | // Check the image width 198 | int comp = 2; 199 | int isValid = 0; 200 | int i; 201 | for( i = 0; i < 10; i++) { 202 | comp <<= 1; 203 | if(sizeX == comp) 204 | isValid = 1; 205 | } 206 | if(!isValid) { 207 | printf( "Error: The image width is not a power of 2 [%s]!" , strFileName ); 208 | exit( 0 ); 209 | } 210 | 211 | // Check the image height 212 | comp = 2; 213 | isValid = 0; 214 | for( i = 0; i < 10; i++) { 215 | comp <<= 1; 216 | if(sizeY == comp) 217 | isValid = 1; 218 | } 219 | if(!isValid) { 220 | printf( "Error: The image height is not a power of 2 [%s]!" , strFileName ); 221 | exit( 0 ); 222 | } 223 | } 224 | 225 | ///////////////////////////////// CREATE TEXTURE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 226 | ///// 227 | ///// This creates a texture in OpenGL that we can use as a texture map 228 | ///// 229 | ///////////////////////////////// CREATE TEXTURE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 230 | 231 | void CreateTexturePNG(unsigned int *textureId, char * strFileName) 232 | { 233 | if(!strFileName) 234 | // Return from the function if no file name was passed in 235 | return; 236 | 237 | 238 | printf( "Loading [%s]!\n" , strFileName ); 239 | 240 | // Load the image and store the data 241 | struct tImagePNG imagePNG; 242 | int hasAlpha = 0; 243 | loadPngTex(strFileName , &imagePNG , &hasAlpha ); 244 | 245 | // Generate a texture with the associative texture ID stored in the array 246 | glGenTextures(1, textureId); 247 | 248 | // Bind the texture to the texture arrays index and init the texture 249 | glBindTexture(GL_TEXTURE_2D, *textureId); 250 | 251 | // Build Mipmaps (builds different versions of the picture for distances - looks better) 252 | if( hasAlpha ) { 253 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 254 | GL_LINEAR_MIPMAP_LINEAR); 255 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 256 | GL_LINEAR); 257 | gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA8, 258 | imagePNG.sizeX, imagePNG.sizeY, 259 | GL_RGBA, 260 | GL_UNSIGNED_BYTE, (const void *)imagePNG.data); 261 | } 262 | else { 263 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 264 | GL_LINEAR_MIPMAP_LINEAR); 265 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 266 | GL_LINEAR); 267 | gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB8, 268 | imagePNG.sizeX, imagePNG.sizeY, 269 | GL_RGB, 270 | GL_UNSIGNED_BYTE, (const void *)imagePNG.data); 271 | } 272 | 273 | // Now we need to free the image data that we loaded since OpenGL stored it as a texture 274 | 275 | if (imagePNG.data) // If there is texture data 276 | { 277 | free(imagePNG.data); // Free the texture data, we don't need it anymore 278 | } 279 | } 280 | 281 | ////////////////////////////////////////////////////////////////////// 282 | // SAVE IMAGE 283 | ////////////////////////////////////////////////////////////////////// 284 | 285 | /* Attempts to save PNG to file; returns 0 on success, non-zero on error. */ 286 | int writepng(char *filename, char *description, 287 | int x, int y, int width, int height) { 288 | RGBPixel *image; 289 | int bytes_per_pixel = 3; 290 | 291 | FILE *fp; 292 | png_structp png_ptr = NULL; 293 | png_infop info_ptr = NULL; 294 | png_uint_32 bytes_per_row; 295 | png_byte **row_pointers = NULL; 296 | 297 | fp = fopen(filename, "wb"); 298 | if (fp == NULL) { 299 | return 1; 300 | } 301 | image = (RGBPixel *) malloc(width * height * sizeof(struct _RGBPixel)); 302 | 303 | /* OpenGL's default 4 byte pack alignment would leave extra bytes at the 304 | end of each image row so that each full row contained a number of bytes 305 | divisible by 4. Ie, an RGB row with 3 pixels and 8-bit componets would 306 | be laid out like "RGBRGBRGBxxx" where the last three "xxx" bytes exist 307 | just to pad the row out to 12 bytes (12 is divisible by 4). To make sure 308 | the rows are packed as tight as possible (no row padding), set the pack 309 | alignment to 1. */ 310 | glPixelStorei(GL_PACK_ALIGNMENT, 1); 311 | glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, (void *)image); 312 | 313 | /* Initialize the write struct. */ 314 | png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 315 | if (png_ptr == NULL) { 316 | fclose(fp); 317 | return -1; 318 | } 319 | 320 | /* Initialize the info struct. */ 321 | info_ptr = png_create_info_struct(png_ptr); 322 | if (info_ptr == NULL) { 323 | png_destroy_write_struct(&png_ptr, NULL); 324 | fclose(fp); 325 | return 1; 326 | } 327 | 328 | /* Set up error handling. */ 329 | if (setjmp(png_jmpbuf(png_ptr))) { 330 | png_destroy_write_struct(&png_ptr, &info_ptr); 331 | fclose(fp); 332 | return 1; 333 | } 334 | 335 | /* Set image attributes. */ 336 | png_set_IHDR(png_ptr, 337 | info_ptr, 338 | width, 339 | height, 340 | 8, 341 | PNG_COLOR_TYPE_RGB, 342 | PNG_INTERLACE_NONE, 343 | PNG_COMPRESSION_TYPE_DEFAULT, 344 | PNG_FILTER_TYPE_DEFAULT); 345 | 346 | /* Initialize rows of PNG. */ 347 | bytes_per_row = width * bytes_per_pixel; 348 | row_pointers = (png_byte **)png_malloc(png_ptr, height * sizeof(png_byte *)); 349 | unsigned char *pixels = (unsigned char *)image; 350 | for (int j = height - 1; j >= 0 ; --j) { 351 | unsigned char *row = (unsigned char *)png_malloc(png_ptr, sizeof(unsigned char) * bytes_per_row); 352 | row_pointers[j] = (png_byte *)row; 353 | memcpy(row_pointers[j], pixels, bytes_per_pixel * width); 354 | pixels += bytes_per_pixel * width; 355 | // for (int i = 0; i < width; ++i) { 356 | // RGBPixel color = *(image + (j * bytes_per_row) + (i * bytes_per_pixel)); 357 | // *row++ = color.red; 358 | // *row++ = color.green; 359 | // *row++ = color.blue; 360 | // } 361 | } 362 | 363 | /* Actually write the image data. */ 364 | png_init_io(png_ptr, fp); 365 | png_set_rows(png_ptr, info_ptr, row_pointers); 366 | png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); 367 | 368 | /* Cleanup. */ 369 | for (int j = 0; j < height; j++) { 370 | png_free(png_ptr, row_pointers[j]); 371 | } 372 | png_free(png_ptr, row_pointers); 373 | 374 | /* Finish writing. */ 375 | png_destroy_write_struct(&png_ptr, &info_ptr); 376 | free(image); 377 | fclose(fp); 378 | return 0; 379 | } 380 | -------------------------------------------------------------------------------- /src/texpng.h: -------------------------------------------------------------------------------- 1 | #define PNG_BYTES_TO_CHECK 4 2 | // This stores png data 3 | struct tImagePNG 4 | { 5 | int bytesPerPixel; 6 | int sizeX; 7 | int sizeY; 8 | unsigned char *data; 9 | }; 10 | 11 | typedef struct tImagePNG *PtImagePNG; 12 | 13 | void loadPngTex(char * fname , struct tImagePNG * pImagePNG , int *hasAlpha ); 14 | void ReverseImage( int width , int height , unsigned char *data , int bytesPerPixel ); 15 | void CheckImageDimensions( int sizeX , int sizeY , char * strFileName); 16 | void CreateTexturePNG(unsigned int *textureId, char * strFileName); 17 | int writepng(char *filename, char *description, 18 | int x, int y, int width, int height); 19 | -------------------------------------------------------------------------------- /src/urotate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MODULE: urotate.c 3 | * 4 | * FUNCTION: 5 | * This module contains three different routines that compute rotation 6 | * matricies and return these to user. 7 | * Detailed description is provided below. 8 | * 9 | * HISTORY: 10 | * Developed & written, Linas Vepstas, Septmeber 1991 11 | * double precision port, March 1993 12 | * 13 | * DETAILED DESCRIPTION: 14 | * This module contains three routines: 15 | * -------------------------------------------------------------------- 16 | * 17 | * void urot_about_axis (float m[16], --- returned 18 | * float angle, --- input 19 | * float axis[3]) --- input 20 | * Computes a rotation matrix. 21 | * The rotation is around the the direction specified by the argument 22 | * argument axis[3]. User may specify vector which is not of unit 23 | * length. The angle of rotation is specified in degrees, and is in the 24 | * right-handed direction. 25 | * 26 | * void rot_about_axis (float angle, --- input 27 | * float axis[3]) --- input 28 | * Same as above routine, except that the matrix is multiplied into the 29 | * GL matrix stack. 30 | * 31 | * -------------------------------------------------------------------- 32 | * 33 | * void urot_axis (float m[16], --- returned 34 | * float omega, --- input 35 | * float axis[3]) --- input 36 | * Same as urot_about_axis(), but angle specified in radians. 37 | * It is assumed that the argument axis[3] is a vector of unit length. 38 | * If it is not of unit length, the returned matrix will not be correct. 39 | * 40 | * void rot_axis (float omega, --- input 41 | * float axis[3]) --- input 42 | * Same as above routine, except that the matrix is multiplied into the 43 | * GL matrix stack. 44 | * 45 | * -------------------------------------------------------------------- 46 | * 47 | * void urot_omega (float m[16], --- returned 48 | * float omega[3]) --- input 49 | * same as urot_axis(), but the angle is taken as the length of the 50 | * vector omega[3] 51 | * 52 | * void rot_omega (float omega[3]) --- input 53 | * Same as above routine, except that the matrix is multiplied into the 54 | * GL matrix stack. 55 | * 56 | * -------------------------------------------------------------------- 57 | */ 58 | 59 | #include 60 | #include "glutil.h" 61 | 62 | /* Some files do not define M_PI... */ 63 | #ifndef M_PI 64 | #define M_PI 3.14159265358979323846 65 | #endif 66 | 67 | /* ========================================================== */ 68 | 69 | void urot_axis_f (float m[16], /* returned */ 70 | float omega, /* input */ 71 | float axis[3]) /* input */ 72 | { 73 | double s, c, ssq, csq, cts; 74 | double tmp; 75 | 76 | /* 77 | * The formula coded up below can be derived by using the 78 | * homomorphism between SU(2) and O(3), namely, that the 79 | * 3x3 rotation matrix R is given by 80 | * t.R.v = S(-1) t.v S 81 | * where 82 | * t are the Pauli matrices (similar to Quaternions, easier to use) 83 | * v is an arbitrary 3-vector 84 | * and S is a 2x2 hermitian matrix: 85 | * S = exp ( i omega t.axis / 2 ) 86 | * 87 | * (Also, remember that computer graphics uses the transpose of R). 88 | * 89 | * The Pauli matrices are: 90 | * 91 | * tx = (0 1) ty = (0 -i) tz = (1 0) 92 | * (1 0) (i 0) (0 -1) 93 | * 94 | * Note that no error checking is done -- if the axis vector is not 95 | * of unit length, you'll get strange results. 96 | */ 97 | 98 | tmp = (double) omega / 2.0; 99 | s = sin (tmp); 100 | c = cos (tmp); 101 | 102 | ssq = s*s; 103 | csq = c*c; 104 | 105 | m[0*4+0] = m[1*4+1] = m[2*4+2] = csq - ssq; 106 | 107 | ssq *= 2.0; 108 | 109 | /* on-diagonal entries */ 110 | m[0*4+0] += ssq * axis[0]*axis[0]; 111 | m[1*4+1] += ssq * axis[1]*axis[1]; 112 | m[2*4+2] += ssq * axis[2]*axis[2]; 113 | 114 | /* off-diagonal entries */ 115 | m[0*4+1] = m[1*4+0] = axis[0] * axis[1] * ssq; 116 | m[1*4+2] = m[2*4+1] = axis[1] * axis[2] * ssq; 117 | m[2*4+0] = m[0*4+2] = axis[2] * axis[0] * ssq; 118 | 119 | cts = 2.0 * c * s; 120 | 121 | tmp = cts * axis[2]; 122 | m[0*4+1] += tmp; 123 | m[1*4+0] -= tmp; 124 | 125 | tmp = cts * axis[0]; 126 | m[1*4+2] += tmp; 127 | m[2*4+1] -= tmp; 128 | 129 | tmp = cts * axis[1]; 130 | m[2*4+0] += tmp; 131 | m[0*4+2] -= tmp; 132 | 133 | /* homogeneous entries */ 134 | m[0*4+3] = m[1*4+3] = m[2*4+3] = m[3*4+2] = m[3*4+1] = m[3*4+0] = 0.0; 135 | m[3*4+3] = 1.0; 136 | 137 | 138 | } 139 | 140 | /* ========================================================== */ 141 | 142 | void urot_about_axis_f (float m[16], /* returned */ 143 | float angle, /* input */ 144 | float axis[3]) /* input */ 145 | { 146 | float len, ax[3]; 147 | 148 | angle *= M_PI/180.0; /* convert to radians */ 149 | 150 | /* renormalize axis vector, if needed */ 151 | len = axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]; 152 | 153 | /* we can save some machine instructions by normalizing only 154 | * if needed. The compiler should be able to schedule in the 155 | * if test "for free". */ 156 | if (len != 1.0) { 157 | len = (float) (1.0 / sqrt ((double) len)); 158 | ax[0] = axis[0] * len; 159 | ax[1] = axis[1] * len; 160 | ax[2] = axis[2] * len; 161 | urot_axis_f (m, angle, ax); 162 | } else { 163 | urot_axis_f (m, angle, axis); 164 | } 165 | } 166 | 167 | /* ========================================================== */ 168 | 169 | void urot_omega_f (float m[16], /* returned */ 170 | float axis[3]) /* input */ 171 | { 172 | float len, ax[3]; 173 | 174 | /* normalize axis vector */ 175 | len = axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]; 176 | 177 | len = (float) (1.0 / sqrt ((double) len)); 178 | ax[0] = axis[0] * len; 179 | ax[1] = axis[1] * len; 180 | ax[2] = axis[2] * len; 181 | 182 | /* the amount of rotation is equal to the length, in radians */ 183 | urot_axis_f (m, len, ax); 184 | } 185 | 186 | /* ======================= END OF FILE ========================== */ 187 | --------------------------------------------------------------------------------