diff --git a/5balls.rt4 b/5balls.rt4 new file mode 100644 index 0000000..dcc18f3 --- /dev/null +++ b/5balls.rt4 @@ -0,0 +1,17 @@ +RT 3.0 +CAMERA 0. 1. 5. 0. 0. 0. 0. 1. 1. 100. 1. 100. 400 400 +SCENE 20. 20. 80. 40. 40. 40. null +MATERIAL 0. 255. 0. 255. 255. 255. 20. 1. 0. 1. null +MATERIAL 0. 0. 0. 255. 255. 255. 40. 1. 0. 1. formica.bmp +MATERIAL 255. 0. 0. 255. 255. 255. 20. 1. 0. 1. null +MATERIAL 0. 0. 255. 255. 255. 255. 20. 1. 0. 1. null +MATERIAL 0. 255. 255. 255. 255. 255. 20. 1. 0. 1. null +MATERIAL 255. 0. 255. 255. 255. 255. 20. 1. 0. 1. null +LIGHT 40. 20. 10. 255. 255. 255. +LIGHT -40. 40. 10. 255. 255. 255. +SPHERE 0 3. 0. 3. -12. +SPHERE 2 3. -3. -3. -10. +SPHERE 3 3. 3. -3. -10. +SPHERE 4 3. -3. 1. -16. +SPHERE 5 3. 3. 1. -16. +BOX 1 -30. -8. -40. 30. -7. 0. diff --git a/IconLib.c b/IconLib.c new file mode 100644 index 0000000..f2710d1 --- /dev/null +++ b/IconLib.c @@ -0,0 +1,868 @@ +/* Arquivo gerado automaticamente por ledc 2.4 */ + +#include +#include + +static Ihandle* named[ 1 ]; + +static Ihandle* decl( char* name, Ihandle* elem, char* first, ...) +{ + char *attr, *val; + va_list arg; + va_start (arg, first); + attr = first; + while (attr) + { + val = va_arg(arg,char*); + IupSetAttribute( elem, attr, val ); + attr = va_arg(arg,char*); + } + va_end (arg); + if(name) IupSetHandle( name, elem ); + return elem; +} + +static void icon_lib_configure (void) +{ + char map[] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 6, 6, 6, 3, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 1, 1, 4, 4, 2, 2, 2, 2, 2, 0, 4, 4, 2, 2, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 1, 5, 6, 0, 0, 2, 6, 3, 2, 2, 0, 0, 0, 5, 6, 0, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 1, 6, 5, 6, 1, 2, 6, 3, 2, 2, 0, 1, 5, 6, 5, 0, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 0, 1, 6, 5, 6, 2, 6, 3, 2, 2, 0, 5, 6, 5, 1, 0, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 0, 1, 6, 6, 0, 2, 6, 3, 2, 2, 0, 0, 5, 6, 1, 0, 4, 4, 4, 4, 4, + 4, 4, 1, 1, 1, 1, 5, 6, 0, 6, 2, 6, 3, 2, 2, 0, 6, 0, 5, 6, 0, 0, 0, 4, 4, 4, + 4, 4, 1, 5, 6, 5, 6, 5, 6, 0, 2, 6, 3, 2, 2, 0, 0, 5, 6, 5, 6, 5, 6, 0, 4, 4, + 4, 4, 0, 1, 1, 1, 1, 6, 5, 6, 0, 0, 0, 0, 0, 0, 5, 6, 5, 0, 1, 1, 1, 0, 4, 4, + 4, 4, 0, 1, 1, 1, 0, 1, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 1, 0, 1, 1, 1, 0, 4, 4, + 4, 4, 0, 1, 1, 0, 5, 6, 5, 0, 0, 1, 5, 6, 1, 0, 0, 6, 5, 6, 0, 1, 1, 0, 4, 4, + 4, 4, 4, 0, 0, 1, 1, 5, 0, 1, 1, 1, 6, 5, 0, 1, 1, 1, 6, 1, 0, 0, 0, 4, 4, 4, + 4, 4, 4, 4, 4, 1, 5, 0, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 0, 0, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 1, 5, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 1, 5, 0, 0, 4, 4, 1, 1, 1, 0, 4, 4, 0, 1, 1, 0, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 4, 0, 1, 1, 0, 4, 4, 4, 0, 0, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + -1 }; + + decl( "icon_lib_configure", IupImage( 26, 26, map ), + "0", "0 0 0", + "1", "132 132 0", + "2", "132 132 132", + "3", "198 198 198", + "4", "BGCOLOR", + "5", "255 255 0", + "6", "255 255 255", 0 ); + + decl( "icon_lib_configure_inactive", IupImage( 26, 26, map ), + "0", "96 96 96", + "1", "96 96 96", + "2", "132 132 132", + "3", "198 198 198", + "4", "BGCOLOR", + "5", "192 192 192", + "6", "192 192 192", 0 ); +} + +static void icon_lib_capture (void) +{ + char map[] = { + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11, 4, 4, 4,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11, 4,14,14,12,10,10,13,12, 7, 7,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11, 4, 7,10,12,12,12, 1, 1,13, 6, 2, 2, 1,12,11,11,11,11,11,11, + 11,11,11,11,11,14, 7,13, 7,12, 1,13,13, 6, 6,10,10,10, 2, 6, 1,11,11,11,11,11, + 11,11,11,11,14, 1, 1,12, 1,13,10,10, 2,16,16,16, 2, 2,16,16, 8,13,11,11,11,11, + 11,11,11,14,12,12,12, 1,10, 2,16,15,15, 8,15,15,15,15,15,15,15, 2,13,11,11,11, + 11,11,11,12, 6, 1,13,10,16,15, 8, 8, 8, 8, 8, 8, 8,15,15,15, 8, 8,10,11,11,11, + 11,11, 7, 1, 1,13,10,15,15,15, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,19,19, 6,11,11, + 11,11,12,13,13, 6,16,15, 8,16, 4, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 3,10,11,11, + 11,11, 1,13, 6, 2,15, 8, 8,16, 5, 5, 5,16,15, 8, 8, 8, 8, 8, 8,19, 3, 2,11,11, + 11,13, 1,10,10,15,15, 8, 8,16, 5, 5, 5, 5,14, 1, 8, 8, 8, 8, 8,19, 3, 9,11,11, + 11,12,16,10, 2,15, 8, 8, 8,16, 5, 5, 5, 5, 5, 5, 5, 2,15, 8, 8,19, 3, 9,10,11, + 11, 1,16, 2,16,15, 8, 8, 8,16, 5, 5, 5, 5, 5, 5, 5, 5, 4,13, 8,19, 3,18,10,11, + 11, 1,10,15,15,15, 8, 8, 8,16, 5, 5, 5, 5, 5, 5, 5,14,15, 8, 8, 3, 9, 9,10,11, + 11,11, 6,15,15,15, 8, 8, 8,16, 5, 5, 5, 5, 5, 4, 2, 8, 8, 8, 8, 3, 9,15,11,11, + 11,11,10, 8, 8, 8, 8, 8, 8,16, 5, 5, 5,14,15, 8, 8, 8, 8, 8,19, 9, 0,15,11,11, + 11,11,13, 8,19, 8, 8, 8, 8,16, 5,17,16, 8, 8, 8, 8, 8, 8,19, 3, 9, 0, 2,11,11, + 11,11,11,10,19, 8, 8, 8, 8,15,16, 8, 8, 8, 8, 8, 8, 8, 8,19, 9, 0,15,11,11,11, + 11,11,11, 6,16,19,19,19, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,19, 9,18, 8,10,11,11,11, + 11,11,11,11, 2, 9, 3, 3,19,19, 8, 8, 8, 8, 8, 8,19, 3, 9, 0, 0, 2,11,11,11,11, + 11,11,11,11,11, 2,15, 9, 9, 3, 3, 3,19, 3, 3, 3, 9,18, 0, 8, 2,11,11,11,11,11, + 11,11,11,11,11,11, 2,15,18, 9, 9, 9, 9, 9, 9,18, 0, 0,15,10,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,16,15, 8, 9, 9, 9, 8,15,15,16,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11, 2, 2,16,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + -1 }; + + decl( "icon_lib_capture", IupImage( 26, 26, map ), + "0", "120 18 25", + "1", "242 146 153", + "2", "232 83 94", + "3", "184 26 36", + "4", "251 203 207", + "5", "255 255 255", + "6", "236 115 123", + "7", "244 175 179", + "8", "221 31 45", + "9", "157 23 32", + "10", "236 101 110", + "11", "BGCOLOR", + "12", "244 160 168", + "13", "236 129 136", + "14", "244 190 194", + "15", "228 45 57", + "16", "228 72 82", + "17", "252 214 212", + "18", "136 20 28", + "19", "200 29 42", 0 ); + + decl( "icon_lib_capture_inactive", IupImage( 26, 26, map ), + "0", "96 96 96", + "1", "96 96 96", + "2", "96 96 96", + "3", "96 96 96", + "4", "96 96 96", + "5", "192 192 192", + "6", "96 96 96", + "7", "96 96 96", + "8", "96 96 96", + "9", "96 96 96", + "10", "96 96 96", + "11", "BGCOLOR", + "12", "96 96 96", + "13", "96 96 96", + "14", "96 96 96", + "15", "96 96 96", + "16", "96 96 96", + "17", "96 96 96", + "18", "96 96 96", + "19", "96 96 96", 0 ); +} + +static void icon_lib_connect (void) +{ + char map[] = { + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 7, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 7, 7, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 3, 0, 6, 6, 6, 6, 6, 6, 6, 6, + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 4, 4, 4, 4, 3, 0, 6, 6, 6, 6, 0, 0, 0, 6, + 0, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 3, 3, 3, 3, 0, 6, 6, 6, 0, 7, 7, 0, 6, + 0, 7, 4, 7, 3, 4, 4, 7, 3, 4, 4, 0, 3, 3, 0, 0, 0, 6, 6, 0, 0, 7, 7, 7, 0, 6, + 0, 7, 4, 3, 3, 4, 4, 3, 3, 4, 4, 0, 3, 0, 3, 0, 0, 0, 0, 7, 0, 7, 4, 4, 0, 6, + 0, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 3, 3, 0, 7, 7, 0, 7, 0, 4, 4, 4, 0, 6, + 0, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 4, 0, 7, 7, 0, 4, 0, 4, 4, 4, 0, 6, + 0, 7, 4, 7, 3, 4, 4, 7, 3, 7, 7, 7, 7, 7, 7, 0, 4, 4, 0, 4, 0, 4, 4, 4, 0, 6, + 0, 7, 4, 3, 3, 4, 4, 3, 3, 7, 4, 4, 4, 4, 4, 0, 3, 3, 0, 4, 0, 4, 4, 4, 0, 6, + 0, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 0, 3, 3, 0, 3, 0, 4, 4, 4, 0, 6, + 0, 7, 4, 5, 5, 2, 2, 1, 1, 7, 4, 4, 4, 4, 4, 0, 0, 0, 0, 3, 0, 3, 4, 4, 0, 6, + 0, 7, 4, 5, 5, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 0, 6, 6, 6, 0, 0, 3, 3, 3, 0, 6, + 0, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 0, 0, 0, 0, 0, 6, 6, 6, 0, 3, 3, 0, 6, + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 7, 7, 7, 7, 3, 0, 6, 6, 6, 0, 0, 0, 6, + 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 3, 0, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 3, 3, 3, 3, 0, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + -1 }; + + decl( "icon_lib_connect", IupImage( 26, 26, map ), + "0", "0 0 0", + "1", "0 0 255", + "2", "0 255 0", + "3", "128 128 128", + "4", "192 192 192", + "5", "255 0 0", + "7", "255 255 255", + "6", "BGCOLOR", 0 ); +} +static void icon_lib_open (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 4, 0, 1, 1, 1, 0, 4, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, + 0, 0, 1, 3, 2, 3, 2, 3, 2, 3, 2, 3, 1, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 1, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 3, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 2, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 3, 2, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 1, 2, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 4, 4, 4, 4, 0, 0, 0, 0, + 0, 0, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 4, 4, 4, 4, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_open", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "000 000 000", + "2", "255 255 000", + "3", "255 255 255", + "4", "128 128 128", + "5", "132 132 000", 0 ); +} + +static void icon_lib_print (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 3, 1, 1, 1, 1, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 3, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 2, 1, 2, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 2, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 5, 5, 5, 2, 2, 1, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 4, 4, 4, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_print", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "074 074 074", + "2", "214 214 214", + "3", "255 255 255", + "4", "255 255 074", + "5", "165 165 165", 0 ); +} + +static void icon_lib_preview (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 3, 4, 4, 3, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 3, 5, 5, 4, 3, 3, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 4, 5, 4, 4, 3, 4, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 4, 4, 4, 4, 3, 4, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 3, 4, 4, 5, 3, 3, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 3, 4, 4, 3, 1, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 3, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_preview", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "074 074 074", + "2", "255 255 255", + "3", "165 165 165", + "4", "214 214 214", + "5", "074 255 255", 0 ); +} + +static void icon_lib_search (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 1, 1, 1, 0, 1, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 1, 1, 1, 0, 0, 0, 0, 0, 1, 2, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 1, 1, 1, 0, 0, 0, 0, 0, 1, 2, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_search", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "000 000 000", + "2", "255 255 255", 0 ); +} + +static void icon_lib_new (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_new", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "000 000 000", + "2", "255 255 255", 0 ); +} + +static void icon_lib_cut (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_cut", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "000 000 132", + "2", "000 000 000", 0 ); +} + +static void icon_lib_undo (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_undo", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "000 000 000", 0 ); +} + +static void icon_lib_redo (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_redo", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "000 000 000", 0 ); +} + +static void icon_lib_copy (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 1, 1, 2, 1, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 1, 1, 1, 1, 3, 2, 2, 2, 2, 3, 2, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 2, 1, 1, 2, 3, 3, 3, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 1, 1, 1, 1, 3, 2, 2, 2, 2, 2, 2, 2, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1, 2, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 2, 2, 2, 2, 2, 2, 2, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 1, 1, 1, 1, 1, 2, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 2, 2, 2, 2, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_copy", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "000 000 000", + "2", "255 255 255", + "3", "000 000 132", 0 ); +} + +static void icon_lib_paste (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 4, 4, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 3, 2, 3, 1, 4, 1, 1, 4, 1, 2, 3, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 3, 1, 3, 3, 3, 3, 3, 3, 1, 2, 3, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 3, 2, 3, 2, 3, 5, 5, 5, 5, 5, 5, 5, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 3, 2, 3, 2, 5, 6, 6, 6, 6, 6, 5, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 3, 2, 3, 2, 3, 5, 6, 6, 6, 6, 6, 5, 6, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 3, 2, 3, 2, 5, 6, 5, 5, 5, 6, 5, 5, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 3, 2, 3, 2, 3, 5, 6, 6, 6, 6, 6, 6, 6, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 3, 2, 3, 2, 5, 6, 5, 5, 5, 5, 5, 6, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 5, 6, 6, 6, 6, 6, 6, 6, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_paste", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "000 000 000", + "2", "132 132 000", + "3", "206 206 206", + "4", "255 255 000", + "5", "000 000 132", + "6", "255 255 255", 0 ); +} + +static void icon_lib_help (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 2, 2, 4, 2, 2, 2, 4, 2, 2, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 4, 2, 2, 2, 4, 2, 2, 2, 4, 2, 1, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 2, 2, 6, 5, 5, 5, 5, 6, 2, 2, 1, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 4, 2, 5, 5, 4, 6, 5, 5, 4, 2, 1, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 2, 2, 5, 3, 2, 2, 5, 5, 2, 2, 1, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 4, 2, 2, 2, 4, 3, 5, 3, 4, 2, 1, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 2, 2, 4, 2, 3, 5, 6, 2, 2, 2, 1, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 4, 2, 2, 2, 5, 3, 2, 2, 4, 2, 1, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 2, 2, 4, 2, 2, 2, 4, 2, 2, 2, 1, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 4, 2, 2, 2, 5, 5, 2, 2, 4, 2, 1, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 2, 2, 4, 2, 4, 2, 4, 2, 2, 2, 1, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 1, 4, 1, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_help", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "074 074 074", + "2", "255 255 255", + "3", "165 165 165", + "4", "255 255 074", + "5", "074 074 165", + "6", "214 214 214", 0 ); +} + +static void icon_lib_zoom_in (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 1, 1, 1, 2, 2, 1, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 1, 1, 1, 2, 2, 1, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 1, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_zoom_in", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "206 206 206", + "2", "000 000 000", 0 ); +} + +static void icon_lib_zoom_out (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 1, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_zoom_out", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "206 206 206", + "2", "000 000 000", 0 ); +} + +static void icon_lib_capture1 (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 3, 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 3, 1, 1, 3, 2, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 3, 1, 1, 3, 3, 3, 3, 2, 1, 2, 2, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 2, 1, 1, 2, 2, 1, 1, 1, 3, 3, 1, 2, 3, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 2, 1, 3, 3, 3, 3, 1, 2, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 2, 3, 2, 1, 1, 3, 3, 2, 1, 2, 3, 2, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 2, 3, 1, 1, 1, 3, 2, 1, 3, 1, 3, 2, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 2, 3, 1, 1, 1, 3, 2, 1, 4, 1, 2, 2, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 2, 3, 3, 1, 1, 3, 2, 2, 2, 3, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_capture", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "000 000 000", + "2", "132 132 132", + "3", "255 255 255", + "4", "000 000 132", 0 ); +} + +static void icon_lib_transfer (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 3, 1, 2, 1, 1,11, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 7, 5, 4, 6, 4, 5, 6, 5, 4, 4, 5,12, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 4, 7, 9,10, 5, 5, 4, 5, 4, 4, 5, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 5, 7, 5, 4, 6, 4, 4, 5, 6, 4,15, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 4, 8, 9,10, 4, 5, 4, 5, 5, 4, 5, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 6, 6, 9, 9, 5, 9, 9, 9, 1, 2, 1, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 5, 5, 4, 5, 5, 4, 5, 3,13,13,13,13, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 5, 5, 9,10, 4, 8, 1,13,13,13, 1,13,13, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 4, 7, 9, 9, 5,12,13,13,13,13, 1, 1,13,13, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 5, 4, 5, 4, 4, 1,13, 1, 1, 1,11,14, 1,13, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 4, 5, 4, 5, 5, 2,13,11, 1, 2, 1, 1,11,13, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 3, 1, 2, 1,11, 1,13,13,13,13, 1, 1,13,13, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,13,13,13, 1,13,13, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,14,13,13,13,13, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,11, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_transfer", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "000 000 000", + "2", "020 016 000", + "3", "000 000 008", + "4", "247 255 247", + "5", "204 204 204", + "6", "247 247 255", + "7", "239 239 247", + "8", "247 255 239", + "9", "000 000 123", + "10", "136 135 175", + "11", "000 008 008", + "12", "016 004 012", + "13", "255 255 000", + "14", "008 000 000", + "15", "239 247 243", 0 ); +} + +static void icon_lib_freeze (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 1, 1, 1, 1, 1, 0, 2, 3, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 3, 0,13, 4, 8, 8, 2, 4, 2, 6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 4, 0, 0, 3, 7, 9, 8, 2,11, 2, 6, 6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 4, 1, 0, 9,11,11, 8, 2,15, 2,14, 6,10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 3, 5, 3, 8, 8, 7,11, 2, 6, 6, 6, 6, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 4, 0, 4,11, 9, 8, 7, 9, 2, 6, 6, 2, 2, 2, 6, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 9,11,11, 8, 8, 4, 2,10, 2, 7, 7, 7, 2,10, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1,11, 8, 8, 4, 8, 7, 2, 7, 7, 2,14, 6,10, 0, 0, 0, 0, + 0, 0, 0, 1, 3, 8, 8, 8, 1, 8, 4,12, 4, 7, 5, 7, 2, 2, 6, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 8, 8, 2, 8, 4,12, 4, 7, 7, 6, 7, 7, 2,14, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2,12, 4,13, 6, 7, 9, 7,13, 6,14,14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 7, 2, 7,13,12, 6,13, 7, 7, 6,14, 2, 6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 6, 7, 7, 6,14, 6, 6,10, 6, 7, 2,14, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,10, 6, 7, 5, 1, 2, 2, 2,10,14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,10,14, 6,14,10, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_freeze", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "153 150 158", + "2", "127 062 032", + "3", "255 239 239", + "4", "241 239 209", + "5", "129 139 079", + "6", "004 000 000", + "7", "187 164 039", + "8", "255 255 148", + "9", "253 244 188", + "10", "017 009 000", + "11", "255 255 214", + "12", "255 206 008", + "13", "255 189 008", + "14", "002 006 008", + "15", "255 255 222", 0 ); +} + +static void icon_lib_save (void) +{ + char map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 1, 1, 1, 1, 1, 1, 3, 3, 1, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 1, 1, 1, 1, 1, 1, 3, 3, 1, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 1, 1, 1, 1, 1, 1, 3, 3, 1, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1 }; + + decl( "icon_lib_save", IupImage( 23, 23, map ), + "ORIGIN", "EdPatt", + "0", "BGCOLOR", + "1", "074 074 074", + "2", "234 234 142", + "3", "255 255 255", 0 ); +} + + +void IconLibOpen(void) +{ + /* files and projects */ + icon_lib_new (); + icon_lib_open (); + icon_lib_save (); + + /* camera */ + icon_lib_connect (); + icon_lib_capture (); + icon_lib_capture1 (); + icon_lib_configure (); + icon_lib_transfer (); + icon_lib_freeze (); + + /* print */ + icon_lib_print (); + icon_lib_preview (); + + /* undo */ + icon_lib_undo (); + icon_lib_redo (); + + /* cut, copy and paste */ + icon_lib_cut (); + icon_lib_copy (); + icon_lib_paste (); + + /* zoom */ + icon_lib_zoom_in (); + icon_lib_zoom_out (); + + /* serach */ + icon_lib_search (); + icon_lib_help (); +} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7499924 --- /dev/null +++ b/Makefile @@ -0,0 +1,43 @@ +OUT=tmp +SRC= \ + algebra.c \ + camera.c \ + color.c \ + image.c \ + light.c \ + mainIUP.c \ + material.c \ + object.c \ + raytracing.c\ + scene.c + +# Configs +CC=gcc +RM=rm +MV=mv +CFLAGS=-O2 -Wall `pkg-config gl --cflags` -I /usr/include/iup -ggdb +LIBS=-liup -liupgl -liupimglib + + +MAKEFILE=Makefile +OBJ=$(SRC:.c=.o) + +.c.o: + $(CC) -c $(CFLAGS) $< + +$(OUT): $(OBJ) + $(CC) $(CFLAGS) $(LIBS) $^ -o $@ + +clean: + $(RM) $(OBJ) $(OUT) + +depend: + if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \ + then \ + sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \ + $(MAKEFILE).$$$$ && \ + $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \ + fi + echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \ + >> $(MAKEFILE); \ + $(CC) -M $(SRC) >> $(MAKEFILE) diff --git a/RedBricks.bmp b/RedBricks.bmp new file mode 100644 index 0000000..13bd678 Binary files /dev/null and b/RedBricks.bmp differ diff --git a/algebra.c b/algebra.c new file mode 100644 index 0000000..f4346a4 --- /dev/null +++ b/algebra.c @@ -0,0 +1,729 @@ +/** + * @file algebra.c Algebra: operações com vetores e matrizes. + * @author Maira Noronha, Rodrigo Espinha e Marcelo Gattass + * + * @date + * Criado em: 3/5/2003. + * Última Modificação: 26/5/2003. + * + * @version 1 + */ + + +#include +#include +#include +#include "algebra.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846264338 +#endif + +#define real double + +/************************************************************************/ +/* Funções Exportadas */ +/************************************************************************/ + +Vector algVector( real x, real y, real z, real w ) +{ + Vector v = {x, y, z, w}; + return v; +} + +real algGetX(Vector vector) +{ + return vector.x; +} + +real algGetY(Vector vector) +{ + return vector.y; +} + +real algGetZ(Vector vector) +{ + return vector.z; +} + +real algGetW(Vector vector) +{ + return vector.w; +} + +Vector algCartesian( Vector vector ) +{ + if ((vector.w!=1)&&((vector.w>1.0e-9)||(vector.w<-1.0e-9))) + { + vector.x /= vector.w; + vector.y /= vector.w; + vector.z /= vector.w; + vector.w = 1; + } + return vector; +} + +Vector algAdd( Vector v1, Vector v2 ) +{ + Vector v = {v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w}; + return v; +} + +Vector algScale( real scalar, Vector vector ) +{ + Vector v = {scalar*vector.x, scalar*vector.y, scalar*vector.z, vector.w}; + return v; +} + +Vector algSub( Vector v1, Vector v2 ) +{ + Vector v = {v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w}; + return v; +} + +Vector algMinus( Vector vector ) +{ + Vector v = {-vector.x, -vector.y, -vector.z, vector.w}; + return v; +} + +real algNorm( Vector vector ) +{ + return (real) sqrt(vector.x*vector.x + vector.y*vector.y + vector.z*vector.z); +} + +Vector algUnit( Vector vector ) +{ + real n = algNorm(vector); + if ( n > 1e-9 ) { + return algScale(1/n, vector); + } else { + return vector; + } +} + +real algDot( Vector v1, Vector v2 ) +{ + return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; +} + +real algDot4( Vector v1, Vector v2 ) +{ + return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + v1.w*v2.w; +} + +Vector algProj( Vector ofVector, Vector ontoVector ) +{ + Vector vProjectVector; + real fNewScale = algDot(ofVector, ontoVector)/algDot(ontoVector,ontoVector); + vProjectVector = algScale(fNewScale , ontoVector); + return vProjectVector; +} + +Vector algCross( Vector v1, Vector v2 ) +{ + Vector v = { + v1.y*v2.z - v1.z*v2.y, + v1.z*v2.x - v1.x*v2.z, + v1.x*v2.y - v1.y*v2.x, + 1 + }; + return v; +} + +Vector algReflect( Vector ofVector, Vector aroundVector ) +{ + Vector vProj = algProj(ofVector,aroundVector); + Vector vIncrH = algSub(vProj,ofVector); + Vector vReflect = algAdd(vProj, vIncrH); + return vReflect; +} + +Vector algLinComb( int count, ... ) +{ + Vector result = { 0, 0, 0, 1 }; + va_list arglist; + + va_start( arglist, count ); + + while( count-- ) + { + real scalar = va_arg( arglist, real ); + Vector vector = va_arg( arglist, Vector ); + + result.x += ( scalar * vector.x ); + result.y += ( scalar * vector.y ); + result.z += ( scalar * vector.z ); + } + va_end( arglist ); + return result; +} + +Matrix algMatrix4x4( real a11, real a12, real a13, real a14, + real a21, real a22, real a23, real a24, + real a31, real a32, real a33, real a34, + real a41, real a42, real a43, real a44) +{ + Matrix m; + m.m[0]=a11; m.m[4]=a12; m.m[8]=a13; m.m[12]=a14; + m.m[1]=a21; m.m[5]=a22; m.m[9]=a23; m.m[13]=a24; + m.m[2]=a31; m.m[6]=a32; m.m[10]=a33; m.m[14]=a34; + m.m[3]=a41; m.m[7]=a42; m.m[11]=a43; m.m[15]=a44; + return m; +} + +real algGetElem(Matrix m, int i, int j) +{ + return m.m[((j-1)<<2)+(i-1)]; +} + +real * algGetOGLMatrix(Matrix *m) +{ + return m->m; +} + +Vector algTransf( Matrix matrix, Vector vector ) +{ + Vector v = { + matrix.m[0]*vector.x + matrix.m[4]*vector.y + matrix.m[8]*vector.z + matrix.m[12]*vector.w, + matrix.m[1]*vector.x + matrix.m[5]*vector.y + matrix.m[9]*vector.z + matrix.m[13]*vector.w, + matrix.m[2]*vector.x + matrix.m[6]*vector.y + matrix.m[10]*vector.z + matrix.m[14]*vector.w, + matrix.m[3]*vector.x + matrix.m[7]*vector.y + matrix.m[11]*vector.z + matrix.m[15]*vector.w + }; + return v; +} + +Matrix algMatrixIdent(void) +{ + Matrix m; + m.m[0] = 1; m.m[4] = 0; m.m[8] = 0; m.m[12] = 0; + m.m[1] = 0; m.m[5] = 1; m.m[9] = 0; m.m[13] = 0; + m.m[2] = 0; m.m[6] = 0; m.m[10] = 1; m.m[14] = 0; + m.m[3] = 0; m.m[7] = 0; m.m[11] = 0; m.m[15] = 1; + return m; +} + +Matrix algMatrixTransl(real tx, real ty, real tz) +{ + Matrix m; + m.m[0] = 1; m.m[4] = 0; m.m[8] = 0; m.m[12] = tx; + m.m[1] = 0; m.m[5] = 1; m.m[9] = 0; m.m[13] = ty; + m.m[2] = 0; m.m[6] = 0; m.m[10] = 1; m.m[14] = tz; + m.m[3] = 0; m.m[7] = 0; m.m[11] = 0; m.m[15] = 1; + return m; +} + +Matrix algMatrixScale(real scalex, real scaley, real scalez) +{ + Matrix m; + m.m[0] = scalex; m.m[4] = 0; m.m[8] = 0; m.m[12] = 0; + m.m[1] = 0; m.m[5] = scaley; m.m[9] = 0; m.m[13] = 0; + m.m[2] = 0; m.m[6] = 0; m.m[10] = scalez; m.m[14] = 0; + m.m[3] = 0; m.m[7] = 0; m.m[11] = 0; m.m[15] = 1; + return m; +} + +Matrix algMatrixRotate(real angle, real ex, real ey, real ez) +{ + Matrix m; + real norm = (real) sqrt(ex*ex + ey*ey + ez*ez); + + /* Converte graus para radianos. */ + angle = (angle* (real) M_PI)/180; + + if ( norm >= 1e-9 ) { + real cos_a, sin_a; + + cos_a = (real) cos(angle); + sin_a = (real) sin(angle); + + ex /= norm; ey /= norm; ez /= norm; + + m.m[0] = cos_a + (1 - cos_a)*ex*ex; //Linha 1 + m.m[4] = ex*ey*(1 - cos_a) - ez*sin_a; + m.m[8] = ez*ex*(1 - cos_a) + ey*sin_a; + m.m[12] = 0; + + m.m[1] = ex*ey*(1 - cos_a) + ez*sin_a; + m.m[5] = cos_a + (1 - cos_a)*ey*ey; + m.m[9] = ey*ez*(1 - cos_a) - ex*sin_a; + m.m[13] = 0; + + m.m[2] = ex*ez*(1 - cos_a) - ey*sin_a; + m.m[6] = ey*ez*(1 - cos_a) + ex*sin_a; + m.m[10] = cos_a + (1 - cos_a)*ez*ez; + m.m[14] = 0; + + m.m[3] = 0; + m.m[7] = 0; + m.m[11] = 0; + m.m[15] = 1; + } else { + /* Matriz identidade. */ + m.m[0] = 1; m.m[4] = 0; m.m[8] = 0; m.m[12] = 0; + m.m[1] = 0; m.m[5] = 1; m.m[9] = 0; m.m[13] = 0; + m.m[2] = 0; m.m[6] = 0; m.m[10] = 1; m.m[14] = 0; + m.m[3] = 0; m.m[7] = 0; m.m[11] = 0; m.m[15] = 1; + } + return m; +} + +Matrix algMatrixAdd( Matrix m1, Matrix m2 ) +{ + Matrix m; + m.m[0] = m1.m[0] + m2.m[0]; m.m[4] = m1.m[4] + m2.m[4]; m.m[8] = m1.m[8] + m2.m[8]; m.m[12] = m1.m[12] + m2.m[12]; + m.m[1] = m1.m[1] + m2.m[1]; m.m[5] = m1.m[5] + m2.m[5]; m.m[9] = m1.m[9] + m2.m[9]; m.m[13] = m1.m[13] + m2.m[13]; + m.m[2] = m1.m[2] + m2.m[2]; m.m[6] = m1.m[6] + m2.m[6]; m.m[10] = m1.m[10] + m2.m[10]; m.m[14] = m1.m[14] + m2.m[14]; + m.m[3] = m1.m[3] + m2.m[3]; m.m[7] = m1.m[7] + m2.m[7]; m.m[11] = m1.m[11] + m2.m[11]; m.m[15] = m1.m[15] + m2.m[15]; + return m; +} + +Matrix algMatrixScalarProduct( real scale, Matrix m1 ) +{ + Matrix m; + m.m[0] = scale*m1.m[0]; m.m[4] = scale*m1.m[4]; m.m[8] = scale*m1.m[8]; m.m[12] = scale*m1.m[12]; + m.m[1] = scale*m1.m[1]; m.m[5] = scale*m1.m[5]; m.m[9] = scale*m1.m[9]; m.m[13] = scale*m1.m[13]; + m.m[2] = scale*m1.m[2]; m.m[6] = scale*m1.m[6]; m.m[10] = scale*m1.m[10]; m.m[14] = scale*m1.m[14]; + m.m[3] = scale*m1.m[3]; m.m[7] = scale*m1.m[7]; m.m[11] = scale*m1.m[11]; m.m[15] = scale*m1.m[15]; + return m; +} + +Matrix algMult( Matrix m1, Matrix m2 ) +{ + Matrix m; + m.m[0] = m1.m[0]*m2.m[0] + m1.m[4]*m2.m[1] + m1.m[8]*m2.m[2] + m1.m[12]*m2.m[3]; + m.m[1] = m1.m[1]*m2.m[0] + m1.m[5]*m2.m[1] + m1.m[9]*m2.m[2] + m1.m[13]*m2.m[3]; + m.m[2] = m1.m[2]*m2.m[0] + m1.m[6]*m2.m[1] + m1.m[10]*m2.m[2] + m1.m[14]*m2.m[3]; + m.m[3] = m1.m[3]*m2.m[0] + m1.m[7]*m2.m[1] + m1.m[11]*m2.m[2] + m1.m[15]*m2.m[3]; + + m.m[4] = m1.m[0]*m2.m[4] + m1.m[4]*m2.m[5] + m1.m[8]*m2.m[6] + m1.m[12]*m2.m[7]; + m.m[5] = m1.m[1]*m2.m[4] + m1.m[5]*m2.m[5] + m1.m[9]*m2.m[6] + m1.m[13]*m2.m[7]; + m.m[6] = m1.m[2]*m2.m[4] + m1.m[6]*m2.m[5] + m1.m[10]*m2.m[6] + m1.m[14]*m2.m[7]; + m.m[7] = m1.m[3]*m2.m[4] + m1.m[7]*m2.m[5] + m1.m[11]*m2.m[6] + m1.m[15]*m2.m[7]; + + m.m[8] = m1.m[0]*m2.m[8] + m1.m[4]*m2.m[9] + m1.m[8]*m2.m[10] + m1.m[12]*m2.m[11]; + m.m[9] = m1.m[1]*m2.m[8] + m1.m[5]*m2.m[9] + m1.m[9]*m2.m[10] + m1.m[13]*m2.m[11]; + m.m[10] = m1.m[2]*m2.m[8] + m1.m[6]*m2.m[9] + m1.m[10]*m2.m[10] + m1.m[14]*m2.m[11]; + m.m[11] = m1.m[3]*m2.m[8] + m1.m[7]*m2.m[9] + m1.m[11]*m2.m[10] + m1.m[15]*m2.m[11]; + + m.m[12] = m1.m[0]*m2.m[12] + m1.m[4]*m2.m[13] + m1.m[8]*m2.m[14] + m1.m[12]*m2.m[15]; + m.m[13] = m1.m[1]*m2.m[12] + m1.m[5]*m2.m[13] + m1.m[9]*m2.m[14] + m1.m[13]*m2.m[15]; + m.m[14] = m1.m[2]*m2.m[12] + m1.m[6]*m2.m[13] + m1.m[10]*m2.m[14] + m1.m[14]*m2.m[15]; + m.m[15] = m1.m[3]*m2.m[12] + m1.m[7]*m2.m[13] + m1.m[11]*m2.m[14] + m1.m[15]*m2.m[15]; + return m; +} + +real algDet( Matrix m ) +{ + return + m.m[0] * + ( m.m[5] * (m.m[10]*m.m[15] - m.m[14]*m.m[11]) - + m.m[9] * (m.m[6]*m.m[15] - m.m[14]*m.m[7]) + + m.m[13] * (m.m[6]*m.m[11] - m.m[10]*m.m[7]) ) - + m.m[4] * + ( m.m[1] * (m.m[10]*m.m[15] - m.m[14]*m.m[11]) - + m.m[9] * (m.m[2]*m.m[15] - m.m[14]*m.m[3]) + + m.m[13] * (m.m[2]*m.m[11] - m.m[10]*m.m[3]) ) + + m.m[8] * + ( m.m[1] * (m.m[6]*m.m[15] - m.m[14]*m.m[7]) - + m.m[5] * (m.m[2]*m.m[15] - m.m[14]*m.m[3]) + + m.m[13] * (m.m[2]*m.m[7] - m.m[6]*m.m[3]) ) - + m.m[12] * + ( m.m[1] * (m.m[6]*m.m[11] - m.m[10]*m.m[7]) - + m.m[5] * (m.m[2]*m.m[11] - m.m[10]*m.m[3]) + + m.m[9] * (m.m[2]*m.m[7] - m.m[6]*m.m[3]) ); +} + +Matrix algInv( Matrix m) +{ + real d; + Matrix r; + + d = algDet(m); + + + r.m[0] = ( m.m[5] * (m.m[10]*m.m[15] - m.m[14]*m.m[11]) + m.m[6] * (-m.m[9]*m.m[15] + m.m[13]*m.m[11]) + + m.m[7] * (m.m[9]*m.m[14] - m.m[13]*m.m[10]) ) / d; + + r.m[4] = - ( m.m[4] * (m.m[10]*m.m[15] - m.m[14]*m.m[11]) + m.m[6] * (-m.m[8]*m.m[15] + m.m[12]*m.m[11]) + + m.m[7] * (m.m[8]*m.m[14] - m.m[12]*m.m[10]) ) / d; + + r.m[8] = ( m.m[4] * (m.m[9]*m.m[15] - m.m[13]*m.m[11]) + m.m[5] * (-m.m[8]*m.m[15] + m.m[12]*m.m[11]) + + m.m[7] * (m.m[8]*m.m[13] - m.m[12]*m.m[9]) ) / d; + + r.m[12] = - ( m.m[4] * (m.m[9]*m.m[14] - m.m[13]*m.m[10]) + m.m[5] * (-m.m[8]*m.m[14] + m.m[12]*m.m[10]) + + m.m[6] * (m.m[8]*m.m[13] - m.m[12]*m.m[9]) ) / d; + + + + r.m[1] = - ( m.m[1] * (m.m[10]*m.m[15] - m.m[14]*m.m[11]) + m.m[2] * (-m.m[9]*m.m[15] + m.m[13]*m.m[11]) + + m.m[3] * (m.m[9]*m.m[14] - m.m[13]*m.m[10]) ) / d; + + r.m[5] = ( m.m[0] * (m.m[10]*m.m[15] - m.m[14]*m.m[11]) + m.m[2] * (-m.m[8]*m.m[15] + m.m[12]*m.m[11]) + + m.m[3] * (m.m[8]*m.m[14] - m.m[12]*m.m[10]) ) / d; + + r.m[9] = - ( m.m[0] * (m.m[9]*m.m[15] - m.m[13]*m.m[11]) + m.m[1] * (-m.m[8]*m.m[15] + m.m[12]*m.m[11]) + + m.m[3] * (m.m[8]*m.m[13] - m.m[12]*m.m[9]) ) / d; + + r.m[13] = ( m.m[0] * (m.m[9]*m.m[14] - m.m[13]*m.m[10]) + m.m[1] * (-m.m[8]*m.m[14] + m.m[12]*m.m[10]) + + m.m[2] * (m.m[8]*m.m[13] - m.m[12]*m.m[9]) ) / d; + + + + r.m[2] = ( m.m[1] * (m.m[6]*m.m[15] - m.m[14]*m.m[7]) + m.m[2] * (-m.m[5]*m.m[15] + m.m[13]*m.m[7]) + + m.m[3] * (m.m[5]*m.m[14] - m.m[13]*m.m[6]) ) / d; + + r.m[6] = - ( m.m[0] * (m.m[6]*m.m[15] - m.m[14]*m.m[7]) + m.m[2] * (-m.m[4]*m.m[15] + m.m[12]*m.m[7]) + + m.m[3] * (m.m[4]*m.m[14] - m.m[12]*m.m[6]) ) / d; + + r.m[10] = ( m.m[0] * (m.m[5]*m.m[15] - m.m[13]*m.m[7]) + m.m[1] * (-m.m[4]*m.m[15] + m.m[12]*m.m[7]) + + m.m[3] * (m.m[4]*m.m[13] - m.m[12]*m.m[5]) ) / d; + + r.m[14] = - ( m.m[0] * (m.m[5]*m.m[14] - m.m[13]*m.m[6]) + m.m[1] * (-m.m[4]*m.m[14] + m.m[12]*m.m[6]) + + m.m[2] * (m.m[4]*m.m[13] - m.m[12]*m.m[5]) ) / d; + + + + r.m[3] = - ( m.m[1] * (m.m[6]*m.m[11] - m.m[10]*m.m[7]) + m.m[2] * (-m.m[5]*m.m[11] + m.m[9]*m.m[7]) + + m.m[3] * (m.m[5]*m.m[10] - m.m[9]*m.m[6]) ) / d; + + r.m[7] = ( m.m[0] * (m.m[6]*m.m[11] - m.m[10]*m.m[7]) + m.m[2] * (-m.m[4]*m.m[11] + m.m[8]*m.m[7]) + + m.m[3] * (m.m[4]*m.m[10] - m.m[8]*m.m[6]) ) / d; + + r.m[11] = - ( m.m[0] * (m.m[5]*m.m[11] - m.m[9]*m.m[7]) + m.m[1] * (-m.m[4]*m.m[11] + m.m[8]*m.m[7]) + + m.m[3] * (m.m[4]*m.m[9] - m.m[8]*m.m[5]) ) / d; + + r.m[15] = ( m.m[0] * (m.m[5]*m.m[10] - m.m[9]*m.m[6]) + m.m[1] * (-m.m[4]*m.m[10] + m.m[8]*m.m[6]) + + m.m[2] * (m.m[4]*m.m[9] - m.m[8]*m.m[5]) ) / d; + return r; +} + +Vector algSolve( Matrix m, Vector b ) +{ + double s1,s2,s3,s4,s5; + Vector result = {0, 0, 0, 0}; /* Vetor inválido */ + + double det = algDet(m); + + if ( fabs(det) < 1e-8 ) { + return result; + } + + s2 = ( m.m[5] * (m.m[10]*m.m[15] - m.m[14]*m.m[11]) + m.m[6] * (-m.m[9]*m.m[15] + m.m[13]*m.m[11]) + + m.m[7] * (m.m[9]*m.m[14] - m.m[13]*m.m[10]) ) * b.x / det; + s3 = - ( m.m[4] * (m.m[10]*m.m[15] - m.m[14]*m.m[11]) + m.m[6] * (-m.m[8]*m.m[15] + m.m[12]*m.m[11]) + + m.m[7] * (m.m[8]*m.m[14] - m.m[12]*m.m[10]) ) * b.y / det; + s1 = s2 + s3; + s2 = s1; + s4 = ( m.m[4] * (m.m[9]*m.m[15] - m.m[13]*m.m[11]) + m.m[5] * (-m.m[8]*m.m[15] + m.m[12]*m.m[11]) + + m.m[7] * (m.m[8]*m.m[13] - m.m[12]*m.m[9]) ) * b.z / det; + s5 = - ( m.m[4] * (m.m[9]*m.m[14] - m.m[13]*m.m[10]) + m.m[5] * (-m.m[8]*m.m[14] + m.m[12]*m.m[10]) + + m.m[6] * (m.m[8]*m.m[13] - m.m[12]*m.m[9]) ) * b.w / det; + s3 = s4 + s5; + result.x = (real) (s2 + s3); + + s2 = - ( m.m[1] * (m.m[10]*m.m[15] - m.m[14]*m.m[11]) + m.m[2] * (-m.m[9]*m.m[15] + m.m[13]*m.m[11]) + + m.m[3] * (m.m[9]*m.m[14] - m.m[13]*m.m[10]) ) * b.x / det; + s3 = ( m.m[0] * (m.m[10]*m.m[15] - m.m[14]*m.m[11]) + m.m[2] * (-m.m[8]*m.m[15] + m.m[12]*m.m[11]) + + m.m[3] * (m.m[8]*m.m[14] - m.m[12]*m.m[10]) ) * b.y / det; + s1 = s2 + s3; + s2 = s1; + s4 = - ( m.m[0] * (m.m[9]*m.m[15] - m.m[13]*m.m[11]) + m.m[1] * (-m.m[8]*m.m[15] + m.m[12]*m.m[11]) + + m.m[3] * (m.m[8]*m.m[13] - m.m[12]*m.m[9]) ) * b.z / det; + s5 = ( m.m[0] * (m.m[9]*m.m[14] - m.m[13]*m.m[10]) + m.m[1] * (-m.m[8]*m.m[14] + m.m[12]*m.m[10]) + + m.m[2] * (m.m[8]*m.m[13] - m.m[12]*m.m[9]) ) * b.w / det; + s3 = s4 + s5; + result.y = (real) (s2 + s3); + + s2 = ( m.m[1] * (m.m[6]*m.m[15] - m.m[14]*m.m[7]) + m.m[2] * (-m.m[5]*m.m[15] + m.m[13]*m.m[7]) + + m.m[3] * (m.m[5]*m.m[14] - m.m[13]*m.m[6]) ) * b.x / det; + s3 = - ( m.m[0] * (m.m[6]*m.m[15] - m.m[14]*m.m[7]) + m.m[2] * (-m.m[4]*m.m[15] + m.m[12]*m.m[7]) + + m.m[3] * (m.m[4]*m.m[14] - m.m[12]*m.m[6]) ) * b.y / det; + s1 = s2 + s3; + s2 = s1; + s4 = ( m.m[0] * (m.m[5]*m.m[15] - m.m[13]*m.m[7]) + m.m[1] * (-m.m[4]*m.m[15] + m.m[12]*m.m[7]) + + m.m[3] * (m.m[4]*m.m[13] - m.m[12]*m.m[5]) ) * b.z / det; + s5 = - ( m.m[0] * (m.m[5]*m.m[14] - m.m[13]*m.m[6]) + m.m[1] * (-m.m[4]*m.m[14] + m.m[12]*m.m[6]) + + m.m[2] * (m.m[4]*m.m[13] - m.m[12]*m.m[5]) ) * b.w / det; + s3 = s4 + s5; + result.z = (real) (s2 + s3); + + s2 = - ( m.m[1] * (m.m[6]*m.m[11] - m.m[10]*m.m[7]) + m.m[2] * (-m.m[5]*m.m[11] + m.m[9]*m.m[7]) + + m.m[3] * (m.m[5]*m.m[10] - m.m[9]*m.m[6]) ) * b.x / det; + s3 = ( m.m[0] * (m.m[6]*m.m[11] - m.m[10]*m.m[7]) + m.m[2] * (-m.m[4]*m.m[11] + m.m[8]*m.m[7]) + + m.m[3] * (m.m[4]*m.m[10] - m.m[8]*m.m[6]) ) * b.y / det; + s1 = s2 + s3; + s2 = s1; + s4 = - ( m.m[0] * (m.m[5]*m.m[11] - m.m[9]*m.m[7]) + m.m[1] * (-m.m[4]*m.m[11] + m.m[8]*m.m[7]) + + m.m[3] * (m.m[4]*m.m[9] - m.m[8]*m.m[5]) ) * b.z / det; + s5 = ( m.m[0] * (m.m[5]*m.m[10] - m.m[9]*m.m[6]) + m.m[1] * (-m.m[4]*m.m[10] + m.m[8]*m.m[6]) + + m.m[2] * (m.m[4]*m.m[9] - m.m[8]*m.m[5]) ) * b.w / det; + s3 = s4 + s5; + result.w = (real) (s2 + s3); + + return result; +} + +Matrix algTransp( Matrix m ) +{ + Matrix r; + r.m[0] = m.m[0]; r.m[4] = m.m[1]; r.m[8] = m.m[2]; r.m[12] = m.m[3]; + r.m[1] = m.m[4]; r.m[5] = m.m[5]; r.m[9] = m.m[6]; r.m[13] = m.m[7]; + r.m[2] = m.m[8]; r.m[6] = m.m[9]; r.m[10] = m.m[10]; r.m[14] = m.m[11]; + r.m[3] = m.m[12]; r.m[7] = m.m[13]; r.m[11] = m.m[14]; r.m[15] = m.m[15]; + return r; +} + +Vector algSnell(Vector in, Vector normal, double n1, double n2) +{ + double c_out; + Vector t, r; + Vector v = algUnit(algMinus(in)); + Vector vn = algProj(algMinus(in), normal); + Vector vt = algSub(vn, v); + double s_in = algNorm(vt); + double s_out = n1 * s_in / n2; + t = algUnit(vt); + if(s_out > 1.0) return t; + c_out = sqrt(1 - s_out * s_out); + r = algLinComb(2, s_out, t, 0 - (c_out), normal); + return r; +} + +Quat algQuat(real w, real x, real y, real z) +{ + Quat q = {w, x, y, z}; + return q; +} + +Quat algQuatAdd(Quat q1, Quat q2) +{ + Quat q = {q1.w + q2.w, q1.x + q2.x, q1.y + q2.y, q1.z + q2.z}; + return q; +} + +Quat algQuatSub(Quat q1, Quat q2) +{ + Quat q = {q1.w - q2.w, q1.x - q2.x, q1.y - q2.y, q1.z - q2.z}; + return q; +} + +Quat algQuatScale(real s, Quat q1) +{ + Quat q = {s*q1.w, s*q1.x, s*q1.y, s*q1.z}; + return q; +} + +Quat algQuatMult(Quat q1, Quat q2) +{ + Quat q = { + q1.w*q2.w - q1.x*q2.x - q1.y*q2.y - q1.z*q2.z, + q1.w*q2.x + q2.w*q1.x + q1.y*q2.z - q1.z*q2.y, + q1.w*q2.y + q2.w*q1.y + q1.z*q2.x - q1.x*q2.z, + q1.w*q2.z + q2.w*q1.z + q1.x*q2.y - q1.y*q2.x + }; + return q; +} + +real algQuatDot(Quat q1, Quat q2) +{ + return q1.w*q2.w + q1.x*q2.x + q1.y*q2.y + q1.z*q2.z; +} + +real algQuatNorm(Quat q1) +{ + return (real) (q1.w*q1.w + q1.x*q1.x + q1.y*q1.y + q1.z*q1.z); +} + +real algQuatEuclidianNorm(Quat q1) +{ + return (real) sqrt(q1.w*q1.w + q1.x*q1.x + q1.y*q1.y + q1.z*q1.z); +} + +Quat algQuatUnit(Quat q1) +{ + Quat q=q1; + real n = (real) sqrt(q1.w*q1.w + q1.x*q1.x + q1.y*q1.y + q1.z*q1.z); + if (n>1e-9) { + q.w = q1.w/n; + q.x = q1.x/n; + q.y = q1.y/n; + q.z = q1.z/n; + } + return q; +} + +Quat algQuatConj(Quat q1) +{ + Quat q = {q1.w, -q1.x, -q1.y, -q1.z}; + return q; +} + +Quat algQuatInv(Quat q1) +{ + real n = q1.w*q1.w + q1.x*q1.x + q1.y*q1.y + q1.z*q1.z; + Quat q = {q1.w/n, -q1.x/n, -q1.y/n, -q1.z/n}; + return q; +} + +Quat algQuatSLERP(Quat q1, Quat q2, real u) +{ + real cos_theta, theta, sin_theta; + + q1 = algQuatUnit(q1); + q2 = algQuatUnit(q2); + + cos_theta = q1.w*q2.w + q1.x*q2.x + q1.y*q2.y + q1.z*q2.z; + + if ( cos_theta < 0 ) + { + cos_theta = -cos_theta; + q2 = algQuatScale(-1, q2); + } + + theta = (real) acos(cos_theta); + sin_theta = (real) sin(theta); + + if ( (1 - cos_theta) > 1e-6 ) { + return algQuatAdd( + algQuatScale((real) sin((1 - u) * theta) / sin_theta, q1), + algQuatScale((real) sin(u * theta) / sin_theta, q2)); + } else { /* theta é quase 0 */ + /* Evita divisão por valor muito pequeno, aproveitando-se de + que sin(theta) é aprox. igual a theta, com theta muito pequeno.. */ + return algQuatAdd(algQuatScale(1 - u, q1), algQuatScale(u, q2)); + } +} + +Quat algQuatFromRot(real angle, Vector axis) +{ + Quat q; + real t, s, n; + + t = (angle * (real) M_PI)/360; + s = (real) sin(t); + n = (real) sqrt(axis.x*axis.x + axis.y*axis.y + axis.z*axis.z); + + q.w = (real) cos(t); + q.x = s*(axis.x/n); + q.y = s*(axis.y/n); + q.z = s*(axis.z/n); + return q; +} + +real algQuatRotAngle(Quat q) +{ + return (real) acos(q.w)*360 / (real) M_PI; +} + +Vector algQuatRotAxis(Quat q) +{ + Vector v = {q.x, q.y, q.z}; + return v; +} + +Quat algQuatFromMatrix(Matrix m) +{ + Quat q; + real tr = m.m[0] + m.m[5] + m.m[10]; /* Traço da matriz */ + real s; + + if ( tr > 0 ) + { + s = (real) sqrt(tr + 1); + + q.w = 0.5f * s; + s = 0.5f / s; + q.x = (m.m[6] - m.m[9]) * s; + q.y = (m.m[8] - m.m[2]) * s; + q.z = (m.m[1] - m.m[4]) * s; + } else + { + /* Descobre qual elemento da diagonal tem maior valor */ + real max = m.m[0]; + max = (m.m[5] > max ? m.m[5] : max); + max = (m.m[10] > max ? m.m[10] : max); + + if ( m.m[0] == max ) + { + /* Coluna 0 */ + s = (real) sqrt(m.m[0] - m.m[5] - m.m[10] + 1); + + q.x = 0.5f * s; + if ( s != 0 ) s = 0.5f / s; + + q.w = (m.m[6] - m.m[9] ) * s; + q.y = (m.m[1] + m.m[4] ) * s; + q.z = (m.m[2] + m.m[8] ) * s; + } else if ( m.m[5] == max ) + { + /* Coluna 1 */ + s = (real) sqrt(m.m[5] - m.m[0] - m.m[10] + 1); + + q.y = 0.5f * s; + if ( s != 0 ) s = 0.5f / s; + + q.w = (m.m[8] - m.m[2]) * s; + q.x = (m.m[1] + m.m[4]) * s; + q.z = (m.m[6] + m.m[9]) * s; + } else + { + /* Coluna 2: m[10] == max */ + s = (real) sqrt(m.m[10] - m.m[0] - m.m[5] + 1); + + q.z = 0.5f * s; + if ( s != 0 ) s = 0.5f / s; + + q.w = (m.m[1] - m.m[4]) * s; + q.x = (m.m[2] + m.m[8]) * s; + q.y = (m.m[6] + m.m[9]) * s; + } + } + return q; +} + +Matrix algQuatToMatrix(Quat q) +{ + Matrix m; + m.m[0] = 1 - 2*(q.y*q.y + q.z*q.z); + m.m[1] = 2*(q.x*q.y + q.z*q.w); + m.m[2] = 2*(q.x*q.z - q.y*q.w); + m.m[3] = 0; + + m.m[4] = 2*(q.x*q.y - q.z*q.w); + m.m[5] = 1 - 2*(q.x*q.x + q.z*q.z); + m.m[6] = 2*(q.y*q.z + q.x*q.w); + m.m[7] = 0; + + m.m[8] = 2*(q.x*q.z + q.y*q.w); + m.m[9] = 2*(q.y*q.z - q.x*q.w); + m.m[10] = 1 - 2*(q.x*q.x + q.y*q.y); + m.m[11] = 0; + + m.m[12] = 0; + m.m[13] = 0; + m.m[14] = 0; + m.m[15] = 1; + return m; +} + +void algVectorPrint(char *text, Vector v) +{ + printf("%s, [%g,%g,%g,%g]\n",text,v.x,v.y,v.z,v.w); +} + +void algMatrixPrint(char *text, Matrix m) +{ + printf("%s\n",text); + printf(" |%g %g %g %g|\n",m.m[0],m.m[4],m.m[ 8],m.m[12]); + printf(" |%g %g %g %g|\n",m.m[1],m.m[5],m.m[ 9],m.m[13]); + printf(" |%g %g %g %g|\n",m.m[2],m.m[6],m.m[10],m.m[14]); + printf(" |%g %g %g %g|\n",m.m[3],m.m[7],m.m[11],m.m[15]); +} + +void algQuatPrint(char *text, Quat v) +{ + printf("%s, [%g,%g,%g,%g]\n",text,v.x,v.y,v.z,v.w); +} + +#undef real diff --git a/algebra.h b/algebra.h new file mode 100644 index 0000000..d9201d2 --- /dev/null +++ b/algebra.h @@ -0,0 +1,386 @@ +/** + * @file algebra.h Algebra: operações com vetores e matrizes. + * + * @date + * Criado em: Mar2003 + * Última Modificação: Mai2003 + * + */ + +#ifndef _ALGEBRA_H_ +#define _ALGEBRA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************/ +/* Tipos Exportados */ +/************************************************************************/ + +#define real double + +/** + * Vetor no espaço 3D homogêneo. + * Para representar vetores 2D, use z = 0 e w = 1. + * Para representar vetores 3D, use w = 1. + */ +typedef struct +{ +/** + * Valor na direcao x. + */ + real x; +/** + * Valor na direcao y. + */ + real y; +/** + * Valor na direcao z (z = 0 para vetores 2D). + */ + real z; +/** + * Valor de w (w = 1 para vetores 2D e 3D). + */ + real w; +} +Vector; + +/** + * Quaternio (w, (x,y,z)). + */ +typedef struct +{ +/** + * Valor de w. + */ + real w; +/** + * Valor na direcao x. + */ + real x; +/** + * Valor na direcao y. + */ + real y; +/** + * Valor na direcao z. + */ + real z; +} +Quat; + +/** + * Matriz homogenea no mesmo formato do OpenGL. + */ +typedef struct +{ +/** + * Matriz homogenea no mesmo formato do OpenGL (vetor de 16 elementos). + * + * Ordem dos elementos: + * M = ( m0, m4, m8, m12 ) + * ( m1, m5, m9, m13 ) + * ( m2, m6, m10, m14 ) + * ( m3, m7, m11, m15 ) + */ + real m[16]; +} Matrix; + + +/************************************************************************/ +/* Funções Exportadas */ +/************************************************************************/ + +/** + * Cria um vetor no espaço 3D homogêneo. + */ +Vector algVector( real x, real y, real z, real w ); + +/** + * Obtem a coordenada x de um vetor. + */ +real algGetX(Vector vector); + +/** + * Obtem a coordenada y de um vetor. + */ +real algGetY(Vector vector); + +/** + * Obtem a coordenada z de um vetor. + */ +real algGetZ(Vector vector); + +/** + * Obtem a coordenada w de um vetor. + */ +real algGetW(Vector vector); + +/** + * Projeta o vetor do espaco homogeneo (w!=1) + * no espaco cartesiano (w=1). + */ +Vector algCartesian( Vector vector ); + +/** + * Soma dois vetores do R3 (ignorando a componente w). + */ +Vector algAdd( Vector v1, Vector v2 ); + +/** + * Multiplica um vetor do R3 por um escalar(ignorando a componente w). + */ +Vector algScale( real scalar, Vector vector ); + +/** + * Subtrai dois vetores (ignorando a componente w). + */ +Vector algSub( Vector v1, Vector v2 ); + +/** + * Negativo de um vetor do R3 (ignorando a componente w). + */ +Vector algMinus( Vector vector ); + +/** + * Norma de um vetor do R3 (ignorando a componente w). + */ +real algNorm( Vector vector ); + +/** + * Vetor unitario direção de um vetor do R3 (ignorando a componente w). + */ +Vector algUnit( Vector vector ); + +/** + * Produto interno entre dois vetores do R3 (ignorando a componente w). + */ +real algDot( Vector v1, Vector v2 ); + +/** + * Produto interno entre dois vetores homogeneos, ou seja w e' uma componente. + */ +real algDot4( Vector v1, Vector v2 ); + +/** + * Projeta um vetor do R3 em outro, e retorna o vetor resultante (ignorando a componente w). + */ +Vector algProj( Vector ofVector, Vector ontoVector ); + +/** + * Produto vetorial entre dois vetores do R3 (ignorando a componente w). + */ +Vector algCross( Vector v1, Vector v2 ); + +/** + * Reflete um vetor do R3 em torno de outro (ignorando a componente w). + */ +Vector algReflect( Vector ofVector, Vector aroundVector ); + +/** + * Combinação linear de N vetores. + * + * O primeiro parâmetro indica N, o número de vetores sendo combinados. Os parâmetros + * seguintes são sempre pares [real scalar, Vector vector]. O vetor resultante é a + * soma de todos os vetores (scalar * vector) fornecidos, e normalizado (w = 1). + * + * Exemplo: para obter o vetor 2 * v1 + 4 * v2 + 8 * v3, use: + * vector = algLinComb( 3, 2.0, v1, 4.0, v2, 8.0, v3 ); + * + * @warning Sempre passe os escalares como real explicitamente (1.0 ao invés de 1). + */ +Vector algLinComb( int count, ... ); + +/** + * Cria uma matriz 4x4. + */ +Matrix algMatrix4x4( real a11, real a12, real a13, real a14, + real a21, real a22, real a23, real a24, + real a31, real a32, real a33, real a34, + real a41, real a42, real a43, real a44); + +/** + * Retorna o elemento i,j da matriz 4x4. + * Os valores validos de i e j sao 1,2,3 e 4. + */ +real algGetElem(Matrix m, int i, int j); + +/** + * Matriz para o OpenGL. + * Retorna um ponteiro do tipo real * para ser passado para o + * OpenGL como sendo a variavel que contem a matriz de + * transformacao. + */ +real * algGetOGLMatrix(Matrix *m); + +/** + * Multiplica um vetor por uma matriz. + */ +Vector algTransf( Matrix matrix, Vector vector ); + +/** + * Matriz identidade. + */ +Matrix algMatrixIdent(void); + +/** + * Matriz de translacao tx, ty, tz. + */ +Matrix algMatrixTransl(real tx, real ty, real tz); + +/** + * Matriz de escala. + */ +Matrix algMatrixScale(real scalex, real scaley, real scalez); + +/** + * Matriz de rotacao em torno de um eixo. + */ +Matrix algMatrixRotate(real angle, real ex, real ey, real ez); + +/** + * Soma duas matrizes colocando o resultando na terceira matriz. + */ +Matrix algMatrixAdd( Matrix m1, Matrix m2 ); + +/** + * Multiplica uma matriz por uma escalar retornando o a matriz resultante. + */ +Matrix algMatrixScalarProduct( real scale, Matrix m ); + +/** + * Multiplica duas matrizes colocando o resultando na terceira matriz. + */ +Matrix algMult( Matrix m1, Matrix m2 ); + +/** + * Calcula o determinante de uma matriz. + */ +real algDet( Matrix matrix ); + +/** + * Calcula a matriz inversa, retornando 0 caso nao consiga + */ +Matrix algInv( Matrix matrix); + +/** + * Resolve o sistema Mx=b. + */ +Vector algSolve( Matrix matrix, Vector b ); + +/** + * Transpõe uma Matriz + */ +Matrix algTransp( Matrix m ); + +Vector algSnell(Vector in, Vector normal, double n1, double n2); + +/** + * Cria um quaternio + */ +Quat algQuat(real w, real x, real y, real z); + +/** + * Soma de quaternios. + */ +Quat algQuatAdd(Quat q1, Quat q2); + +/** + * Subtracao de quaternios. + */ +Quat algQuatSub(Quat q1, Quat q2); + +/** + * Multiplicacao de quaternio por escalar. + */ +Quat algQuatScale(real s, Quat q1); + +/** + * Multiplicacao de quaternios. + */ +Quat algQuatMult(Quat q1, Quat q2); + +/** + * Produto interno de quaternios. + */ +real algQuatDot(Quat q1, Quat q2); + +/** + * Norma de quaternios. + */ +real algQuatNorm(Quat q1); + +/** + * Norma euclidiana de quaternios. + */ +real algQuatEuclidianNorm(Quat q1); + +/** + * Soma de quaternios. + */ +Quat algQuatUnit(Quat q1); + +/** + * Conjugado de um quaternio. + */ +Quat algQuatConj(Quat q1); + +/** + * Inverso de um quaternio. + */ +Quat algQuatInv(Quat q1); + +/** + * Interpolacao linear esferiaca de quaternios, SLERP (Spherical Linear Interpolation). + */ +Quat algQuatSLERP(Quat q1, Quat q2, real u); + +/** + * Quaternio que representa uma rotacao de "angle" (em radianos) em torno do eixo "axis" + * que e' definido por um vetor que pode nao ser unitario. + */ +Quat algQuatFromRot(real angle, Vector axis); + +/** + * Angulo de rotacao representado em um quaternio. + */ +real algQuatRotAngle(Quat q); + +/** + * Eixo de rotacao representado em um quaternio. + */ +Vector algQuatRotAxis(Quat q); + +/** + * Quaternio correspondente a uma matriz de rotacao. + */ +Quat algQuatFromMatrix(Matrix m); + +/** + * Matriz de rotacao representada por um quaternio. + */ +Matrix algQuatToMatrix(Quat q); + +/** + * Imprime um vetor. + */ +void algVectorPrint(char *text, Vector v); + +/** + * Imprime uma matriz. + */ +void algMatrixPrint(char *text, Matrix m); + +/** + * Imprime um quaternio. + */ +void algQuatPrint(char *text, Quat v); + +#undef real + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/back.bmp b/back.bmp new file mode 100644 index 0000000..43afc82 Binary files /dev/null and b/back.bmp differ diff --git a/bolas.rt4 b/bolas.rt4 new file mode 100644 index 0000000..22235e7 --- /dev/null +++ b/bolas.rt4 @@ -0,0 +1,27 @@ +RT 4.0 +CAMERA 120. 50. 40. 0. 30. 0. 0. 1. 0. 90. 1. 100. 400 400 +SCENE 0. 0. 35. 30. 30. 30. null +MATERIAL 20. 50. 20. 255. 255. 255. 35. 1. 0.8 1.5 null +MATERIAL 20. 200. 200. 0. 0. 0. 2000. .6 0. 1. null +LIGHT 100. 100. 0. 185 185 185 +SPHERE 0 10.0 0.0 0. 0. +SPHERE 0 10.0 -17.32 0. -10. +SPHERE 0 10.0 -17.32 0. 10. +SPHERE 0 10.0 -34.64 0. -20. +SPHERE 0 10.0 -34.64 0. 0. +SPHERE 0 10.0 -34.64 0. 20. +SPHERE 0 10.0 -51.96 0. -10. +SPHERE 0 10.0 -51.96 0. 10. +SPHERE 0 10.0 -51.96 0. -30. +SPHERE 0 10.0 -51.96 0. 30. +SPHERE 0 10.0 -8.66 17.32 0. +SPHERE 0 10.0 -25.98 17.32 -10. +SPHERE 0 10.0 -25.98 17.32 10. +SPHERE 0 10.0 -43.3 17.32 -20. +SPHERE 0 10.0 -43.3 17.32 0. +SPHERE 0 10.0 -43.3 17.32 20. +SPHERE 0 10.0 -17.32 34.64 0. +SPHERE 0 10.0 -34.64 34.64 10. +SPHERE 0 10.0 -34.64 34.64 -10. +SPHERE 0 10.0 -25.98 51.96 0. +BOX 1 -500. -20. -500. 500. -10. 500. diff --git a/camera.c b/camera.c new file mode 100644 index 0000000..408b108 --- /dev/null +++ b/camera.c @@ -0,0 +1,222 @@ +/** + * @file camera.c Camera*: definição de câmeras e cálculos relacionados. + * + * @author + * - Maira Noronha + * - Thiago Bastos + * - Mauricio Carneiro + * + * @date + * Criado em: 30 de Novembro de 2002 + * Última Modificação: 22 de Janeiro de 2003 + * + * @version 2.0 + */ + +#include "camera.h" +#include +#include +#include + + +/************************************************************************/ +/* Constantes Privadas */ +/************************************************************************/ +#define M_PI 3.14159265358979323846 + +/** + * Camera no mesmo formato do OpenGL. + */ +struct _Camera +{ + /* Definição da câmera */ + + /** + * Posição da câmera (do observador). + */ + Vector eye; + /** + * Direção para onde o observador está olhando. + */ + Vector at; + /** + * Direção perpendicular a at que indica a orientação vertical da câmera. + */ + Vector up; + /** + * Abertura da câmera (ângulo de visão), de 0 a 180. + */ + double fovy; + /** + * Distância de eye até nearp (onde a cena será projetada). + */ + double nearp; + /** + * Distância de eye até farp (background). + */ + double farp; + /** + * Largura da tela em pixels. + */ + double screenWidth; + /** + * Altura da tela em pixels + */ + double screenHeight; + + /* Estado interno */ + + /** + * Direção x + */ + Vector xAxis; + /** + * Direção y + */ + Vector yAxis; + /** + * Direção z + */ + Vector zAxis; + /** + * Origem do near plane. + */ + Vector nearOrigin; + /** + * Vetor u do near plane. + */ + Vector nearU; + /** + * Vetor v do near plane. + */ + Vector nearV; + /** + * Origem do far plane. + */ + Vector farOrigin; + /** + * Vetor normal ao far plane. + */ + Vector farNormal; + /** + * Vetor u do far plane. + */ + Vector farU; + /** + * Vetor v do far plane. + */ + Vector farV; +}; + + +/************************************************************************/ +/* Funções Privadas */ +/************************************************************************/ +static void camResize( Camera* camera, int screenWidth, int screenHeight ); + + +/************************************************************************/ +/* Definição das Funções Exportadas */ +/************************************************************************/ +Camera* camCreate( Vector eye, Vector at, Vector up, double fovy, double nearp, double farp, + int screenWidth, int screenHeight ) +{ + Camera* camera = (struct _Camera *)malloc( sizeof(struct _Camera) ); + + /* Copia propriedades */ + camera->eye = eye; + camera->at = at; + camera->up = up; + camera->fovy = fovy; + camera->nearp = nearp; + camera->farp = farp; + + /* Calcula sistema de coordenadas da câmera */ + camera->zAxis = algUnit( algSub( eye, at ) ); + camera->xAxis = algUnit( algCross( up, camera->zAxis ) ); + camera->yAxis = algCross( camera->zAxis, camera->xAxis ); + + /* Inicia estado da câmera com as dimensões especificadas */ + camResize( camera, screenWidth, screenHeight ); + + return camera; +} + +void camGetFarPlane( Camera* camera, Vector *origin, Vector *normal, Vector *u, Vector *v ) +{ + *origin = camera->farOrigin; + *normal = camera->farNormal; + *u = camera->farU; + *v = camera->farV; +} + +Vector camGetEye( Camera* camera ) +{ + return camera->eye; +} + +Vector camGetRay( Camera* camera, double x, double y ) +{ + Vector u = algScale( ( x / camera->screenWidth ), camera->nearU ); + Vector v = algScale( ( y / camera->screenHeight ), camera->nearV ); + Vector point = algAdd( algAdd( camera->nearOrigin, u ), v ); + + return algUnit( algSub( point, camera->eye ) ); +} + +int camGetScreenWidth( Camera* camera ) +{ + return (int)camera->screenWidth; +} + +int camGetScreenHeight( Camera* camera ) +{ + return (int)camera->screenHeight; +} + + +void camDestroy( Camera* camera ) +{ + free( camera ); +} + + +/************************************************************************/ +/* Definição das Funções Privadas */ +/************************************************************************/ +static void camResize( Camera* camera, int screenWidth, int screenHeight ) +{ + double sx, sy, sz; + + camera->screenWidth = screenWidth; + camera->screenHeight = screenHeight; + + /* Calcula a origem do near plane */ + sz = camera->nearp; + sy = ( sz * tan( ( M_PI * camera->fovy ) / ( 2.0 * 180.0 ) ) ); + sx = ( ( sy * screenWidth ) / screenHeight ); + camera->nearOrigin = algLinComb( 4, + 1.0, camera->eye, + -sz, camera->zAxis, + -sy, camera->yAxis, + -sx, camera->xAxis ); + + /* Calcula os eixos (u,v) do near plane */ + camera->nearU = algScale( ( 2 * sx ), camera->xAxis ); + camera->nearV = algScale( ( 2 * sy ), camera->yAxis ); + + /* Calcula a origem do far plane */ + sz *= ( camera->farp / camera->nearp ); + sy *= ( camera->farp / camera->nearp ); + sx *= ( camera->farp / camera->nearp ); + camera->farOrigin = algLinComb( 4, + 1.0, camera->eye, + -sz, camera->zAxis, + -sy, camera->yAxis, + -sx, camera->xAxis ); + + /* Calcula os eixos (u,v) do far plane */ + camera->farU = algScale( ( 2 * sx ), camera->xAxis ); + camera->farV = algScale( ( 2 * sy ), camera->yAxis ); + camera->farNormal = algUnit( algCross( camera->farU, camera->farV ) ); +} diff --git a/camera.h b/camera.h new file mode 100644 index 0000000..1162558 --- /dev/null +++ b/camera.h @@ -0,0 +1,92 @@ +/** + * @file camera.h Camera*: definição de câmeras e cálculos relacionados. + * + * @author + * - Maira Noronha + * - Thiago Bastos + * - Mauricio Carneiro + * + * @date + * Criado em: 30 de Novembro de 2002 + * Última Modificação: 22 de Janeiro de 2003 + * + * @version 2.0 + */ + +#ifndef _CAMERA_H_ +#define _CAMERA_H_ + +#include "algebra.h" + + +/************************************************************************/ +/* Tipos Exportados */ +/************************************************************************/ + +typedef struct _Camera Camera; + + +/************************************************************************/ +/* Funções Exportadas */ +/************************************************************************/ +/** + * Cria uma nova câmera usando as propriedades especificadas. + * + * @param eye Posição da câmera (do observador). + * @param at Direção para onde o observador está olhando. + * @param up Direção perpendicular a at que indica a orientação vertical da câmera. + * @param fovy Abertura da câmera (ângulo de visão), de 0 a 180. + * @param nearp Distância de eye até nearp. + * @param farp Distância de eye até farp. + * @param screenWidth Largura da tela em pixels. + * @param screenHeight Altura da tela em pixels. + * + * @return Handle da câmera criada. + */ +Camera* camCreate( Vector eye, Vector at, Vector up, double fovy, double nearp, double farp, + int screenWidth, int screenHeight ); + +/** + * Obtém informações sobre o far plane definido para uma câmera. + * + * @param origin [out]Retorna a origem do far plane. + * @param normal [out]Retorna um vetor normal ao far plane. + * @param u [out]Retorna o vetor u do far plane. + * @param v [out]Retorna o vetor v do far plane. + */ +void camGetFarPlane( Camera* camera, Vector *origin, Vector *normal, Vector *u, Vector *v ); + +/** + * Obtém a posição de uma câmera. + * + * @return Posição do 'eye' da câmera. + */ +Vector camGetEye( Camera* camera ); + +/** + * Obtém um raio saindo do eye de uma câmera e passando por um pixel especificado. + * + * @param x Posição X do pixel por onde o raio deve passar. + * @param y Posição Y do pixel por onde o raio deve passar. + * + * @return Um raio saindo de eye e passando pelo pixel (x,y) no near plane. + */ +Vector camGetRay( Camera* camera, double x, double y ); + +/** + * Obtém a largura da tela de uma câmera, em pixels. + */ +int camGetScreenWidth( Camera* camera ); + +/** + * Obtém a altura da tela de uma câmera, em pixels. + */ +int camGetScreenHeight( Camera* camera ); + +/** + * Destrói uma câmera criada com camCreate(). + */ +void camDestroy( Camera* camera ); + +#endif + diff --git a/cavalo.rt4 b/cavalo.rt4 new file mode 100644 index 0000000..983f29b --- /dev/null +++ b/cavalo.rt4 @@ -0,0 +1,11 @@ +RT 4.0 +CAMERA 100. 100. 40. 0. 0. 0. 0. 1. 0. 90. 30. 230. 400 400 +SCENE 110. 110. 110. 90. 90. 130. null +MATERIAL 0. 0. 200. 10. 10. 200. 50. 0. 0.8 0.4 null +MATERIAL 180. 180. 0. 255. 255. 255. 40. 0. 0. 1. null +MATERIAL 180. 180. 0. 255. 255. 255. 40. 0. 0. 1. null +MATERIAL 0. 0. 0. 255. 255. 255. 40. 1. 0. 0. null +LIGHT 40. 120. 0. 255 255 255 +MESH 0 -20. 0. -20 20. 30.0 30.0 cavalo.um +BOX 1 -80. -50. -50. 50. -45. 50. +BOX 2 -80. -50. -60. 50. 50. -50. diff --git a/color.c b/color.c new file mode 100644 index 0000000..2139f81 --- /dev/null +++ b/color.c @@ -0,0 +1,70 @@ +/** + * @file color.c Color: manipulação de cores. + * + * @author + * - Maira Noronha + * - Thiago Bastos + * + * @date + * Criado em: 1 de Dezembro de 2002 + * Última Modificação: 22 de Janeiro de 2003 + * + * @version 2.0 + */ + +#include "color.h" + +#include + + +/************************************************************************/ +/* Constantes Privadas */ +/************************************************************************/ +#define MAX( a, b ) ( ( a > b ) ? a : b ) +#define MIN( a, b ) ( ( a < b ) ? a : b ) + +/************************************************************************/ +/* Definições das Funções Exportadas */ +/************************************************************************/ +Color colorCreate3b( unsigned char red, unsigned char green, unsigned char blue ) +{ + Color color= { (float)( red / 255.0 ), (float)( green / 255.0 ), (float)( blue / 255.0 ) }; + + return color; +} + +Color colorAddition( Color c1, Color c2 ) +{ + Color color = { (float)( c1.red + c2.red ), (float)( c1.green + c2.green ), (float)( c1.blue + c2.blue ) }; + + return color; +} + +Color colorScale( double s, Color c ) +{ + Color color = { (float)( s * c.red ), (float)( s * c.green ), (float)( s * c.blue ) }; + + return color; +} + +Color colorMultiplication( Color c1, Color c2 ) +{ + Color color = { (float)( c1.red * c2.red ), (float)( c1.green * c2.green ), (float)( c1.blue * c2.blue ) }; + + return color; +} + +Color colorReflection( double s, Color l, Color m ) +{ + Color color = { (float)( s * ( l.red * m.red ) ), (float)( s * ( l.green * m.green ) ), (float)( s * ( l.blue * m.blue ) ) }; + + return color; +} + +Color colorNormalize( Color c1 ) +{ + Color color= { (float)(c1.red/255.0), (float)(c1.green/255.0), (float)(c1.blue/255.0) }; + + return color; +} + diff --git a/color.h b/color.h new file mode 100644 index 0000000..cfe8632 --- /dev/null +++ b/color.h @@ -0,0 +1,78 @@ +/** + * @file color.h Color: manipulação de cores. + * + * @author + * - Maira Noronha + * - Thiago Bastos + * + * + * @date + * Criado em: 01 de Dezembro de 2002 + * Última Modificação: 22 de Janeiro de 2003 + * + * @version 2.0 + */ + +#ifndef _COLOR_H_ +#define _COLOR_H_ + +/************************************************************************/ +/* Tipos Exportados */ +/************************************************************************/ +/** + * Cor rgb. + */ +typedef struct color_impl +{ + /** + * Componente vermelha. + */ + float red; + /** + * Componente verde. + */ + float green; + /** + * Componente azul. + */ + float blue; +} +Color; + +/************************************************************************/ +/* Funções Exportadas */ +/************************************************************************/ +/** + * Cria uma cor a partir de 3 bytes RGB. + */ +Color colorCreate3b( unsigned char red, unsigned char green, unsigned char blue ); + +/** + * Soma duas cores. + */ +Color colorAddition( Color c1, Color c2 ); + +/** + * Amplia ou reduz o brilho de uma cor, multiplicando-o por um fator. + */ +Color colorScale( double scale, Color color ); + +/** + * Multiplica duas cores. + * Útil para obter a cor de um material iluminado por uma luz ambiente. + */ +Color colorMultiplication( Color c1, Color c2 ); + +/** + * Cor refletida por um material iluminado por uma certa luz, usando um + * coeficiente especificado (scale). Útil nos cálculos de iluminação. + */ +Color colorReflection( double scale, Color light, Color material ); + +/** + * Torna a faixa de valores de r, g e b entre 0 e 1. + */ +Color colorNormalize( Color color ); + +#endif + diff --git a/earth.bmp b/earth.bmp new file mode 100644 index 0000000..c29808a Binary files /dev/null and b/earth.bmp differ diff --git a/esfera.rt4 b/esfera.rt4 new file mode 100644 index 0000000..ae26228 --- /dev/null +++ b/esfera.rt4 @@ -0,0 +1,8 @@ +RT 4.0 +CAMERA 100. 40. 40. 0. 0. 0. 0. 1. 0. 90. 10. 100. 400 400 +SCENE 110. 110. 110. 30. 30. 80. watery.bmp +MATERIAL 0. 0. 255. 255. 255. 255. 50. 0. 0. 1. estrela.bmp +MATERIAL 180. 180. 0. 255. 255. 255. 40. 0. 0. 1. marmore.bmp +LIGHT 40. 120. 20. 255 255 255 +SPHERE 0 25.0 0.0 20.0 0.0 +BOX 1 -80. -50. -50. 50. -45. 50. diff --git a/esfera_planos.rt4 b/esfera_planos.rt4 new file mode 100644 index 0000000..5da2fcf --- /dev/null +++ b/esfera_planos.rt4 @@ -0,0 +1,9 @@ +RT 4.0 +CAMERA 100. 40. 40. 0. 0. 0. 0. 1. 0. 90. 30. 230. 400 400 +SCENE 110. 110. 110. 90. 90. 130. null +MATERIAL 0. 0. 255. 255. 255. 255. 50. 0. 0.8 0.4 null +MATERIAL 180. 180. 0. 255. 255. 255. 40. 0. 0. 1. null +LIGHT 40. 120. 0. 255 255 255 +SPHERE 0 25.0 0.0 20.0 0.0 +BOX 1 -80. -50. -50. 50. -45. 50. +BOX 1 -80. -50. -60. 50. 50. -50. diff --git a/esferas.rt4 b/esferas.rt4 new file mode 100644 index 0000000..59e6645 --- /dev/null +++ b/esferas.rt4 @@ -0,0 +1,10 @@ +RT 4.0 +CAMERA 0. 0. 150. 0. 0. 0. 0. 1. 0. 90. 1. 100. 400 400 +SCENE 30. 30. 30. 25. 25. 0. sky.bmp +MATERIAL 255. 255. 0. 225. 225. 225. 65. 0.9 0. 1. null +MATERIAL 0. 0. 0. 255. 255. 255. 45. 0.9 0. 1. null +MATERIAL 50. 50. 80. 70. 70. 90. 0. 0. 0. 1. null +LIGHT 0. 400. 80. 200 200 200 +SPHERE 1 40.0 45.0 0.0 0.0 +SPHERE 0 40.0 -45.0 0.0 0.0 +BOX 2 -200. -46. -60. 200. -44. 60. diff --git a/espelho.rt4 b/espelho.rt4 new file mode 100644 index 0000000..7a021bd --- /dev/null +++ b/espelho.rt4 @@ -0,0 +1,12 @@ +RT 4.0 +CAMERA 50. 70. 400. 0. 0. 150. 0. 1. 0. 90. 1. 100. 400 400 +SCENE 0. 100. 100. 100. 60. 40. null +MATERIAL 0. 50. 255. 50. 70. 255. 5. 0. 0. 1. null +MATERIAL 215. 215. 0. 225. 225. 30. 5. 0. 0. 1. null +MATERIAL 0. 0. 0. 255. 255. 255. 500. .6 0. 1. null +MATERIAL 0. 0. 0. 0. 0. 0. 500. 0. 0. 1. null +LIGHT 0. 400. 0. 200 200 200 +SPHERE 0 50.0 100.0 0.0 150.0 +SPHERE 1 50.0 -100.0 0.0 150.0 +BOX 2 -300. -150. -250. 350. 200. -170. +BOX 3 -310. -160. -201. 360. 210. -171. diff --git a/estrela.bmp b/estrela.bmp new file mode 100644 index 0000000..8a48327 Binary files /dev/null and b/estrela.bmp differ diff --git a/floor.bmp b/floor.bmp new file mode 100644 index 0000000..d203b05 Binary files /dev/null and b/floor.bmp differ diff --git a/formica.bmp b/formica.bmp new file mode 100644 index 0000000..4d45eb8 Binary files /dev/null and b/formica.bmp differ diff --git a/genericWall.bmp b/genericWall.bmp new file mode 100644 index 0000000..8bbc2cd Binary files /dev/null and b/genericWall.bmp differ diff --git a/image.c b/image.c new file mode 100644 index 0000000..1695f22 --- /dev/null +++ b/image.c @@ -0,0 +1,1537 @@ +/** + * @file image.c Image: operações imagens em formato TGA. + * + * @author + * - Maira Noronha + * - Fabiola Maffra + * - Marcelo Gattass + * + * @date + * Última Modificação: 23 de Abril de 2003 + * + * @version 2.0 + */ + +#include +#include +#include +#include +#include +#include +#include "color.h" +#include "image.h" + +/* Compiler dependent definitions */ +typedef unsigned char BYTE; +typedef unsigned short int USHORT; +typedef unsigned short int WORD; +typedef long int LONG; +typedef unsigned long int DWORD; + +#define ROUND(_) (int)floor( (_) + 0.5 ) + +struct Image_imp { + + int width; /* numero de pixels na direcao horizontal da imagem */ + int height; /* numero de pixels na direcao vertical da imagem */ + float *buf; /* vetor de dimensao 3*width*height que armazena consecutivamente as 3 componentes de cor de cada pixel a */ + /* partir do canto inferior esquerdo da imagem. A posicao das 3 componentes de cor do pixel (x,y) */ + /* fica armazenada a partir da posicao (y*width*3) + (x*3) */ +}; + +typedef struct +{ + Color max; /* maximos R's, G's e B's */ + Color min; /* minimos R's, G's e B's */ + float var; /* variacao em cada cubo */ + int ini; /* final do cubo */ + int fim; /* inicio do cubo */ + int maiorDim; /* R=0, G=1, B=2 */ + int checked; +} colorCube; + +/************************************************************************/ +/* Definicao das Funcoes Privadas */ +/************************************************************************/ + +/* getuint e putuint: +* Funcoes auxiliares para ler e escrever inteiros na ordem (lo-hi) +* Note que no Windows as variaveis tipo "unsigned short int" sao +* armazenadas no disco em dois bytes na ordem inversa. Ou seja, o +* numero 400, por exemplo, que pode ser escrito como 0x190, fica +* armazenado em dois bytes consecutivos 0x90 e 0x01. Nos sistemas +* UNIX e Mac este mesmo inteiro seria armazenado na ordem 0x01 e +* 0x90. O armazenamento do Windows e' chamado de "little endian" +* (i.e., lowest-order byte stored first), e no sitemas Unix sao +* "big-endian" (i.e., highest-order byte stored first). +*/ + +/*************************************************************************** +* Reads an unsigned integer from input * +***************************************************************************/ +static int getuint(unsigned short *_uint, FILE *input) +{ + int got; + unsigned char temp[2]; + unsigned short tempuint; + + got = (int) fread(&temp, 1, 2, input); + if (got != 2) return 0; + + tempuint = ((unsigned short)(temp[1])<<8) | ((unsigned short)(temp[0])); + + *_uint = tempuint; + + return 1; +} + +/*************************************************************************** +* Writes an unsigned integer in output * +***************************************************************************/ +static int putuint(unsigned short _uint, FILE *output) +{ + int put; + unsigned char temp[2]; + + temp[0] = _uint & 0xff; + temp[1] = (_uint >> 8) & 0xff; + + put = (int) fwrite(&temp, 1, 2, output); + if (put != 2) return 0; + + return 1; +} + +/*************************************************************************** +* Reads a long integer from input * +***************************************************************************/ +static int getlong(FILE *input, long int *longint) +{ + int got; + unsigned char temp[4]; + long int templongint; + + got = (int)fread(&temp, 1, 4, input); + if (got != 4) return 0; + + templongint = ((long int)(temp[3])<<24) | ((long int)(temp[2])<<16) + | ((long int)(temp[1])<<8) | ((long int)(temp[0])); + + *longint = templongint; + + return 1; +} + +/*************************************************************************** +* Writes a long integer in output * +***************************************************************************/ +static int putlong(FILE *output, long int longint) +{ + int put; + unsigned char temp[4]; + + temp[0] = (unsigned char)longint & 0xff; + temp[1] = (unsigned char)(longint >> 8) & 0xff; + temp[2] = (unsigned char)(longint >> 16) & 0xff; + temp[3] = (unsigned char)(longint >> 24) & 0xff; + + put = (int)fwrite(&temp, 1, 4, output); + + if (put != 4) return 0; + + return 1; +} + +/*************************************************************************** +* Reads a word from input * +***************************************************************************/ +static int getword(FILE *input, unsigned short int *word) +{ + int got; + unsigned char temp[2]; + unsigned short int tempword; + + got = (int)fread(&temp, 1, 2, input); + if (got != 2) return 0; + + tempword = ((unsigned short int)(temp[1])<<8) | ((unsigned short int)(temp[0])); + + *word = tempword; + + return 1; +} + +/*************************************************************************** +* Writes a word in output * +***************************************************************************/ +static int putword(FILE *output, unsigned short int word) +{ + int put; + unsigned char temp[2]; + + temp[0] = word & 0xff; + temp[1] = (word >> 8) & 0xff; + + put = (int)fwrite(&temp, 1, 2, output); + if (put != 2) return 0; + + return 1; +} + +/*************************************************************************** +* Reads a double word from input * +***************************************************************************/ +static int getdword(FILE *input, unsigned long int *dword) +{ + int got; + unsigned char temp[4]; + unsigned long int tempdword; + + got = (int)fread(&temp, 1, 4, input); + if (got != 4) return 0; + + tempdword = ((unsigned long int)(temp[3])<<24) | ((unsigned long int)(temp[2])<<16) + | ((unsigned long int)(temp[1])<<8) | ((unsigned long int)(temp[0])); + + *dword = tempdword; + + return 1; +} + +/*************************************************************************** +* Writes a double word in output * +***************************************************************************/ +static int putdword(FILE *output, unsigned long int dword) +{ + int put; + unsigned char temp[4]; + + temp[0] = (unsigned char) (dword & 0xff); + temp[1] = (unsigned char) ((dword >> 8) & 0xff); + temp[2] = (unsigned char) ((dword >> 16) & 0xff); + temp[3] = (unsigned char) ((dword >> 24) & 0xff); + + put = (int)fwrite(&temp, 1, 4, output); + + if (put != 4) return 0; + + return 1; +} + +/************************************************************************/ +/* Definicao das Funcoes Exportadas */ +/************************************************************************/ + +Image * imgCreate(int w, int h) +{ + Image * image = (Image*) malloc (sizeof(Image)); + assert(image); + image->width =(unsigned int) w; + image->height =(unsigned int) h; + image->buf = (float *) malloc (w * h * 3*sizeof(float)); + assert(image->buf); + return image; +} + +void imgDestroy (Image *image) +{ + if (image) + { + if (image->buf) free (image->buf); + free(image); + } +} + +Image * imgCopy(Image * image) +{ + int w = imgGetWidth(image); + int h = imgGetHeight(image); + Image * img1=imgCreate(w,h); + int x,y; + float rgb[3]; + + for (y=0;ywidth; + int h0=img0->height; + int w1,h1; + int x,y; + float rgb[3],black[3]={0.f,0.f,0.f}; + + for (i=0;i<14&&valid[i]width; +} + +int imgGetHeight(Image * image) +{ + return image->height; +} + +float *imgGetRGBData(Image * image) +{ + return image->buf; +} + +void imgSetPixel3fv(Image * image, int x, int y, float * color) +{ + int pos = (y*image->width*3) + (x*3); + image->buf[pos ] = color[0]; + image->buf[pos+1] = color[1]; + image->buf[pos+2] = color[2]; +} + +void imgGetPixel3fv(Image * image, int x, int y, float *color) +{ + int pos = (y*image->width*3) + (x*3); + color[0] = image->buf[pos ]; + color[1] = image->buf[pos+1]; + color[2] = image->buf[pos+2]; +} + +void imgSetPixel3ubv(Image * image, int x, int y, unsigned char * color) +{ + int pos = (y*image->width*3) + (x*3); + + image->buf[pos ] = (float)(color[0]/255.); + image->buf[pos+1] = (float)(color[1]/255.); + image->buf[pos+2] = (float)(color[2]/255.); +} + +void imgGetPixel3ubv(Image * image, int x, int y, unsigned char *color) +{ + int pos = (y*image->width*3) + (x*3); + int r= ROUND(255*image->buf[pos]); + int g= ROUND (255*image->buf[pos+1]); + int b= ROUND (255*image->buf[pos+2]); + color[0] = (unsigned char)(r<256) ? r : 255 ; + color[1] = (unsigned char)(g<256) ? g : 255 ; + color[2] = (unsigned char)(b<256) ? b : 255 ; +} + +void imageSetPixel(Image *image, int x, int y, Color color) +{ + int pos = (y*image->width*3) + (x*3); + + image->buf[pos ] = (float)(color.red); + image->buf[pos+1] = (float)(color.green); + image->buf[pos+2] = (float)(color.blue); +} + +Color imageGetPixel(Image *image, int x, int y) +{ + Color color; + int pos = (y*image->width*3) + (x*3); + + color.red = (image->buf[pos]); + color.green = (image->buf[pos+1]); + color.blue = (image->buf[pos+2]); + + return color; +} + +Image * imageLoad(char *filename) +{ + FILE *filePtr; + + Image *image; /* imagem a ser criada */ + unsigned char *buffer; /* buffer para ler o vetor de rgb da imagem */ + + unsigned char imageType; /* 2 para imagens RGB */ + unsigned short int imageWidth; /* largura da imagem */ + unsigned short int imageHeight; /* altura da imagem */ + unsigned char bitCount; /* numero de bits por pixel */ + + int x,y; /* posicao de um pixel */ + + unsigned char ucharSkip; /* dado lixo unsigned char */ + short int sintSkip; /* dado lixo short int */ + + /* abre o arquivo com a imagem TGA */ + filePtr = fopen(filename, "rb"); + assert(filePtr); + + /* pula os primeiros dois bytes que devem ter valor zero */ + ucharSkip = getc(filePtr); /* tamanho do descritor da imagem (0) */ + if (ucharSkip != 0) printf("erro na leitura de %s: imagem com descritor\n", filename); + + ucharSkip = getc(filePtr); + if (ucharSkip != 0) printf("erro na leitura de %s: imagem com tabela de cores\n", filename); + + /* le o tipo de imagem (que deve ser obrigatoriamente 2). + nao estamos tratando dos outros tipos */ + imageType=getc(filePtr); + assert(imageType == 2); + + /* pula 9 bytes relacionados com a tabela de cores + (que nao existe quando a imagem e' RGB, imageType=2) */ + getuint((short unsigned int *)&sintSkip,filePtr); + getuint((short unsigned int *)&sintSkip,filePtr); + ucharSkip = getc(filePtr); + + /* especificacao da imagem */ + getuint((short unsigned int *)&sintSkip,filePtr); /* origem em x (por default = 0) */ + getuint((short unsigned int *)&sintSkip,filePtr); /* origem em y (por default = 0) */ + getuint(&imageWidth,filePtr); /* largura */ + getuint(&imageHeight,filePtr); /* altura */ + + /* read image bit depth */ + bitCount=getc(filePtr); + assert(bitCount == 24); /* colorMode -> 3 = BGR (24 bits) */ + + /* read 1 byte of garbage data */ + ucharSkip = getc(filePtr); + + /* cria uma instancia do tipo Imagem */ + image = imgCreate(imageWidth,imageHeight); + buffer = (unsigned char *) malloc(3*imageWidth*imageHeight*sizeof(unsigned char)); + assert(image); + assert(buffer); + + /* read in image data */ + fread(buffer, sizeof(unsigned char), 3*imageWidth*imageHeight, filePtr); + + /* copia e troca as compontes de BGR para RGB */ + for (y=0;ybuf[pos ] = (float)(buffer[pos+2]/255.); + image->buf[pos+1] = (float)(buffer[pos+1]/255.); + image->buf[pos+2] = (float)(buffer[pos ]/255.); + } + } + + free(buffer); + fclose(filePtr); + return image; +} + +int imageWriteTGA(char *filename, Image * image) +{ + unsigned char imageType=2; /* RGB(A) sem compressão */ + unsigned char bitDepth=24; /* 24 bits por pixel */ + + FILE *filePtr; /* ponteiro do arquivo */ + unsigned char * buffer; /* buffer de bytes */ + int x,y; + + unsigned char byteZero=0; /* usado para escrever um byte zero no arquivo */ + short int shortZero=0; /* usado para escrever um short int zero no arquivo */ + + if (!image) return 0; + + /* cria um arquivo binario novo */ + filePtr = fopen(filename, "wb"); + assert(filePtr); + + /* cria o buffer */ + buffer = (unsigned char *) malloc(3*image->width*image->height*sizeof(unsigned char)); + assert(buffer); + + /* copia e troca as compontes de BGR para RGB */ + for (y=0;yheight;y++) { + for (x=0;xwidth;x++) { + int pos = (y*image->width*3) + (x*3); + int r= ROUND (255*image->buf[pos ]); + int g= ROUND (255*image->buf[pos+1]); + int b= ROUND (255*image->buf[pos+2]); + buffer[pos+2] = (unsigned char)(r<256) ? r : 255 ; + buffer[pos+1] = (unsigned char)(g<256) ? g : 255 ; + buffer[pos ] = (unsigned char)(b<256) ? b : 255 ; + } + } + + /* escreve o cabecalho */ + putc(byteZero,filePtr); /* 0, no. de caracteres no campo de id da imagem */ + putc(byteZero,filePtr); /* = 0, imagem nao tem palheta de cores */ + putc(imageType,filePtr); /* = 2 -> imagem "true color" (RGB) */ + putuint(shortZero,filePtr); /* info sobre a tabela de cores (inexistente) */ + putuint(shortZero,filePtr); /* idem */ + putc(byteZero,filePtr); /* idem */ + putuint(shortZero,filePtr); /* =0 origem em x */ + putuint(shortZero,filePtr); /* =0 origem em y */ + putuint(image->width,filePtr); /* largura da imagem em pixels */ + putuint(image->height,filePtr); /* altura da imagem em pixels */ + putc(bitDepth,filePtr); /* numero de bits de um pixel */ + putc(byteZero, filePtr); /* =0 origem no canto inf esquedo sem entrelacamento */ + + /* escreve o buf de cores da imagem */ + fwrite(buffer, sizeof(unsigned char), 3*image->width*image->height, filePtr); + + free(buffer); + fclose(filePtr); + return 1; +} + +Image * imgReadBMP(char *filename) +{ + FILE *filePtr; /* ponteiro do arquivo */ + Image *image; /* imagem a ser criada */ + BYTE *linedata; + + USHORT bfType; /* "BM" = 19788 */ + LONG biWidth; /* image width in pixels */ + LONG biHeight; /* image height in pixels */ + WORD biBitCount; /* bitmap color depth */ + DWORD bfSize; + + USHORT ushortSkip; /* dado lixo USHORT */ + DWORD dwordSkip; /* dado lixo DWORD */ + LONG longSkip; /* dado lixo LONG */ + WORD wordSkip; /* dado lixo WORD */ + + LONG i, j, k, l, linesize, got; + + /* abre o arquivo com a imagem BMP */ + filePtr = fopen(filename, "rb"); + assert(filePtr); + + /* verifica se eh uma imagem bmp */ + getuint(&bfType, filePtr); + assert(bfType == 19778); + + /* pula os 12 bytes correspondentes a bfSize, Reserved1 e Reserved2 */ + getdword(filePtr, &bfSize); + getuint(&ushortSkip, filePtr); /* Reserved1, deve ter valor 0 */ + assert(ushortSkip == 0); + getuint(&ushortSkip, filePtr); /* Reserved2, deve ter valor 0 */ + assert(ushortSkip == 0); + + /* pula os 4 bytes correspondentes a bfOffBits, que deve ter valor 54 */ + getdword(filePtr, &dwordSkip); + assert(dwordSkip == 54); + + /* pula os 4 bytes correspondentes a biSize, que deve ter valor 40 */ + getdword(filePtr, &dwordSkip); + assert(dwordSkip == 40); + + /* pega largura e altura da imagem */ + getlong(filePtr, &biWidth); + getlong(filePtr, &biHeight); + + /* verifica que o numero de quadros eh igual a 1 */ + getword(filePtr, &wordSkip); + assert(wordSkip == 1); + + /* Verifica se a imagem eh de 24 bits */ + getword(filePtr, &biBitCount); + if(biBitCount != 24) + { + fprintf(stderr, "imgReadBMP: Not a bitmap 24 bits file.\n"); + fclose(filePtr); + return (NULL); + } + + /* pula os demais bytes do infoheader */ + getdword(filePtr, &dwordSkip); + assert(dwordSkip == 0); + getdword(filePtr, &dwordSkip); + getlong(filePtr, &longSkip); + getlong(filePtr, &longSkip); + getdword(filePtr, &dwordSkip); + getdword(filePtr, &dwordSkip); + + image = imgCreate(biWidth, biHeight); + + /* a linha deve terminar em uma fronteira de dword */ + linesize = 3*image->width; + if (linesize & 3) { + linesize |= 3; + linesize++; + } + + /* aloca espaco para a area de trabalho */ + linedata = (BYTE *) malloc(linesize); + if (linedata == NULL) { + fprintf(stderr, "get24bits: Not enough memory.\n"); + return 0; + } + + /* pega as componentes de cada pixel */ + for (k=0, i=0; iheight; i++) { + got = (unsigned long int)fread(linedata, linesize, 1, filePtr); + if (got != 1) { + free(linedata); + fprintf(stderr, "get24bits: Unexpected end of file.\n"); + } + for (l=1, j=0; jwidth; j++, l=l+3) { + image->buf[k++] = (float)(linedata[l+1]/255.); + image->buf[k++] = (float)(linedata[l ]/255.); + image->buf[k++] = (float)(linedata[l-1]/255.); + } + } + + free(linedata); + fclose(filePtr); + return image; +} + +int imgWriteBMP(char *filename, Image * bmp) +{ + FILE *filePtr; /* ponteiro do arquivo */ + unsigned char *filedata; + DWORD bfSize; + int i, j, k, l; + + int linesize, put; + + if (!bmp) return 0; + + /* cria um novo arquivo binario */ + filePtr = fopen(filename, "wb"); + assert(filePtr); + + /* a linha deve terminar em uma double word boundary */ + linesize = bmp->width * 3; + if (linesize & 3) { + linesize |= 3; + linesize ++; + } + + /* calcula o tamanho do arquivo em bytes */ + bfSize = 14 + /* file header size */ + 40 + /* info header size */ + bmp->height * linesize; /* image data size */ + + /* Preenche o cabeçalho -> FileHeader e InfoHeader */ + putuint(19778, filePtr); /* type = "BM" = 19788 */ + putdword(filePtr, bfSize); /* bfSize -> file size in bytes */ + putuint(0, filePtr); /* bfReserved1, must be zero */ + putuint(0, filePtr); /* bfReserved2, must be zero */ + putdword(filePtr, 54); /* bfOffBits -> offset in bits to data */ + + putdword(filePtr, 40); /* biSize -> structure size in bytes */ + putlong(filePtr, bmp->width); /* biWidth -> image width in pixels */ + putlong(filePtr, bmp->height); /* biHeight -> image height in pixels */ + putword(filePtr, 1); /* biPlanes, must be 1 */ + putword(filePtr, 24); /* biBitCount, 24 para 24 bits -> bitmap color depth */ + putdword(filePtr, 0); /* biCompression, compression type -> no compression */ + putdword(filePtr, 0); /* biSizeImage, nao eh usado sem compressao */ + putlong(filePtr, 0); /* biXPelsPerMeter */ + putlong(filePtr, 0); /* biYPelsPerMeter */ + putdword(filePtr, 0); /* biClrUsed, numero de cores na palheta */ + putdword(filePtr, 0); /* biClrImportant, 0 pq todas sao importantes */ + + /* aloca espacco para a area de trabalho */ + filedata = (unsigned char *) malloc(linesize); + assert(filedata); + + /* a linha deve ser zero padded */ + for (i=0; i<(linesize-(3*bmp->width)); i++) + filedata[linesize-1-i] = 0; + j = 1; + for (k=0; kheight;k++) + { + l = 1; + /* coloca as componentes BGR no buffer */ + for (i=0; iwidth; i++) { + int b= ROUND (255*bmp->buf[j+1]); + int g= ROUND (255*bmp->buf[j ]); + int r= ROUND (255*bmp->buf[j-1]); + filedata[l-1] = (unsigned char)(b<256) ? b : 255 ; + filedata[l ] = (unsigned char)(g<256) ? g : 255 ; + filedata[l+1] = (unsigned char)(r<256) ? r : 255 ; + j+=3; l+=3; + } + + /* joga para o arquivo */ + put = (int)fwrite(filedata, linesize, 1, filePtr); + if (put != 1) { + fprintf(stderr, "put24bits: Disk full."); + free(filedata); + return 0; + } + } + + /* operacao executada com sucesso */ + fprintf(stdout,"imgWriteBMP: %s successfuly generated\n",filename); + free(filedata); + fclose(filePtr); + return 1; +} + +static int comparaCor(const void * p1, const void * p2) +{ + float *c1 = (float *) p1; /* aponta para o byte red da cor 1 */ + float *c2 = (float *) p2; /* aponta para o byte red da cor 2 */ + + /* compara o canal vermelho */ + if (*c1 < *c2) return -1; + if (*c1 > *c2) return 1; + + /* compara o canal verde, uma vez que o vermelho e' igual */ + c1++; c2++; + if (*c1 < *c2) return -1; + if (*c1 > *c2) return 1; + + /* compara o canal azul, uma vez que o vermelho e o azul sao iguais */ + c1++; c2++; + if (*c1 < *c2) return -1; + if (*c1 > *c2) return 1; + + /* sao iguais */ + return 0; +} + +unsigned int imgCountColors(Image * img) +{ + unsigned int numCor = 1; + int w = imgGetWidth(img); + int h = imgGetHeight(img); + float* buf=imgGetRGBData(img); + float *vet=(float*) malloc(3*w*h*sizeof(float)); + int i; + + /* copia o buffer da imagem no vetor de floats fazendo uma quantizacao para 256 tons de cada componente de cor */ + for (i=0;i<3*w*h;i++) { + float val = (float)(255*buf[i]); + vet[i] = (float)(val<256) ? val : 255; + } + + /* ordena o vetor */ + qsort(vet,w*h,3*sizeof(float),comparaCor); + + /* conta o numero de cores diferentes */ + for (i=3; i<3*w*h; i+=3) + if (comparaCor(&vet[i-3],&vet[i])!=0) numCor++; + + free(vet); + return numCor; +} + +Image * imgNormalizeColors(Image * img0) +{ + int w = imgGetWidth(img0); + int h = imgGetHeight(img0); + Image* img1 = imgCreate(w,h); + int x,y; + float rgb[3]; + + + for (y=0;y c2.red) return 1; + + return 0; +} + +static int comparaG(const void * p1, const void * p2) +{ + Color *color1 = (Color *) p1; + Color *color2 = (Color *) p2; + + Color c1 = *color1; + Color c2 = *color2; + + if (c1.green < c2.green) return -1; + if (c1.green > c2.green) return 1; + + return 0; +} + +static int comparaB(const void * p1, const void * p2) +{ + Color *color1 = (Color *) p1; + Color *color2 = (Color *) p2; + + Color c1 = *color1; + Color c2 = *color2; + + if (c1.blue < c2.blue) return -1; + if (c1.blue > c2.blue) return 1; + + return 0; +} + +void caixaEnvolvente(colorCube* cube, Color* colorVec) +{ + float r,g,b; + int i; + + /* inicializa com o pior caso */ + cube->min.red = cube->min.green = cube->min.blue = 1.0; + cube->max.red = cube->max.green = cube->max.blue = 0.0; + + /* percorre o cubo ajustando o domínio das cores */ + for (i=cube->ini;i<=cube->fim;i++){ + r = colorVec[i].red; + if (r > cube->max.red) cube->max.red = r; + if (r < cube->min.red) cube->min.red = r; + g = colorVec[i].green; + if (g > cube->max.green) cube->max.green = g; + if (g < cube->min.green) cube->min.green = g; + b = colorVec[i].blue; + if (b > cube->max.blue) cube->max.blue = b; + if (b < cube->min.blue) cube->min.blue = b; + } +} + +Image* bestColor(Image *img0, Color* pal, Image* img1, int pal_size) +{ + int w = imgGetWidth(img0); + int h = imgGetHeight(img0); + float rgb[3]; + int x,y,i; + + for (y=0;y=var[1])&&(var[0]>=var[2])) cubeVec[i].maiorDim = 0; + else + if((var[1]>=var[0])&&(var[1]>=var[2])) cubeVec[i].maiorDim = 1; + else + if((var[2]>var[0]) && (var[2]>var[1])) cubeVec[i].maiorDim = 2; + + /* ordena de acordo com a maior dimensao da caixa */ + if(cubeVec[i].maiorDim == 0) + { + qsort(&colorVec[cubeVec[i].ini],numElem,tamElem,comparaR); + cubeVec[i].var = var[0]; + } + if(cubeVec[i].maiorDim == 1) + { + qsort(&colorVec[cubeVec[i].ini],numElem,tamElem,comparaG); + cubeVec[i].var = var[1]; + } + if(cubeVec[i].maiorDim == 2) + { + qsort(&colorVec[cubeVec[i].ini],numElem,tamElem,comparaB); + cubeVec[i].var = var[2]; + } +} + +void cortaCubo(colorCube* cubeVec, int posCorte, int numCubos) +{ + /* divide o cubo */ + int ini = cubeVec[posCorte].ini; + int fim = cubeVec[posCorte].fim; + + if((fim - ini)%2 != 0) /* numero par de elementos */ + { + cubeVec[numCubos].ini = ini + (fim - ini + 1)/2; + cubeVec[numCubos].fim = fim; + cubeVec[posCorte].fim = cubeVec[numCubos].ini - 1; + } + else /* numero impar de elementos */ + { + cubeVec[numCubos].ini = ini + (fim - ini)/2; + cubeVec[numCubos].fim = fim; + cubeVec[posCorte].fim = cubeVec[numCubos].ini - 1; + } +} + +int cuboCorte(colorCube* cubeVec, int numCubos) +{ + /* escolhe o cubo a ser cortado */ + float maiorVar = -1; + int posCorte = -1; + int k; + for(k=0;kmaiorVar) + { + maiorVar = cubeVec[k].var; + posCorte = k; + } + } + + return posCorte; +} + +Image* imgReduceColors(Image * img0, int maxCores) +{ + int w = imgGetWidth(img0); + int h = imgGetHeight(img0); + Image* img1 = imgCreate(w,h); + + int x,y,i,j,numCubos = 0; + int posCorte = -1; + float rgb[3]; + + colorCube* cubeVec = (colorCube*)malloc(maxCores*sizeof(colorCube)); /* vetor de cubos */ + Color* colorVec = (Color*)malloc(w*h*sizeof(Color)); /* vetor de cores */ + Color* pal = (Color*)malloc(maxCores*sizeof(Color)); /* paleta de cores */ + + /* guarda as cores nos vetores (com repeticao) */ + i = 0; + for (y=0;yrgb0[0])? rgb1[0]-rgb0[0] : rgb0[0]-rgb1[0] ; + rgb0[1]=(rgb1[1]>rgb0[1])? rgb1[1]-rgb0[1] : rgb0[1]-rgb1[1] ; + rgb0[2]=(rgb1[2]>rgb0[2])? rgb1[2]-rgb0[2] : rgb0[2]-rgb1[2] ; + imgSetPixel3fv(img0,x,y,rgb0); + } + } +} + +Image * imgGaussFilter(Image * img0) +{ + int w = imgGetWidth (img0); + int h = imgGetHeight(img0); + Image * img1 = imgCreate(w,h); + + float rgb00[3], rgb01[3], rgb02[3]; + float rgb10[3], rgb11[3], rgb12[3]; + float rgb20[3], rgb21[3], rgb22[3]; + float rgb[3]; + + int Gauss[3][3]; + + int x, y; + + /* Filtro Gaussiano */ + Gauss[0][0] = 1; Gauss[0][1] = 2; Gauss[0][2] = 1; + Gauss[1][0] = 2; Gauss[1][1] = 4; Gauss[1][2] = 2; + Gauss[2][0] = 1; Gauss[2][1] = 2; Gauss[2][2] = 1; + + for (y=0;y=0 && (y-1)>=0) imgGetPixel3fv(img0,x-1,y-1,rgb00); + if((y-1)>=0) imgGetPixel3fv(img0, x,y-1,rgb01); + if((x+1)=0) imgGetPixel3fv(img0,x+1,y-1,rgb02); + if((x-1)>=0) imgGetPixel3fv(img0,x-1, y,rgb10); + if((x+1)=0 && (y+1)0) && (y<(h-1)))){ + + rgb[0] = (rgb11[0]*Gauss[1][1] + rgb00[0]*Gauss[0][0] + rgb01[0]*Gauss[0][1] + rgb10[0]*Gauss[1][0] + rgb21[0]*Gauss[2][1] + rgb20[0]*Gauss[2][0])/16; + rgb[1] = (rgb11[1]*Gauss[1][1] + rgb00[1]*Gauss[0][0] + rgb01[1]*Gauss[0][1] + rgb10[1]*Gauss[1][0] + rgb21[1]*Gauss[2][1] + rgb20[1]*Gauss[2][0])/16; + rgb[2] = (rgb11[2]*Gauss[1][1] + rgb00[2]*Gauss[0][0] + rgb01[2]*Gauss[0][1] + rgb10[2]*Gauss[1][0] + rgb21[2]*Gauss[2][1] + rgb20[2]*Gauss[2][0])/16; + } + + if(((x == 0) && (y > 0) && (y < (h-1)))){ + + rgb[0] = (rgb11[0]*Gauss[1][1] + rgb01[0]*Gauss[0][1] + rgb02[0]*Gauss[0][2] + rgb12[0]*Gauss[1][2] + rgb21[0]*Gauss[2][1] + rgb22[0]*Gauss[2][2])/16; + rgb[1] = (rgb11[1]*Gauss[1][1] + rgb01[1]*Gauss[0][1] + rgb02[1]*Gauss[0][2] + rgb12[1]*Gauss[1][2] + rgb21[1]*Gauss[2][1] + rgb22[1]*Gauss[2][2])/16; + rgb[2] = (rgb11[2]*Gauss[1][1] + rgb01[2]*Gauss[0][1] + rgb02[2]*Gauss[0][2] + rgb12[2]*Gauss[1][2] + rgb21[2]*Gauss[2][1] + rgb22[2]*Gauss[2][2])/16; + } + + if(((y == 0) && (x > 0) && (x < (w-1)))){ + + rgb[0] = (rgb11[0]*Gauss[1][1] + rgb10[0]*Gauss[1][0] + rgb12[0]*Gauss[1][2] + rgb20[0]*Gauss[2][0] + rgb21[0]*Gauss[2][1] + rgb22[0]*Gauss[2][2])/16; + rgb[1] = (rgb11[1]*Gauss[1][1] + rgb10[1]*Gauss[1][0] + rgb12[1]*Gauss[1][2] + rgb20[1]*Gauss[2][0] + rgb21[1]*Gauss[2][1] + rgb22[1]*Gauss[2][2])/16; + rgb[2] = (rgb11[2]*Gauss[1][1] + rgb10[2]*Gauss[1][0] + rgb12[2]*Gauss[1][2] + rgb20[2]*Gauss[2][0] + rgb21[2]*Gauss[2][1] + rgb22[2]*Gauss[2][2])/16; + } + + if(((y == (h-1)) && (x > 0) && (x < (w-1)))){ + + rgb[0] = (rgb11[0]*Gauss[1][1] + rgb00[0]*Gauss[0][0] + rgb01[0]*Gauss[0][1] + rgb02[0]*Gauss[0][2] + rgb10[0]*Gauss[1][0] + rgb12[0]*Gauss[1][2])/16; + rgb[1] = (rgb11[1]*Gauss[1][1] + rgb00[1]*Gauss[0][0] + rgb01[1]*Gauss[0][1] + rgb02[1]*Gauss[0][2] + rgb10[1]*Gauss[1][0] + rgb12[1]*Gauss[1][2])/16; + rgb[2] = (rgb11[2]*Gauss[1][1] + rgb00[2]*Gauss[0][0] + rgb01[2]*Gauss[0][1] + rgb02[2]*Gauss[0][2] + rgb10[2]*Gauss[1][0] + rgb12[2]*Gauss[1][2])/16; + } + + /* tratando os pixels centrais */ + if( ((x!=0) && (y!=0) && (y!=(h-1)) && (x!=(w-1)))){ + + rgb[0] = (rgb00[0]*Gauss[0][0] + rgb01[0]*Gauss[0][1] + rgb02[0]*Gauss[0][2] + + rgb10[0]*Gauss[1][0] + rgb11[0]*Gauss[1][1] + rgb12[0]*Gauss[1][2] + + rgb20[0]*Gauss[2][0] + rgb21[0]*Gauss[2][1] + rgb22[0]*Gauss[2][2])/16; + + rgb[1] = (rgb00[1]*Gauss[0][0] + rgb01[1]*Gauss[0][1] + rgb02[1]*Gauss[0][2] + + rgb10[1]*Gauss[1][0] + rgb11[1]*Gauss[1][1] + rgb12[1]*Gauss[1][2] + + rgb20[1]*Gauss[2][0] + rgb21[1]*Gauss[2][1] + rgb22[1]*Gauss[2][2])/16; + + rgb[2] = (rgb00[2]*Gauss[0][0] + rgb01[2]*Gauss[0][1] + rgb02[2]*Gauss[0][2] + + rgb10[2]*Gauss[1][0] + rgb11[2]*Gauss[1][1] + rgb12[2]*Gauss[1][2] + + rgb20[2]*Gauss[2][0] + rgb21[2]*Gauss[2][1] + rgb22[2]*Gauss[2][2])/16; + } + + if(rgb[0]>1) rgb[0] = 1; + if(rgb[1]>1) rgb[1] = 1; + if(rgb[2]>1) rgb[2] = 1; + + imgSetPixel3fv(img1,x,y,rgb); + } + } + + return img1; +} + +Image * imgLaplcFilter(Image * img) +{ + int w = imgGetWidth (img); + int h = imgGetHeight(img); + Image * img1 = imgCreate(w,h); + Image * img0 = imgCreate(w,h); + + float rgb00[3], rgb01[3], rgb02[3]; + float rgb10[3], rgb11[3], rgb12[3]; + float rgb20[3], rgb21[3], rgb22[3]; + float rgb[3]; + + int Laplc[3][3]; + + int x,y; + + img0 = imgGrey(img); + + /* Filtro Laplaciano */ + Laplc[0][0] = -1; Laplc[0][1] = -1; Laplc[0][2] = -1; + Laplc[1][0] = -1; Laplc[1][1] = 8; Laplc[1][2] = -1; + Laplc[2][0] = -1; Laplc[2][1] = -1; Laplc[2][2] = -1; + + for (y=0;y=0) + { + imgGetPixel3fv(img0,x,y-1,rgb01); + rgb[0] += rgb01[0]*Laplc[0][1]; + rgb[1] += rgb01[1]*Laplc[0][1]; + rgb[2] += rgb01[2]*Laplc[0][1]; + } + + if((x-1)>=0) + { + imgGetPixel3fv(img0,x-1,y,rgb10); + rgb[0] += rgb10[0]*Laplc[1][0]; + rgb[1] += rgb10[1]*Laplc[1][0]; + rgb[2] += rgb10[2]*Laplc[1][0]; + + if((y-1)>=0) + { + imgGetPixel3fv(img0,x-1,y-1,rgb00); + rgb[0] += rgb00[0]*Laplc[0][0]; + rgb[1] += rgb00[1]*Laplc[0][0]; + rgb[2] += rgb00[2]*Laplc[0][0]; + } + + if((y+1)=0) + { + imgGetPixel3fv(img0,x+1,y-1,rgb02); + rgb[0] += rgb02[0]*Laplc[0][2]; + rgb[1] += rgb02[1]*Laplc[0][2]; + rgb[2] += rgb02[2]*Laplc[0][2]; + } + + if((y+1)1) rgb[0] = 1; + if(rgb[1]>1) rgb[1] = 1; + if(rgb[2]>1) rgb[2] = 1; + + if(rgb[0]<0) rgb[0] = 0; + if(rgb[1]<0) rgb[1] = 0; + if(rgb[2]<0) rgb[2] = 0; + + imgSetPixel3fv(img1,x,y,rgb); + } + } + + return img1; +} + +Image * imgEdges(Image * img0) +{ + int w = imgGetWidth (img0); + int h = imgGetHeight(img0); + Image * imgLoG = imgCreate(w,h); + float rgb1[3]; + float rgb[3]; + + int x, y; + + imgLoG = imgGaussFilter(img0); + imgLoG = imgLaplcFilter(imgLoG); + + for (y=0;y=0) + { + imgGetPixel3fv(img0,x,y-1,rgb01); + vet0[k] = rgb01[0]; + vet1[k] = rgb01[1]; + vet2[k] = rgb01[2]; + k++; + } + + if((x-1)>=0) + { + imgGetPixel3fv(img0,x-1,y,rgb10); + vet0[k] = rgb10[0]; + vet1[k] = rgb10[1]; + vet2[k] = rgb10[2]; + k++; + + if((y-1)>=0) + { + imgGetPixel3fv(img0,x-1,y-1,rgb00); + vet0[k] = rgb00[0]; + vet1[k] = rgb00[1]; + vet2[k] = rgb00[2]; + k++; + } + + if((y+1)=0) + { + imgGetPixel3fv(img0,x+1,y-1,rgb02); + vet0[k] = rgb02[0]; + vet1[k] = rgb02[1]; + vet2[k] = rgb02[2]; + k++; + } + + if((y+1)1) rgb[0] = 1; + if(rgb[1]>1) rgb[1] = 1; + if(rgb[2]>1) rgb[2] = 1; + + imgSetPixel3fv(img1,x,y,rgb); + } + } + + return img1; +} + +Image * imgBinarizacao(Image * img0) +{ + int w = imgGetWidth (img0); + int h = imgGetHeight(img0); + Image * imgB = imgCreate(w,h); + float rgb[3], rgbB[3]; + float sumR = 0; + float sumG = 0; + float sumB = 0; + + int x, y; + + imgB = imgGrey(img0); + + for (y=0;y (sumR / (w*h))) rgbB[0] = 1; + else rgbB[0] = 0; + if(rgb[1] > (sumG / (w*h))) rgbB[1] = 1; + else rgbB[1] = 0; + if(rgb[2] > (sumB / (w*h))) rgbB[2] = 1; + else rgbB[2] = 0; + + imgSetPixel3fv(imgB,x,y,rgbB); + } + } + + return imgB; +} + diff --git a/image.h b/image.h new file mode 100644 index 0000000..cdb3aa8 --- /dev/null +++ b/image.h @@ -0,0 +1,288 @@ +/** + * @file image.h Image: operacoes imagens em formato TGA. + * + * @author + * - Maira Noronha + * - Fabiola Maffra + * - Marcelo Gattass + * + * @date + * Ultima Modificacao: 23 de Abril de 2003 + * + * @version 2.0 + */ + +#ifndef IMAGE_H +#define IMAGE_H + +#include "color.h" + +typedef struct Image_imp Image; + +/************************************************************************/ +/* Funcoes Exportadas */ +/************************************************************************/ + +/** + * Cria uma nova imagem com as dimensoes especificadas. + * + * @param w Largura da imagem. + * @param h Altura da imagem. + * + * @return Handle da imagem criada. + */ +Image * imgCreate (int w, int h); + +/** + * Destroi a imagem. + * + * @param image imagem a ser destruida. + */ +void imgDestroy (Image *image); + +/** +* Cria uma nova nova copia imagem dada. +* +* @param image imagem a ser copiada. +* +* @return Handle da imagem criada. +*/ +Image * imgCopy(Image * image); + +/** +* Cria uma nova nova copia imagem dada em tons de cinza. +* +* @param image imagem a ser copiada em tons de cinza. +* +* @return Handle da imagem criada. +*/ +Image * imgGrey(Image * image); + +/** +* Redimensiona a imagem especificada. +* +* @param image Handle para uma imagem. +* @param w1 Nova largura da imagem. +* @param h1 Nova altura da imagem. +* @return imagem criada. +*/ +Image * imgResize(Image *img0, int w1, int h1); + +/** +* Ajusta a largura da imagem para uma potencia de 2. +* +* @param img0 imagem a ser ajustada. +*/ +Image * imgAdjust2eN(Image *img0); + +/** +* Obtem a largura (width) de uma imagem. +* +* @param image Handle para uma imagem. +* @return a largura em pixels (width) da imagem. +*/ +int imgGetWidth(Image * image); + +/** +* Obtem a altura (heigth) de uma imagem. +* +* @param image Handle para uma imagem. +* @return a altura em pixels (height) da imagem. +*/ +int imgGetHeight(Image * image); + +/** +* Obtem as dimensoes de uma imagem. +* +* @param image Handle para uma imagem. +* @param w [out]Retorna a largura da imagem. +* @param h [out]Retorna a altura da imagem. +*/ +float * imgGetRGBData(Image * image); + +/** +* Ajusta o pixel de uma imagem com a cor especificada. +* +* @param image Handle para uma imagem. +* @param x Posicao x na imagem. +* @param y Posicao y na imagem. +* @param color Cor do pixel(valor em float [0,1]). +*/ +void imgSetPixel3fv(Image * image, int x, int y, float * color); + +/** +* Obtem o pixel de uma imagem na posicao especificada. +* +* @param image Handle para uma imagem. +* @param x Posicao x na imagem. +* @param y Posicao y na imagem. +* @param color [out] Pixel da posicao especificada(valor em float [0,1]). +*/ +void imgGetPixel3fv(Image * image, int x, int y, float *color); + +/** +* Ajusta o pixel de uma imagem com a cor especificada. +* +* @param image Handle para uma imagem. +* @param x Posicao x na imagem. +* @param y Posicao y na imagem. +* @param color Cor do pixel (valor em unsigend char[0,255]). +*/ +void imgSetPixel3ubv(Image * image, int x, int y, unsigned char * color); + +/** +* Obtem o pixel de uma imagem na posicao especificada. +* +* @param image Handle para uma imagem. +* @param x Posicao x na imagem. +* @param y Posicao y na imagem. +* @param color [out] Pixel da posicao especificada (valor em unsigend char[0,255]). +*/ +void imgGetPixel3ubv(Image * image, int x, int y, unsigned char *color); + +/** + * Ajusta o pixel de uma imagem com a cor especificada. + * + * @param image Handle para uma imagem. + * @param x Posicao x na imagem. + * @param y Posicao y na imagem. + * @param color Cor do pixel. + */ +void imageSetPixel(Image *image, int x, int y, Color color); + +/** + * Obtem o pixel de uma imagem na posicao especificada. + * + * @param image Handle para uma imagem. + * @param x Posicao x na imagem. + * @param y Posicao y na imagem. + * + * @return Pixel da posicao especificada. + */ +Color imageGetPixel(Image *image, int x, int y); + + + +/** + * Le a imagem a partir do arquivo especificado. + * + * @param filename Nome do arquivo de imagem. + * + * @return imagem criada. + */ +Image * imageLoad(char *filename); + +/** + * Salva a imagem no arquivo especificado em formato TGA. + * + * @param filename Nome do arquivo de imagem. + * @param image Handle para uma imagem. + * + * @return retorna 1 caso nao haja erros. + */ +int imageWriteTGA(char *filename, Image *image); + +/** +* Le a imagem a partir do arquivo especificado. +* +* @param filename Nome do arquivo de imagem. +* +* @return imagem criada. +*/ +Image * imgReadBMP (char *filename); + +/** +* Salva a imagem no arquivo especificado em formato BMP. +* +* @param filename Nome do arquivo de imagem. +* @param bmp Handle para uma imagem. +* +* @return retorna 1 caso nao haja erros. +*/ +int imgWriteBMP(char *filename, Image * bmp); + +/*** FUNCOES QUE DEVEM SER IMPLEMENTADAS NO TRABALHO 1 ***/ + +/** +* Conta o numero de cores diferentes na imagem +* +* @param image Handle para uma imagem. +* @param w Nova largura da imagem. +* @param h Nova altura da imagem. +*/ +unsigned int imgCountColors(Image * image); + +/** +* Normaliza as cores da imagem (eliminando o +* efeito da iluminacao. +* +* @param image Handle para uma imagem. +* +* @return Handle para nova imagem normalizada. +*/ +Image * imgNormalizeColors(Image * image); + +/** +* Reduz o numero de cores distintas +* +* @param image Handle para uma imagem. +* @param maxCores numero de cores que a nova imagem deve ter. +* +* @return Handle para a nova imagem. +*/ +Image * imgReduceColors(Image * image, int maxCores); + +/** +* Subtrai uma imagem de outra. +* +* @param img0 img0 = |img0-img1|. +* @param img1. +*/ +void imgSub(Image *img0, Image *img1); + +/** +* Passa um filtro gaussiano na imagem. +* +* @param img0 imagem a ser filtrada. +* +* @return imagem filtrada. +*/ +Image * imgGaussFilter(Image * img0); + +/** +* Passa um filtro laplaciano na imagem. +* +* @param img0 imagem a ser filtrada. +* +* @return imagem filtrada. +*/ +Image * imgLaplcFilter(Image * img0); + +/** +* Passa um filtro log. +* +* @param img0 imagem a ser filtrada. +* +* @return imagem filtrada. +*/ +Image * imgEdges(Image * img0); + +/** +* Passa um filtro de mediana na imagem. +* +* @param img0 imagem a ser filtrada. +* +* @return imagem filtrada. +*/ +Image * imgFiltroDeMediana(Image * img0); + +/** +* transforma a imagem em uma imagem binaria(preta e branca). +* +* @param img0 imagem a ser binarizada. +* +* @return imagem binarizada. +*/ +Image * imgBinarizacao(Image * img0); + +#endif diff --git a/light.c b/light.c new file mode 100644 index 0000000..a6b15de --- /dev/null +++ b/light.c @@ -0,0 +1,71 @@ +/** + * @file light.c Light*: definição e operações com fontes de luz. + * + * @author + * - Maira Noronha + * - Thiago Bastos + * + * @date + * Criado em: 01 de Dezembro de 2002 + * Última Modificação: 22 de Janeiro de 2003 + * + * @version 2.0 + */ + +#include "light.h" +#include +#include + +/** + * Luz com posição e intensidade. + */ +struct _Light +{ + /** + * Posição da luz. + */ + Vector position; + /** + * Intensidade da luz em rgb. + */ + Color color; +}; + +/************************************************************************/ +/* Definição das Funções Exportadas */ +/************************************************************************/ +Light* lightCreate( Vector position, Color color ) +{ + Light* light = (struct _Light *)malloc( sizeof(struct _Light) ); + + light->position = position; + light->color = color; + + return light; +} + +Vector lightGetPosition( Light* light ) +{ + return light->position; +} + +Color lightGetColor( Light* light ) +{ + return light->color; +} + +void lightDestroy( Light* light ) +{ + free( light ); +} + +void lightSetPosition( Light* light, Vector position ) +{ + light->position = position; +} + +void lightSetColor( Light* light, Color color ) +{ + light->color = color; +} + diff --git a/light.h b/light.h new file mode 100644 index 0000000..1880e55 --- /dev/null +++ b/light.h @@ -0,0 +1,84 @@ +/** + * @file light.h Light*: definição e operações com fontes de luz. + * + * @author + * - Maira Noronha + * - Thiago Bastos + * + * @date + * Criado em: 01 de Dezembro de 2002 + * Última Modificação: 22 de Janeiro de 2003 + * + * @version 2.0 + */ + +#ifndef _LIGHT_H_ +#define _LIGHT_H_ + +#include "color.h" +#include "algebra.h" + + +/************************************************************************/ +/* Tipos Exportados */ +/************************************************************************/ + + +typedef struct _Light Light; + +/************************************************************************/ +/* Funções Exportadas */ +/************************************************************************/ +/** + * Cria uma fonte de luz não-direcional com as propriedades especificadas. + * + * @param position Posição da fonte de luz. + * @param color Cor da luz. + * + * @return Handle para a fonte de luz. + */ +Light* lightCreate( Vector position, Color color ); + +/** + * Obtém a posição em que está localizada uma fonte de luz. + * + * @param light Fonte de luz. + * + * @return Posição da fonte de luz. + */ +Vector lightGetPosition( Light* light ); + +/** + * Obtém a cor de uma fonte de luz. + * + * @param light Fonte de luz. + * + * @return Cor da fonte de luz. + */ +Color lightGetColor( Light* light ); + +/** + * Destrói uma fonte de luz criada com lightCreate(). + * + * @param light Fonte de luz. + */ +void lightDestroy( Light* light ); + +/** + * Posiciona uma fonte de luz. + * + * @param light Fonte de luz. + * @param position Posição da fonte de luz. + */ +void lightSetPosition( Light* light, Vector position ); + +/** + * Fixa a cor de uma fonte de luz. + * + * @param light Fonte de luz. + * @param color Cor da fonte de luz. + */ +void lightSetColor( Light* light, Color color ); + +#endif + diff --git a/mahogany.bmp b/mahogany.bmp new file mode 100644 index 0000000..23e6058 Binary files /dev/null and b/mahogany.bmp differ diff --git a/mainIUP.c b/mainIUP.c new file mode 100644 index 0000000..88f23bb --- /dev/null +++ b/mainIUP.c @@ -0,0 +1,313 @@ +/* + * Computação Gráfica - Trabalho de Raytracing + * Professor Marcelo Gattass + * + * @file main.c + * + * @author + * - Maira Noronha + * - Thiago Bastos + * + * @date + * Última Modificação: 10 de Fevereiro de 2003 + * + * @version 2.0 + * + * Este arquivo não precisa ser modificado. + * Veja o módulo raytracing.c + */ + +#include +#include + +/*- Inclusao das bibliotecas IUP e CD: ------------------------------------*/ +#ifdef WIN32 +#include +#include +#include +#else +#include +#include +#endif + +#include +#include +#include "image.h" +#include "color.h" +#include "algebra.h" +#include "raytracing.h" + +/* -- implemented in "iconlib.c" to load standard icon images into IUP */ +void IconLibOpen(void); + +/*- Contexto do Programa: -------------------------------------------------*/ +Scene* scene; /* cena corrente */ +int yc=0; /* y corrente para Ray Tracing incremetnal */ +int width,height=-1; /* alrgura e altura corrente */ +Image *image; /* imagem que armazena o resultado até agora do algoritmo */ +Vector eye; +Camera* camera; + +double duration; +int start_time; +int finish_time; + + +Ihandle *canvas; /* ponteiro IUP dos canvas */ +Ihandle *label; /* ponteiro IUP do label para colocar mensagens para usuario */ + +/*- Funcoes auxiliares ------------*/ + +/* Dialogo de selecao de arquivo */ +static char * get_file_name( void ) +{ + Ihandle* getfile = IupFileDlg(); + char* filename = NULL; + + IupSetAttribute(getfile, IUP_TITLE, "Abertura de arquivo" ); + IupSetAttribute(getfile, IUP_DIALOGTYPE, IUP_OPEN); + IupSetAttribute(getfile, IUP_FILTER, "*.rt4"); + IupSetAttribute(getfile, IUP_FILTERINFO, "Arquivo de cena (*.rt4)"); + IupPopup(getfile, IUP_CENTER, IUP_CENTER); /* o posicionamento nao esta sendo respeitado no Windows */ + + filename = IupGetAttribute(getfile, IUP_VALUE); + return filename; +} + + +/*------------------------------------------*/ +/* Callbacks do IUP. */ +/*------------------------------------------*/ + + +/* - Callback de mudanca de tamanho no canvas (mesma para ambos os canvas) */ +int resize_cb(Ihandle *self, int width, int height) +{ + IupGLMakeCurrent(self); /* torna o foco do OpenGL para este canvas */ + + /* define a area do canvas que deve receber as primitivas do OpenGL */ + glViewport(0,0,width,height); + + /* transformacao de instanciacao dos objetos no sistema de coordenadas da camera */ + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); /* identidade, ou seja nada */ + + /* transformacao de projecao */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D (0.0, (GLsizei)(width), 0.0, (GLsizei)(height)); /* ortografica no plano xy de [0,w]x[0,h] */ + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + return IUP_DEFAULT; /* retorna o controle para o gerenciador de eventos */ +} + + +/* - Callback de repaint do canvas */ +int repaint_cb(Ihandle *self) +{ + int w,h; + int x,y; + Color rgb; + + IupGLMakeCurrent(self); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + glFlush(); + + printf("cp:0\n"); + if (yc!=height) { /* esta callback so'desenha depois que o algoritmo termina a imagem */ + return IUP_DEFAULT; + } + + printf("cp:1\n"); + w = imgGetWidth(image); + h = imgGetHeight(image); + IupGLMakeCurrent(self); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glBegin(GL_POINTS); + for (y=0;y +#include + +/** + * Material* com o qual é feito um objeto. + */ +struct _Material +{ + /** + * Textura do material. + */ + Image *texture; + + /** + * Cor base do material (difusa). + */ + Color diffuseColor; + /** + * Cor do brilho especular do material. + */ + Color specularColor; + + /** + * Coeficiente que define o brilho especular. + */ + double specularExponent; + /** + * Fator de refletividade do material. + */ + double reflectionFactor; + /** + * Índice de refração do material. + */ + double refractionFactor; + /** + * Opacidade do material. + */ + double opacityFactor; +}; + +/************************************************************************/ +/* Definição das Funções Exportadas */ +/************************************************************************/ +Material* matCreate( Image *texture, Color diffuseColor, + Color specularColor, double specularExponent, + double reflectionFactor, double refractionFactor, double opacityFactor ) +{ + Material* material = (struct _Material *)malloc( sizeof(struct _Material) ); + + material->texture = texture; + material->diffuseColor = diffuseColor; + material->specularColor = specularColor; + material->specularExponent = specularExponent; + material->reflectionFactor = reflectionFactor; + material->refractionFactor = refractionFactor; + material->opacityFactor = opacityFactor; + + return material; +} + +Color matGetDiffuse( Material* material, Vector textureCoordinate ) +{ + int x; + int y; + int width; + int height; + + if( material->texture == NULL ) + { + return material->diffuseColor; + } + + width = imgGetWidth(material->texture); + height = imgGetHeight(material->texture); + + //imageGetDimensions( material->texture, &width, &height ); + + x = ( (int)( textureCoordinate.x * ( width - 1 ) ) % width ); + y = ( (int)( textureCoordinate.y * ( height - 1 ) ) % height ); + + return imageGetPixel( material->texture, x, y ); +} + +Color matGetSpecular( Material* material ) +{ + return material->specularColor; +} + +double matGetSpecularExponent( Material* material ) +{ + return material->specularExponent; +} + +double matGetReflectionFactor( Material* material ) +{ + return material->reflectionFactor; +} + +double matGetRefractionIndex( Material* material ) +{ + return material->refractionFactor; +} + +double matGetOpacity( Material* material ) +{ + return material->opacityFactor; +} + +void matDestroy( Material* material ) +{ + free( material ); +} + diff --git a/material.h b/material.h new file mode 100644 index 0000000..9326da5 --- /dev/null +++ b/material.h @@ -0,0 +1,94 @@ +/** + * @file material.h Material*: manutenção de materiais. + * + * @author + * - Maira Noronha + * - Thiago Bastos + * - Mauricio Carneiro + * + * @date + * Criado em: 1 de Dezembro de 2002 + * Última Modificação: 4 de Junho de 2003 + * + * @version 2.0 + */ + +#ifndef _MATERIAL_H_ +#define _MATERIAL_H_ + +#include "color.h" +#include "image.h" +#include "algebra.h" + + +/************************************************************************/ +/* Tipos Exportados */ +/************************************************************************/ + + +typedef struct _Material Material; + + +/************************************************************************/ +/* Funções Exportadas */ +/************************************************************************/ +/** + * Cria um novo material com as propriedades especificadas. + * + * @param texture Imagem contendo textura do material (pode ser NULL). + * @param diffusecolor Cor base do material (é substituido pela textura, quando presente). + * @param specularColor Cor do brilho especular para este material. + * @param specularExponent Coeficiente que define o brilho especular. + * @param reflectionFactor Fator de refletividade do material: 0 se não reflete nada, + * 1 se totalmente reflexivo). + * @param refractionFactor Índice de refração do material, para materiais transparentes. + * @param opacityFactor Opacidade do material (1 para 100% opaco, 0 para 100% transparente). + * + * @return Handle para o material criado. + */ +Material* matCreate( Image *texture, Color diffuseColor, + Color specularColor, double specularExponent, + double reflectionFactor, double refractionFactor, double opacityFactor ); + +/** + * Obtém a cor difusa para um objeto composto de um material. + * + * @param material Handle para o material do objeto. + * @param textureCoordinate Coordenada de textura calculada para o objeto em questão. + * + * @return Cor difusa do objeto num certo ponto. + */ +Color matGetDiffuse( Material* material, Vector textureCoordinate ); + +/** + * Obtém a cor do brilho especular de um material. + */ +Color matGetSpecular( Material* material ); + +/** + * Obtém o coeficiente do brilho especular (o expoente N). + */ +double matGetSpecularExponent( Material* material ); + +/** + * Obtém o fator de refletividade do material: 1.0f para 100% reflexivo. + */ +double matGetReflectionFactor( Material* material ); + +/** + * Obtém o índice de refração de um material (usado para implementar transparência). + */ +double matGetRefractionIndex( Material* material ); + +/** + * Obtém a opacidade de um material: 1.0f para 100% opaco, 0.0f para 100% transparente. + */ +double matGetOpacity( Material* material ); + +/** + * Destrói um material criado com matCreate(). + */ +void matDestroy( Material* material ); + +#endif + diff --git a/object.c b/object.c new file mode 100644 index 0000000..57ec81e --- /dev/null +++ b/object.c @@ -0,0 +1,693 @@ +/** + * @file object.c Object*: definição e operações com primitivas. + * As primitivas suportadas atualmente são: esferas, triângulos e paralelepípedos. + * + * @date + * Criado em: 01 de Dezembro de 2002 + * Última Modificação: 05 de outubro de 2009 + * + */ + +#include "object.h" +#include +#include +#include +#include +#include "algebra.h" + +/** + * Tipo objeto + */ +struct _Object +{ + /** + * Tipo do objeto. + */ + int type; + /** + * Material* do objeto. + */ + int material; + /** + * Dados do objeto. + */ + void *data; +}; + +/** + * Objeto esfera. + */ +struct _Sphere +{ + + /** + * Posição do centro da esfera na cena. + */ + Vector center; + + /** + * Raio da esfera. + */ + double radius; +}; + + +/** + * Objeto caixa. + */ +struct _Box +{ + /** + * Vértice de baixo e à esquerda do paralelepípedo. + */ + Vector bottomLeft; + /** + * Vértice de cima e à direita do paralelepípedo. + */ + Vector topRight; +}; + +/** + * Objeto triângulo. + */ +struct _Triangle +{ + /** + * Primeiro vértice do triângulo. + */ + Vector v0; + /** + * Segundo vértice do triângulo. + */ + Vector v1; + /** + * Terceiro vértice do triângulo. + */ + Vector v2; + + Vector tex0; /* coordenada de textura do verive 0 */ + Vector tex1; /* coordenada de textura do verive 1 */ + Vector tex2; /* coordenada de textura do verive 2 */ +}; +/** +* Objeto malha. +*/ +struct _Mesh +{ + /** + * Vértice de baixo e à esquerda do paralelepípedo. + */ + Vector bottomLeft; + /** + * Vértice de cima e à direita do paralelepípedo. + */ + Vector topRight; + /** + * Numero de vertices da malha. + */ + int nvertices; + /** + * Numero de triangulos da malha. + */ + int ntriangles; + /** + * Vetor dos vertices. + */ + float* coord; + /** + * Vetor da incidencia dos triangulos. + */ + int* triangle; +}; +/************************************************************************/ +/* Constantes Privadas */ +/************************************************************************/ +#define MIN( a, b ) ( ( a < b ) ? a : b ) +#define MAX( a, b ) ( ( a > b ) ? a : b ) + +#ifndef EPSILON +#define EPSILON 1.0e-3 +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + + +enum +{ + TYPE_UNKNOWN, + TYPE_SPHERE, + TYPE_TRIANGLE, + TYPE_BOX, + TYPE_MESH +}; + + +/************************************************************************/ +/* Definição das Funções Exportadas */ +/************************************************************************/ +Object* objCreateSphere( int material, const Vector center, double radius ) +{ + Object* object; + Sphere *sphere; + + object = (Object *)malloc( sizeof(Object) ); + sphere = (Sphere *)malloc( sizeof(Sphere) ); + + sphere->center = center; + sphere->radius = radius; + + object->type = TYPE_SPHERE; + object->material = material; + object->data = sphere; + + return object; +} + + +Object* objCreateTriangle( int material, const Vector v0, const Vector v1, const Vector v2, + const Vector tex0, const Vector tex1, const Vector tex2 ) +{ + Object* object; + Triangle *triangle; + + object = (Object *)malloc( sizeof(Object) ); + triangle = (Triangle *)malloc( sizeof(Triangle) ); + + triangle->v0 = v0; + triangle->v1 = v1; + triangle->v2 = v2; + + triangle->tex0 = tex0; + triangle->tex1 = tex1; + triangle->tex2 = tex2; + + object->type = TYPE_TRIANGLE; + object->material = material; + object->data = triangle; + + return object; +} + + +Object* objCreateBox( int material, const Vector bottomLeft, const Vector topRight ) +{ + Object* object; + Box *box; + + object = (Object *)malloc( sizeof(Object) ); + box = (Box *)malloc( sizeof(Box) ); + + box->bottomLeft = bottomLeft; + box->topRight = topRight; + + object->type = TYPE_BOX; + object->material = material; + object->data = box; + + return object; +} + +Object* objCreateMesh( int material, const Vector bottomLeft, const Vector topRight, const char* filename ) +{ + Object* object; + Mesh* mesh; + FILE* fp=NULL; + + object = (Object *)malloc( sizeof(Object) ); + mesh = (Mesh*)malloc( sizeof(Mesh) ); + + mesh->bottomLeft = bottomLeft; + mesh->topRight = topRight; + + object->type = TYPE_MESH; + object->material = material; + object->data = mesh; + + fp = fopen(filename,"rt"); + if (fp!=NULL) { + int i; + float xm,xM,ym,yM,zm,zM; + + fscanf(fp,"%d",&mesh->nvertices); + mesh->coord = (float*)malloc(3*mesh->nvertices*sizeof(float)); + for (i=0;invertices;i++){ + fscanf(fp," %f %f %f",&mesh->coord[3*i],&mesh->coord[3*i+1],&mesh->coord[3*i+2]); + } + fscanf(fp,"%d",&mesh->ntriangles); + mesh->triangle=(int*)malloc(3*mesh->ntriangles*sizeof(int)); + for (i=0;intriangles;i++){ + fscanf(fp," %d %d %d",&mesh->triangle[3*i],&mesh->triangle[3*i+1],&mesh->triangle[3*i+2]); + } + xm=xM=mesh->coord[0]; ym=yM=mesh->coord[1]; zm=zM=mesh->coord[2]; + for (i=1;invertices;i++){ + xm=(xmcoord[3*i+0])?xm:mesh->coord[3*i+0]; + ym=(ymcoord[3*i+1])?ym:mesh->coord[3*i+1]; + zm=(zmcoord[3*i+2])?zm:mesh->coord[3*i+2]; + xM=(xM>mesh->coord[3*i+0])?xM:mesh->coord[3*i+0]; + yM=(yM>mesh->coord[3*i+1])?yM:mesh->coord[3*i+1]; + zM=(zM>mesh->coord[3*i+2])?zM:mesh->coord[3*i+2]; + } + for (i=0;invertices;i++){ + mesh->coord[3*i+0] = (float) (bottomLeft.x+(topRight.x-bottomLeft.x)*(mesh->coord[3*i+0]-xm)/(xM-xm)); + mesh->coord[3*i+1] = (float) (bottomLeft.y+(topRight.y-bottomLeft.y)*(mesh->coord[3*i+1]-ym)/(yM-ym)); + mesh->coord[3*i+2] = (float) (bottomLeft.z+(topRight.z-bottomLeft.z)*(mesh->coord[3*i+2]-zm)/(zM-zm)); + } + } + + return object; +} + +double objMeshIntercept(Mesh* mesh,Vector origin,Vector direction,double distance) +{ + int i; + for (i=0;intriangles;i++) + { + int p0 = mesh->triangle[3*i+0]; + int p1 = mesh->triangle[3*i+1]; + int p2 = mesh->triangle[3*i+2]; + + Vector v0 = {mesh->coord[3*p0+0],mesh->coord[3*p0+1],mesh->coord[3*p0+2],1}; + Vector v1 = {mesh->coord[3*p1+0],mesh->coord[3*p1+1],mesh->coord[3*p1+2],1}; + Vector v2 = {mesh->coord[3*p2+0],mesh->coord[3*p2+1],mesh->coord[3*p2+2],1}; + + double dividend, divisor; + double distance = -1.0; + + Vector v0ToV1 = algSub( v1, v0 ); + Vector v1ToV2 = algSub( v2, v1 ); + Vector normal = algCross( v0ToV1, v1ToV2 ); + Vector eyeToV0 = algSub( v0, origin ); + + dividend = algDot( eyeToV0, normal ); + divisor = algDot( direction, normal ); + + if( divisor <= -EPSILON ) + { + distance = ( dividend / divisor ); + } + + if( distance >= 0.0001 ) + { + double a0, a1, a2; + + Vector v2ToV0 = algSub( v0, v2 ); + Vector p = algAdd( origin, algScale( distance, direction ) ); + Vector n0 = algCross( v0ToV1, algSub( p, v0 ) ); + Vector n1 = algCross( v1ToV2, algSub( p, v1 ) ); + Vector n2 = algCross( v2ToV0, algSub( p, v2 ) ); + + normal = algUnit(normal); + a0 = ( 0.5 * algDot( normal, n0 ) ); + a1 = ( 0.5 * algDot( normal, n1 ) ); + a2 = ( 0.5 * algDot( normal, n2 ) ); + + if ( (a0>0) && (a1>0) && (a2>0) ) + return distance; + } + + } + + return -1.0; +} + +double objIntercept( Object* object, Vector eye, Vector ray ) +{ + switch( object->type ) + { + case TYPE_SPHERE: + { + Sphere *s = (Sphere *)object->data; + + double a, b, c, delta; + double distance = -1.0; + + Vector fromSphereToEye; + + fromSphereToEye = algSub( eye, s->center ); + + a = algDot( ray, ray ); + b = ( 2.0 * algDot( ray, fromSphereToEye ) ); + c = ( algDot( fromSphereToEye, fromSphereToEye ) - ( s->radius * s->radius ) ); + + delta = ( ( b * b ) - ( 4 * a * c ) ); + + if( fabs( delta ) <= EPSILON ) + { + distance = ( -b / (2 * a ) ); + } + else if( delta > EPSILON ) + { + double root = sqrt( delta ); + distance = MIN( ( ( -b + root ) / ( 2 * a ) ), ( ( -b - root ) / ( 2.0 * a ) ) ); + } + + return distance; + } + + case TYPE_TRIANGLE: + { + Triangle *t = (Triangle *)object->data; + + + double dividend, divisor; + double distance = -1.0; + + Vector v0ToV1 = algSub( t->v1, t->v0 ); + Vector v1ToV2 = algSub( t->v2, t->v1 ); + Vector normal = algCross( v0ToV1, v1ToV2 ); + Vector eyeToV0 = algSub( t->v0, eye ); + + dividend = algDot( eyeToV0, normal ); + divisor = algDot( ray, normal ); + + if( divisor <= -EPSILON ) + { + distance = ( dividend / divisor ); + } + + if( distance >= 0.0001 ) /* teste para ver se e' inteior */ + { + double a0, a1, a2; + + Vector v2ToV0 = algSub( t->v0, t->v2 ); + Vector p = algAdd( eye, algScale( distance, ray ) ); + Vector n0 = algCross( v0ToV1, algSub( p, t->v0 ) ); + Vector n1 = algCross( v1ToV2, algSub( p, t->v1 ) ); + Vector n2 = algCross( v2ToV0, algSub( p, t->v2 ) ); + + normal = algUnit(normal); + a0 = ( 0.5 * algDot( normal, n0 ) ); + a1 = ( 0.5 * algDot( normal, n1 ) ); + a2 = ( 0.5 * algDot( normal, n2 ) ); + + if ( (a0>0) && (a1>0) && (a2>0) ) + return distance; + } + + return -1.0; + } + + case TYPE_BOX: + { + Box *box = (Box *)object->data; + + double xmin = box->bottomLeft.x; + double ymin = box->bottomLeft.y; + double zmin = box->bottomLeft.z; + double xmax = box->topRight.x; + double ymax = box->topRight.y; + double zmax = box->topRight.z; + + double x, y, z; + double distance = -1.0; + + if( ray.x > EPSILON || -ray.x > EPSILON ) + { + if( ray.x > 0 ) + { + x = xmin; + distance = ( ( xmin - eye.x ) / ray.x ); + } + else + { + x = xmax; + distance = ( ( xmax - eye.x ) / ray.x ); + } + + if( distance > EPSILON ) + { + y = ( eye.y + ( distance * ray.y ) ); + z = ( eye.z + ( distance * ray.z ) ); + if( ( y >= ymin ) && ( y <= ymax ) && ( z >= zmin ) && ( z <= zmax ) ) + return distance; + } + } + + if( ray.y > EPSILON || -ray.y > EPSILON ) + { + if( ray.y > 0 ) + { + y = ymin; + distance = ( ( ymin - eye.y ) / ray.y ); + } + else + { + y = ymax; + distance = ( ( ymax - eye.y ) / ray.y ); + } + + if( distance > EPSILON ) + { + x = ( eye.x + ( distance * ray.x ) ); + z = ( eye.z + ( distance * ray.z ) ); + if( ( x >= xmin ) && ( x <= xmax ) && ( z >= zmin ) && ( z <= zmax ) ) + return distance; + } + + } + + if( ray.z > EPSILON || -ray.z > EPSILON ) + { + if( ray.z > 0 ) + { + z = zmin; + distance = ( (zmin - eye.z ) / ray.z ); + } + else + { + z = zmax; + distance = ( ( zmax - eye.z ) / ray.z ); + } + + if( distance > EPSILON ) + { + x = ( eye.x + ( distance * ray.x ) ); + y = ( eye.y + ( distance * ray.y ) ); + if( ( x >= xmin ) && ( x <= xmax ) && ( y >= ymin ) && ( y <= ymax ) ) + return distance; + } + } + + return -1.0; + } + case TYPE_MESH: + { + Mesh* mesh = (Mesh*)object->data; + + double xmin = mesh->bottomLeft.x; + double ymin = mesh->bottomLeft.y; + double zmin = mesh->bottomLeft.z; + double xmax = mesh->topRight.x; + double ymax = mesh->topRight.y; + double zmax = mesh->topRight.z; + + double x, y, z; + double distance = -1.0; + + if( ray.x > EPSILON || -ray.x > EPSILON ) + { + if( ray.x > 0 ) + { + x = xmin; + distance = ( ( xmin - eye.x ) / ray.x ); + } + else + { + x = xmax; + distance = ( ( xmax - eye.x ) / ray.x ); + } + + if( distance > EPSILON ) + { + y = ( eye.y + ( distance * ray.y ) ); + z = ( eye.z + ( distance * ray.z ) ); + if( ( y >= ymin ) && ( y <= ymax ) && ( z >= zmin ) && ( z <= zmax ) ) + return objMeshIntercept(mesh,eye,ray,distance); + } + } + + if( ray.y > EPSILON || -ray.y > EPSILON ) + { + if( ray.y > 0 ) + { + y = ymin; + distance = ( ( ymin - eye.y ) / ray.y ); + } + else + { + y = ymax; + distance = ( ( ymax - eye.y ) / ray.y ); + } + + if( distance > EPSILON ) + { + x = ( eye.x + ( distance * ray.x ) ); + z = ( eye.z + ( distance * ray.z ) ); + if( ( x >= xmin ) && ( x <= xmax ) && ( z >= zmin ) && ( z <= zmax ) ) + return objMeshIntercept(mesh,eye,ray,distance); + } + + } + + if( ray.z > EPSILON || -ray.z > EPSILON ) + { + if( ray.z > 0 ) + { + z = zmin; + distance = ( (zmin - eye.z ) / ray.z ); + } + else + { + z = zmax; + distance = ( ( zmax - eye.z ) / ray.z ); + } + + if( distance > EPSILON ) + { + x = ( eye.x + ( distance * ray.x ) ); + y = ( eye.y + ( distance * ray.y ) ); + if( ( x >= xmin ) && ( x <= xmax ) && ( y >= ymin ) && ( y <= ymax ) ) + return objMeshIntercept(mesh,eye,ray,distance); + } + } + + return -1.0; + } + + default: + /* Tipo de Objeto Inválido: nunca deve acontecer */ + return -1.0; + } +} + +Vector objInterceptExit( Object* object, Vector point, Vector d ) +{ + switch( object->type ) + { + case TYPE_SPHERE: + { + Sphere *s = (Sphere *)object->data; + + double a, b, c, delta, distance; + //double distance = -1.0; + + Vector fromSphereToEye; + + fromSphereToEye = algSub( point, s->center ); + + a = algDot( d, d ); + b = ( 2.0 * algDot( d, fromSphereToEye ) ); + c = ( algDot( fromSphereToEye, fromSphereToEye ) - ( s->radius * s->radius ) ); + + delta = ( ( b * b ) - ( 4 * a * c ) ); + + if( fabs( delta ) <= EPSILON ) + { + distance = ( -b / (2 * a ) ); + } + else if( delta > EPSILON ) + { + double root = sqrt( delta ); + distance = MAX( ( ( -b + root ) / ( 2 * a ) ), ( ( -b - root ) / ( 2.0 * a ) ) ); + } + + return algAdd(point, algScale(distance, d)); + } + + case TYPE_TRIANGLE: + case TYPE_BOX: + break; + } + return point; +} + + +Vector objNormalAt( Object* object, Vector point ) +{ + if( object->type == TYPE_SPHERE ) + { + Sphere *sphere = (Sphere *)object->data; + + return algScale( ( 1.0 / sphere->radius ), + algSub( point, sphere->center ) ); + } + else if ( object->type == TYPE_TRIANGLE ) + { + Triangle *triangle = (Triangle *)object->data; + + return algCross( algSub( triangle->v1, triangle->v0 ), + algSub( triangle->v2, triangle->v0 ) ); + } + else if ( object->type == TYPE_BOX ) + { + Box *box = (Box *)object->data; + /* Seleciona a face mais próxima de point */ + if( fabs( point.x - box->bottomLeft.x ) < EPSILON ) + { + return algVector( -1, 0, 0, 1 ); + } + else if( fabs( point.x - box->topRight.x ) < EPSILON ) + { + return algVector( 1, 0, 0, 1 ); + } + else if( fabs( point.y - box->bottomLeft.y ) < EPSILON ) + { + return algVector( 0, -1, 0, 1 ); + } + else if( fabs( point.y - box->topRight.y ) < EPSILON ) + { + return algVector( 0, 1, 0, 1 ); + } + else if( fabs( point.z - box->bottomLeft.z ) < EPSILON ) + { + return algVector( 0, 0, -1, 1 ); + } + else if( fabs( point.z - box->topRight.z ) < EPSILON ) + { + return algVector( 0, 0, 1, 1 ); + } + else + { + return algVector( 0, 0, 0, 1 ); + } + } + else + { + /* Tipo de Objeto Inválido: nunca deve acontecer */ + return algVector( 0, 0, 0, 1 ); + } +} + +Vector objTextureCoordinateAt( Object* object, Vector point ) +{ + if( object->type == TYPE_SPHERE ) + { + /*...*/ + return algVector( 0, 0, 0, 1 ); + } + else if( object->type == TYPE_TRIANGLE ) + { + /*...*/ + return algVector( 0, 0, 0, 1 ); + } + else if( object->type == TYPE_BOX ) + { + /*...*/ + return algVector( 0, 0, 0, 1 ); + } + + /* Tipo de Objeto Inválido: nunca deve acontecer */ + return algVector( 0, 0, 0, 1 ); +} + +int objGetMaterial( Object* object ) +{ + return object->material; +} + +void objDestroy( Object* object ) +{ + free( object ); +} diff --git a/object.h b/object.h new file mode 100644 index 0000000..a47840d --- /dev/null +++ b/object.h @@ -0,0 +1,137 @@ +/** + * @file object.h Object*: definição e operações com primitivas. + * As primitivas suportadas atualmente são: esferas, triângulos e paralelepípedos. + * + * @author + * - Maira Noronha + * - Thiago Bastos + * - Mauricio Carneiro + * + * @date + * Criado em: 01 de Dezembro de 2002 + * Última Modificação: 22 de Janeiro de 2003 + * + * @version 2.0 + */ + +#ifndef _OBJECT_H_ +#define _OBJECT_H_ + +#include "color.h" +#include "algebra.h" +#include "material.h" + + +/************************************************************************/ +/* Tipos Exportados */ +/************************************************************************/ + + +typedef struct _Object Object; + +typedef struct _Sphere Sphere; + +typedef struct _Triangle Triangle; + +typedef struct _Box Box; + +typedef struct _Mesh Mesh; + +/************************************************************************/ +/* Funções Exportadas */ +/************************************************************************/ +/** + * Cria uma esfera. + * + * @param material Id do material da esfera. + * @param center Posição do centro da esfera na cena. + * @param radius Raio da esfera. + * + * @return Handle para o objeto criado. + */ +Object* objCreateSphere( int material, const Vector center, double radius ); + +/** + * Cria um triângulo. + * + * @param material Id do material do triângulo. + * @param v0 Primeiro vértice do triângulo. + * @param v1 Segundo vértice do triângulo. + * @param v2 Terceiro vértice do triângulo. + * @param tex0 Coordenadas de textura do primeiro vértice do triângulo. + * @param tex1 Coordenadas de textura do segundo vértice do triângulo. + * @param tex2 Coordenadas de textura do terceiro vértice do triângulo. + * + * @return Handle para o objeto criado. + */ +Object* objCreateTriangle( int material, const Vector v0, const Vector v1, const Vector v2, + const Vector tex0, const Vector tex1, const Vector tex2 ); + +/** + * Cria um paralelepípedo. + * + * @param material Id do material do paralelepípedo. + * @param bottomLeft Vértice de baixo e à esquerda do paralelepípedo. + * @param topRight Vértice de cima e à direita do paralelepípedo. + * + * @return Handle para o objeto criado. + */ +Object* objCreateBox( int material, const Vector bottomLeft, const Vector topRight ); + +/** +* Cria um malha de triangulos em um paralelepípedo. +* +* @param material Id do material da malha de triangulos. +* @param bottomLeft Vértice de baixo e à esquerda do paralelepípedo. +* @param topRight Vértice de cima e à direita do paralelepípedo. +* +* @return Handle para o objeto criado. +*/ +Object* objCreateMesh( int material, const Vector bottomLeft, const Vector topRight, const char* filename ); + +/** + * Calcula a que distância um raio intercepta um objeto. + * + * @param object Handle para um objeto. + * @param eye Origem do raio. + * @param ray Direção do raio. + * + * @return Distância de eye até a superfície do objeto no ponto onde ocorreu a + * interseção. Menor ou igual a zero se não houver interseção. + */ +double objIntercept( Object* object, Vector eye, Vector ray ); + +Vector objInterceptExit( Object* object, Vector point, Vector d ); + +/** + * Calcula o vetor normal a um objeto em um ponto. + * + * @param object Handle para um objeto. + * @param point Ponto na superfície do objeto onde a normal deve ser calculada. + * + * @return Vetor unitário, normal ao objeto, com origem em point. + */ +Vector objNormalAt( Object* object, Vector point ); + +/** + * Calcula a coordenada de textura para um objeto em um ponto. + * + * @param object Handle para um objeto. + * @param point Ponto na superfície do objeto para onde uma coordenada de textura + * será calculada. + * + * @return Coordenada de textura para o objeto no ponto especificado. + */ +Vector objTextureCoordinateAt( Object* object, Vector point ); + +/** + * Obtém o Material* de um objeto. + */ +int objGetMaterial( Object* object ); + +/** + * Destrói um objeto criado com as funções objCreate*(). + */ +void objDestroy( Object* object ); + +#endif diff --git a/parede.bmp b/parede.bmp new file mode 100644 index 0000000..49a3a86 Binary files /dev/null and b/parede.bmp differ diff --git a/paredeazul.bmp b/paredeazul.bmp new file mode 100644 index 0000000..ef4d884 Binary files /dev/null and b/paredeazul.bmp differ diff --git a/pessoa.rt4 b/pessoa.rt4 new file mode 100644 index 0000000..ae7bb03 --- /dev/null +++ b/pessoa.rt4 @@ -0,0 +1,26 @@ +RT 4.0 +CAMERA 160. 150. -65. 0. 130. -35. 0. 1. 0. 90. 1. 100. 400 400 +SCENE 120. 110. 110. 70. 40. 40. null +MATERIAL 0. 0. 255. 255. 255. 255. 50. 0. 0. 1. null +MATERIAL 180. 180. 0. 255. 255. 255. 40. 0. 0. 1. null +LIGHT 0. 20. 100. 255 255 255 +LIGHT 80. 180. -100. 155 155 155 +SPHERE 1 5.0 -1.0 0.0 20.0 +SPHERE 1 5.0 -1.0 0.0 -20.0 +SPHERE 1 5.0 2.0 55.0 20.0 +SPHERE 1 5.0 2.0 55.0 -20.0 +SPHERE 1 6.0 2.0 202.0 32.0 ! ombros +SPHERE 1 6.0 2.0 202.0 -32.0 +SPHERE 1 18.0 0.0 235.0 0.0 ! cabeça +SPHERE 1 8.0 2.0 203.0 -125.0 ! mão (dedo) +SPHERE 1 8.0 2.0 115.0 45.0 ! mão +BOX 1 5. -5. -25. 25. 5. -15. ! pés +BOX 1 5. -5. 15. 25. 5. 25. +BOX 1 -5. 5. -25. 5. 50. -15. +BOX 1 -5. 5. 15. 5. 50. 25. +BOX 1 -5. 60. -25. 5. 110. -15. +BOX 1 -5. 60. 15. 5. 110. 25. +BOX 1 -5. 112. -25. 5. 210. 25. ! corpo +BOX 1 -4. 200. -115. 4. 210. -40. ! braço esticado +BOX 1 -5. 125. 50. 5. 210. 40. ! outro braço +BOX 1 -2. 205. -145. 2. 209. -135. ! dedo diff --git a/pool.rt4 b/pool.rt4 new file mode 100644 index 0000000..83c21b1 --- /dev/null +++ b/pool.rt4 @@ -0,0 +1,49 @@ +RT 4.0 +CAMERA 45. -450. 70. 30. -300. 65. 0. 0. 1. 90. 1. 100. 400 400 +SCENE 10. 10. 10. 50. 50. 50. null +MATERIAL 0. 170. 0. 0. 0. 0. 25. 0. 0. 1. null ! mesa 0 +MATERIAL 100. 100. 0. 0. 0. 0. 50. 0. 0. 1. null ! moldura 1 +MATERIAL 200. 0. 0. 255. 255. 255. 100. .1 0. 1. null ! vermelha 2 +MATERIAL 200. 200. 200. 255. 255. 255. 100. .1 0. 1. null ! branca 3 +MATERIAL 20. 20. 20. 255. 255. 255. 100. .1 0. 1. null ! preta 4 +MATERIAL 0. 0. 250. 255. 255. 255. 100. .1 0. 1. null ! azul 5 +MATERIAL 250. 250. 0. 255. 255. 255. 100. .1 0. 1. null ! amarela 6 +MATERIAL 0. 180. 0. 255. 255. 255. 100. .1 0. 1. null ! verde 7 +MATERIAL 250. 80. 250. 255. 255. 255. 100. .1 0. 1. null ! magenta 8 +MATERIAL 200. 200. 200. 0. 0. 0. 70. 0. 0. 1. null ! parede 9 +MATERIAL 30. 30. 30. 0. 0. 0. 15. 0. 0. 1. null ! quadro 10 +MATERIAL 85. 60. 0. 0. 0. 0. 15. 0. 0. 1. null ! madeira 11 +MATERIAL 150. 130. 0. 0. 0. 0. 15. 0. 0. 1. marmore.bmp ! taco 12 +MATERIAL 0. 0. 0. 0. 0. 0. 15. 0. 0. 1. null ! ponteira 13 +MATERIAL 200. 200. 200. 0. 0. 0. 15. 0. 0. 1. null ! giz 14 +LIGHT 0. -450. 600. 255 255 255 +SPHERE 3 20. 50. -300. 20. +SPHERE 2 20. 0. 0. 20. +SPHERE 4 20. -80. -90. 20. +SPHERE 5 20. -100. 300. 20. +SPHERE 6 20. 200. 200. 20. +SPHERE 7 20. 100. 480. 20. +SPHERE 8 20. -300. 350. 20. +BOX 0 -400. -600. -20. 400. 600. 0. ! mesa +BOX 1 -400. -580. -20. -380. 580. 20. ! | +BOX 1 380. -580. -20. 400. 580. 20. ! | +BOX 1 -400. -600. -20. 400. -580. 20. ! |- moldura da mesa +BOX 1 -400. 580. -20. 400. 600. 20. ! | +BOX 9 -800. 600. -500. 800. 650. 900. ! parede +BOX 10 0. 590. 130. 800. 600. 430. ! quadro +BOX 11 -30. 595. 100. 830. 600. 460. ! moldura do quadro +BOX 13 -312. 579. 500. -308. 580. 520. ! | +BOX 13 -372. 579. 470. -368. 580. 490. ! | +BOX 13 -492. 579. 500. -488. 580. 520. ! | +BOX 11 -540. 560. 90. -260. 600. 110. ! | suportes +BOX 11 -540. 560. 430. -260. 600. 450. ! | dos tacos +TRIANGLE 12 -320. 580. 100. -300. 580. 100. -308. 580. 500. 0. 0. 1. 0. 1. 1. +TRIANGLE 12 -308. 580. 500. -312. 580. 500. -320. 580. 100. 0. 0. 1. 0. 1. 1. ! |- taco1 +TRIANGLE 12 -380. 580. 100. -360. 580. 100. -368. 580. 470. 0. 0. 1. 0. 1. 1. ! | +TRIANGLE 12 -368. 580. 500. -372. 580. 470. -380. 580. 100. 0. 0. 1. 0. 1. 1. ! |- taco2 +TRIANGLE 12 -500. 580. 100. -480. 580. 100. -488. 580. 500. 0. 0. 1. 0. 1. 1. ! | +TRIANGLE 12 -488. 580. 500. -492. 580. 500. -500. 580. 100. 0. 0. 1. 0. 1. 1. ! |- taco3 +TRIANGLE 14 200. 585. 180. 400. 585. 250. 395. 585. 250. 0. 0. 1. 0. 1. 1. ! riscos +TRIANGLE 14 100. 585. 370. 105. 585. 400. 100. 585. 400. 0. 0. 1. 0. 1. 1. +TRIANGLE 14 130. 585. 370. 135. 585. 400. 130. 585. 400. 0. 0. 1. 0. 1. 1. +TRIANGLE 14 160. 585. 370. 165. 585. 400. 160. 585. 400. 0. 0. 1. 0. 1. 1. diff --git a/raytracing.c b/raytracing.c new file mode 100644 index 0000000..d51d094 --- /dev/null +++ b/raytracing.c @@ -0,0 +1,224 @@ +/** + * @file raytracing.c RayTracing: renderização de cenas por raytracing. + * + * @date + * Criado em: 02 de Dezembro de 2002 + * Última Modificação: 04 de Outubro de 2009 + * + */ + +#include +#include +#include +#include + +#include "raytracing.h" +#include "color.h" +#include "algebra.h" + + +/************************************************************************/ +/* Constantes Privadas */ +/************************************************************************/ +#define MAX( a, b ) ( ( a > b ) ? a : b ) + +/** Número máximo de recursões permitidas */ +#define MAX_DEPTH 6 + + +/************************************************************************/ +/* Funções Privadas */ +/************************************************************************/ +/** + * Obtém uma cor através do traçado de um raio dentro de uma cena. + * + * @param scene Handle para a cena sendo renderizada. + * @param eye Posição do observador, origem do raio. + * @param ray Direção do raio. + * @param depth Para controle do número máximo de recursões. Funções clientes devem + * passar 0 (zero). A cada recursão depth é incrementado até, no máximo, + * MAX_DEPTH. Quando MAX_DEPTH é atingido, recursões são ignoradas. + * + * @return Cor resultante do traçado do raio. + */ +static Color shade( Scene* scene, Vector eye, Vector ray, Object* object, Vector point, + Vector normal, int depth ); + +/** + * Encontra o primeiro objeto interceptado pelo raio originado na posição especificada. + * + * @param scene Cena. + * @param eye Posição do Observador (origem). + * @param ray Raio sendo traçado (direção). + * @param object Onde é retornado o objeto resultante. Não pode ser NULL. + * @return Distância entre 'eye' e a superfície do objeto interceptado pelo raio. + * DBL_MAX se nenhum objeto é interceptado pelo raio, neste caso + * 'object' não é modificado. + */ +static double getNearestObject( Scene* scene, Vector eye, Vector ray, Object* *object ); + +/** + * Checa se objetos em uma cena impedem a luz de alcançar um ponto. + * + * @param scene Cena. + * @param point Ponto sendo testado. + * @param rayToLight Um raio (direção) indo de 'point' até 'lightLocation'. + * @param lightLocation Localização da fonte de luz. + * @return Zero se nenhum objeto bloqueia a luz e não-zero caso contrário. + */ +static int isInShadow( Scene* scene, Vector point, Vector rayToLight, Vector lightLocation ); + + +/************************************************************************/ +/* Definição das Funções Exportadas */ +/************************************************************************/ + +Color rayTrace( Scene* scene, Vector eye, Vector ray, int depth ) +{ + Object* object; + double distance; + + Vector point; + Vector normal; + + /* Calcula o primeiro objeto a ser atingido pelo raio */ + distance = getNearestObject( scene, eye, ray, &object ); + + /* Se o raio não interceptou nenhum objeto... */ + if( distance == DBL_MAX ) + { + return sceGetBackgroundColor( scene, eye, ray ); + } + + /* Calcula o ponto de interseção do raio com o objeto */ + point = algAdd( eye, algScale( distance, ray ) ); + + /* Obtém o vetor normal ao objeto no ponto de interseção */ + normal = objNormalAt( object, point ); + + return shade( scene, eye, ray, object, point, normal, depth ); +} + +/************************************************************************/ +/* Definição das Funções Privadas */ +/************************************************************************/ +static Color shade( Scene* scene, Vector eye, Vector ray, Object* object, Vector point, + Vector normal, int depth ) +{ + Material* material = sceGetMaterial(scene,objGetMaterial(object)); + double reflectionFactor = matGetReflectionFactor( material ); + double specularExponent = matGetSpecularExponent( material ); + double refractedIndex = matGetRefractionIndex( material ); + double opacity = matGetOpacity( material ); + Color ambient = sceGetAmbientLight( scene ); + Color diffuse = matGetDiffuse( material, objTextureCoordinateAt( object, point ) ); + Color specular = matGetSpecular( material ); + + int nlights; + int i; + double cos, sin; + Vector V; + Vector Rr, Rt; + Color colorRr, colorRt; + Vector vt, T; + + /* Começa com a cor ambiente */ + Color color = colorMultiplication( diffuse, ambient ); + + /* Adiciona a componente difusa */ + nlights = sceGetLightCount(scene); /* numero de luzes na cena */ + for (i=0; i0 && isInShadow(scene,point,L,lightpos) == 0) /* se for visivel para a luz */ + color = colorAddition(color,colorReflection(cos,lightcolor,diffuse)); + } + + /*Componente especular*/ + V = algUnit(algMinus(ray)); + for (i=0; i0 && isInShadow(scene,point,L,lightpos) == 0) + color = colorAddition(color,colorReflection(pow(cos,specularExponent),lightcolor,specular)); + } + + + depth ++; + + /*Reflexão*/ + Rr = algReflect(V,algUnit(normal)); + if ((reflectionFactor>0.001)&&(depth < MAX_DEPTH)) + { + colorRr = rayTrace (scene,point,Rr,depth); + colorRr = colorScale(reflectionFactor,colorRr); + color = colorAddition(color,colorRr); + } + + + /*Transparência */ + if(((1-opacity)>0.001)&&(depth < MAX_DEPTH)) + { + vt = algSub(algProj(V,algUnit(normal)),V); + sin = (1.0/refractedIndex)*algNorm(vt); + cos = sqrt(1.-sin*sin); + T = algUnit(vt); + Rt = algAdd(algScale(sin,T),algScale(-cos,algUnit(normal))); + //Rt=algMinus(V); + colorRt = rayTrace(scene,point,Rt,depth); + color = colorAddition(color,colorScale(1-opacity,colorRt)); + } + return color; +} + +static double getNearestObject( Scene* scene, Vector eye, Vector ray, Object** object ) +{ + int i; + int objectCount = sceGetObjectCount( scene ); + + double closest = DBL_MAX; + + /* Para cada objeto na cena */ + for( i = 0; i < objectCount; ++i ) { + Object* currentObject = sceGetObject( scene, i ); + double distance = objIntercept( currentObject, eye, ray ); + + if( distance > 0.001 && distance < closest ) /* 0.001 e' uma tolerancia (autointersecao) */ + { + closest = distance; + *object = currentObject; + } + } + + return closest; +} + +static int isInShadow( Scene* scene, Vector point, Vector rayToLight, Vector lightLocation ) +{ + int i; + int objectCount = sceGetObjectCount( scene ); + + /* maxDistance = distância de point até lightLocation */ + double maxDistance = algNorm( algSub( lightLocation, point ) ); + + /* Para cada objeto na cena */ + for( i = 0; i < objectCount; ++i ) + { + double distance = objIntercept( sceGetObject( scene, i ), point, rayToLight ); + + if( distance > 0.1 && distance < maxDistance ) + { + return 1; + } + } + + return 0; +} + diff --git a/raytracing.h b/raytracing.h new file mode 100644 index 0000000..0ab7bd5 --- /dev/null +++ b/raytracing.h @@ -0,0 +1,38 @@ +/** + * @file raytracing.h RayTracing: renderização de cenas por raytracing. + * + * @author + * - Maira Noronha + * - Thiago Bastos + * + * @date + * Criado em: 02 de Dezembro de 2002 + * Última Modificação: 7 de Setembro de 2004 + * + * @version 2.0 + */ + +#ifndef _RAYTRACING_H_ +#define _RAYTRACING_H_ + +#include "scene.h" +#include "algebra.h" +#include "color.h" + + +/************************************************************************/ +/* Funções Exportadas */ +/************************************************************************/ +/** + * Calcula a cor correspondente ao raio que parte de eye na direcao ray. + * + * @param scene Handle para cena. + * @param eye vetor de posicao da origem do raio. + * @param ray vetor de direcao do raio. + * @param depth nivel de recursao do raio (inicialmente deve ser passado como 0). + * + * @return cor correspondente ao raio. + */ +Color rayTrace( Scene* scene, Vector eye, Vector ray, int depth ); +#endif + diff --git a/rhino_skin.bmp b/rhino_skin.bmp new file mode 100644 index 0000000..f95b8e9 Binary files /dev/null and b/rhino_skin.bmp differ diff --git a/room.rt4 b/room.rt4 new file mode 100644 index 0000000..6fdd483 --- /dev/null +++ b/room.rt4 @@ -0,0 +1,53 @@ +RT 4.0 +CAMERA 280. -60. 245. 0. -100. 245. 0. 1. 0. 90. 1. 100. 400 400 +SCENE 0. 120. 255. 80. 100. 120. null +MATERIAL 70. 50. 0. 0. 0. 0. 30. 0. 0. 1. null !madeira +MATERIAL 0. 0. 0. 0. 0. 0. 30. 0. 0. 1. null !lustre +MATERIAL 200. 200. 200. 0. 0. 0. 30. 0. 0. 1. parede.bmp !paredes +MATERIAL 150. 200. 200. 0. 0. 0. 30. 0. 0. 1. null !teto +MATERIAL 70. 70. 0. 0. 0. 0. 30. 0. 0. 1. wood.bmp !piso +MATERIAL 100. 0. 90. 0. 0. 0. 30. 0. 0. 1. null !mesa +MATERIAL 150. 150. 0. 0. 0. 0. 0. 0. 0. 1. null !tapete +MATERIAL 80. 60. 0. 0. 0. 0. 30. 0. 0. 1. null !estante +MATERIAL 100. 0. 0. 200. 50. 50. 50. 0. 0. 1. null !bola +MATERIAL 0. 0. 100. 50. 50. 200. 30. 0. 0. 1. null !caixa +MATERIAL 0. 0. 0. 100. 100. 100. 80. 0.9 0. 1. null !quadro +MATERIAL 0. 0. 0. 100. 100. 100. 80. 0. 0. 1. null !desenho 1 +MATERIAL 0. 0. 0. 100. 100. 100. 80. 0. 0. 1. null !desenho 2 +MATERIAL 0. 0. 0. 100. 100. 100. 80. 0. 0. 1. null !desenho 3 +MATERIAL 0. 0. 0. 100. 100. 100. 80. 0. 0. 1. null !desenho 4 +MATERIAL 0. 0. 0. 100. 100. 100. 80. 0. 0. 1. null !desenho 5 +LIGHT 0. 12. 245. 200 200 200 +LIGHT -100. 0. -1000. 255 255 255 +LIGHT 900. -50. 245. 100 100 100 +SPHERE 1 10. 0. 30. 245. +SPHERE 8 15. -150. -103. 150. ! bola +BOX 2 -200. -165. 95. 200. -88.75 105. +BOX 2 -200. -21.25 95. 200. 35. 105. +BOX 2 -200. -165. 95. -67.5 35. 105. +BOX 2 67.5 -165. 95. 200. 35. 105. +BOX 2 -200. -165. 395. 200. 35. 405. ! parede esquerda +BOX 2 -205. -165. 95. -200. 35. 405. ! parede fundo +BOX 3 -200. 35. 95. 200. 40. 405. ! teto +BOX 4 -200. -170. 95. 200. -165. 405. ! piso +BOX 5 -70. -165. 390. -65. -100. 395. ! | +BOX 5 65. -165. 390. 70. -100. 395. ! |- pes da mesa +BOX 5 -70. -165. 280. -65. -100. 285. ! | +BOX 5 65. -165. 280. 70. -100. 285. ! | +BOX 5 -70. -150. 280. -68. -125. 395. ! lateral da mesa +BOX 5 68. -150. 280. 70. -125. 395. ! lateral da mesa +BOX 5 -70. -100. 280. 70. -90. 395. ! tampa da mesa +BOX 0 -68. -89. 95. -65. -21. 105. ! | +BOX 0 65. -89. 95. 68. -21. 105. ! | +BOX 0 -68. -24. 95. 68. -21. 105. ! |- armacao janela +BOX 0 -68. -89. 95. 68. -86. 105. ! | +BOX 0 -1. -89. 100. 1. -21. 105. ! | +BOX 0 -68. -55. 100. 68. -52. 105. ! | +BOX 6 -150. -166. 145. 150. -164. 325. ! tapete +BOX 7 -200. -120. 105. -100. -118. 205. ! tampa da estante +BOX 7 -200. -165. 110. -100. -120. 112. ! pe da estante (mais longe) +BOX 7 -200. -165. 198. -100. -120. 200. ! pe da estante +BOX 7 -200. -135. 110. -100. -133. 200. ! prateleira +BOX 9 -150. -118. 170. -120. -98. 200. ! caixa +BOX 0 -200. -100. 250. -199. 0. 350. ! moldura do quadro +BOX 10 -199. -95. 255 -198.5 -5. 345. ! quadro diff --git a/scene.c b/scene.c new file mode 100644 index 0000000..31ce634 --- /dev/null +++ b/scene.c @@ -0,0 +1,388 @@ +/** + * @file scene.c Scene: definição e manutenção de cenas. + * + * @author + * - Maira Noronha + * - Thiago Bastos + * + * @date + * Criado em: 02 de Dezembro de 2002 + * Última Modificação: 4 de Junho de 2003 + * + * @version 2.0 + */ + +#include "scene.h" +#include "raytracing.h" +#include +#include +#include +#include +#include + + +/** + * Cena com a camera, os objetos, as luzes e a imagem/cor de fundo. + */ +struct _Scene +{ + /** + * Camera* da cena + */ + Camera* camera; + + /** + * Cor de fundo da cena + */ + Color bgColor; + /** + * Imagem de fundo da cena + */ + Image* bgImage; + + /** + * Número de materiais existentes na cena. + */ + int materialCount; + /** + * Vetor com os materiais existentes na cena. + */ + Material* materials[MAX_MATERIALS]; + + /** + * Número de objetos existentes na cena. + */ + int objectCount; + /** + * Vetor com os objetos existentes na cena. + */ + Object* objects[MAX_OBJECTS]; + + /** + * Intensidade rgb da luz ambiente da cena + */ + Color ambientLight; + /** + * Número de fontes de luz existentes na cena. + */ + int lightCount; + /** + * Vetor com as fontes de luz existentes na cena. + */ + Light* lights[MAX_LIGHTS]; +}; + +/************************************************************************/ +/* Definição das Funções Exportadas */ +/************************************************************************/ +Color sceGetBackgroundColor( Scene* scene, Vector eye, Vector ray ) +{ + double planeDistance, divisor, distance, scaleU, scaleV; + Vector farOrigin, farNormal, farU, farV, point, pointFromOrigin; + + if( scene->bgImage == NULL || scene->camera == NULL ) + { + return scene->bgColor; + } + + /* Obtém informações sobre o far plane */ + camGetFarPlane( scene->camera, &farOrigin, &farNormal, &farU, &farV ); + + /* Cos(alpha) entre a normal do plano e o raio */ + divisor = algDot( ray, farNormal ); + + /* Se o raio se distancia ou é paralelo ao far plane */ + if( divisor > 0 || -divisor < EPSILON ) + { + return scene->bgColor; + } + + planeDistance = algDot( farOrigin, farNormal ); + + distance = ( ( planeDistance - algDot( eye, farNormal ) ) / divisor ); + + /* Se o raio se distancia do far plane */ + if( distance < 0 ) + { + return scene->bgColor; + } + + point = algAdd( eye, algScale( distance, ray ) ); + + pointFromOrigin = algSub( point, farOrigin ); + + divisor = algDot( farU, farU ); + scaleU = ( algDot( farU, pointFromOrigin ) / divisor ); + + divisor = algDot( farV, farV ); + scaleV = ( algDot( farV, pointFromOrigin ) / divisor ); + + /* Se o raio não intercepta o far plane (ou seja, a imagem de fundo)... */ + if( scaleU < 0 || scaleV < 0 || scaleU > 1 || scaleV > 1 ) + { + return scene->bgColor; + } + + return imageGetPixel( scene->bgImage, + (int)( scaleU * camGetScreenWidth( scene->camera ) ), + (int)( scaleV * camGetScreenHeight( scene->camera ) ) ); +} + +Color sceGetAmbientLight( Scene* scene ) +{ + return scene->ambientLight; +} + +Camera* sceGetCamera( Scene* scene ) +{ + return scene->camera; +} + +int sceGetObjectCount( Scene* scene ) +{ + return scene->objectCount; +} + +Object* sceGetObject( Scene* scene, int index ) +{ + if( index < 0 || index >= scene->objectCount ) + { + return NULL; + } + + return scene->objects[index]; +} + +int sceGetLightCount( Scene* scene ) +{ + return scene->lightCount; +} + +Light* sceGetLight( Scene* scene, int index ) +{ + if( index < 0 || index >= scene->lightCount ) + { + return NULL; + } + + return scene->lights[index]; +} + +Scene* sceLoad( const char *filename ) +{ + FILE *file; + char buffer[512]; + + Scene* scene; + + Color bgColor; + Color ambientLight; + char backgroundFileName[FILENAME_MAXLEN]; + + /* Camera* */ + Vector eye = algVector( 0,0,0,1 ); + Vector at = algVector( 0,0,0,1 ); + Vector up = algVector( 0,0,0,1 ); + double fovy; + double nearp; + double farp; + int screenWidth; + int screenHeight; + + /* Material* */ + Color diffuse; + Color specular; + double specularExponent; + double reflective; + double refractive; + double opacity; + char textureFileName[FILENAME_MAXLEN]; + + /* Lights & Objects */ + Color lightColor; + int material; + Vector pos1 = algVector( 0,0,0,1 ); + Vector pos2 = algVector( 0,0,0,1 ); + Vector pos3 = algVector( 0,0,0,1 ); + Vector tex1 = algVector( 0,0,0,1 ); + Vector tex2 = algVector( 0,0,0,1 ); + Vector tex3 = algVector( 0,0,0,1 ); + double radius; + + file = fopen( filename, "rt" ); + if( !file ) + { + return NULL; + } + + scene = (struct _Scene *)malloc( sizeof(struct _Scene) ); + if( !scene ) + { + return NULL; + } + + /* Default (undefined) values: */ + scene->camera = NULL; + scene->bgImage = NULL; + scene->objectCount = 0; + scene->lightCount = 0; + scene->materialCount = 0; + + while( fgets( buffer, sizeof(buffer), file ) ) + { + if( sscanf( buffer, "RT %lf\n", &at ) == 1 ) + { + /* Ignore File Version Information */ + } + else if( sscanf( buffer, "CAMERA %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %d %d\n", &eye.x, &eye.y, &eye.z, &at.x, &at.y, &at.z, &up.x, &up.y, &up.z, &fovy, &nearp, &farp, &screenWidth, &screenHeight ) == 14) + { + if( scene->camera ) + { + camDestroy( scene->camera ); + } + + scene->camera = camCreate( eye, at, up, fovy, nearp, farp, screenWidth, screenHeight ); + } + else if( sscanf( buffer, "SCENE %f %f %f %f %f %f %s\n", &bgColor.red, &bgColor.green, &bgColor.blue, &ambientLight.red, &ambientLight.green, &ambientLight.blue, backgroundFileName ) == 7 ) + { + bgColor = colorNormalize( bgColor ); + ambientLight = colorNormalize( ambientLight ); + + scene->bgColor = bgColor; + scene->ambientLight = ambientLight; + + if( scene->bgImage ) + { + imgDestroy( scene->bgImage ); + } + + if( strcmp( backgroundFileName, "null") == 0 ) + { + scene->bgImage = NULL; + } + else + { + scene->bgImage = imgReadBMP (backgroundFileName); + } + } + else if( sscanf( buffer, "MATERIAL %f %f %f %f %f %f %lf %lf %lf %lf %s\n", &diffuse.red, &diffuse.green, &diffuse.blue, &specular.red, &specular.green, &specular.blue, &specularExponent, &reflective, &refractive, &opacity, textureFileName ) == 11 ) + { + Image *image = NULL; + + if( strcmp( textureFileName, "null") != 0 ) + { + image = imgReadBMP (textureFileName); + } + + if( scene->materialCount >= MAX_MATERIALS ) + { + imgDestroy( image ); + fprintf( stderr, "sceLoad: Foi ultrapassado o limite de definicoes de materiais na cena. Ignorando." ); + continue; + } + + diffuse = colorNormalize( diffuse ); + specular = colorNormalize( specular ); + + scene->materials[scene->materialCount++] = matCreate( image, diffuse, specular, specularExponent, reflective, refractive, opacity ); + } + else if( sscanf( buffer, "LIGHT %lf %lf %lf %f %f %f\n", &pos1.x, &pos1.y, &pos1.z, &lightColor.red, &lightColor.green, &lightColor.blue ) == 6 ) + { + if( scene->lightCount >= MAX_LIGHTS ) + { + fprintf( stderr, "sceLoad: Foi ultrapassado o limite de definicoes de luzes na cena. Ignorando." ); + continue; + } + + lightColor = colorNormalize( lightColor ); + + scene->lights[scene->lightCount++] = lightCreate( pos1, lightColor ); + } + else if( sscanf( buffer, "SPHERE %d %lf %lf %lf %lf\n", &material, &radius, &pos1.x,&pos1.y,&pos1.z ) == 5 ) + { + if( scene->objectCount >= MAX_OBJECTS ) + { + fprintf( stderr, "sceLoad: Foi ultrapassado o limite de definicoes de objetos na cena. Ignorando." ); + continue; + } + + scene->objects[scene->objectCount++] = objCreateSphere( material, pos1, radius ); + } + else if( sscanf( buffer, "TRIANGLE %d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n", &material, &pos1.x, &pos1.y, &pos1.z, &pos2.x, &pos2.y, &pos2.z, &pos3.x, &pos3.y, &pos3.z, &tex1.x, &tex1.y, &tex2.x, &tex2.y, &tex3.x, &tex3.y) == 16 ) + { + if( scene->objectCount >= MAX_OBJECTS ) + { + fprintf( stderr, "sceLoad: Foi ultrapassado o limite de definicoes de objetos na cena. Ignorando." ); + continue; + } + + scene->objects[scene->objectCount++] = objCreateTriangle( material, pos1, pos2, pos3, tex1, tex2, tex3 ); + } + else if( sscanf( buffer, "BOX %d %lf %lf %lf %lf %lf %lf\n", &material, &pos1.x, &pos1.y, &pos1.z, &pos2.x, &pos2.y, &pos2.z ) == 7 ) + { + if( scene->objectCount >= MAX_OBJECTS ) + { + fprintf( stderr, "sceLoad: Foi ultrapassado o limite de definicoes de objetos na cena. Ignorando." ); + continue; + } + + scene->objects[scene->objectCount++] = objCreateBox( material, pos1, pos2 ); + } + else if( sscanf( buffer, "MESH %d %lf %lf %lf %lf %lf %lf %s\n", &material, &pos1.x, &pos1.y, &pos1.z, &pos2.x, &pos2.y, &pos2.z, buffer ) == 8 ) + { + if( scene->objectCount >= MAX_OBJECTS ) + { + fprintf( stderr, "sceLoad: Foi ultrapassado o limite de definicoes de objetos na cena. Ignorando." ); + continue; + } + + scene->objects[scene->objectCount++] = objCreateMesh( material, pos1, pos2, buffer ); + } + else + { + printf( "sceLoad: Ignorando comando:\n %s\n", buffer ); + } + } + + /* Adjust background image to screen size */ + if( scene->camera && scene->bgImage ) + { + scene->bgImage = imgResize( scene->bgImage, camGetScreenWidth( scene->camera ), + camGetScreenHeight( scene->camera ) ); + } + + fclose( file ); + + return scene; +} + +int sceGetMaterialCount( Scene* scene ) +{ + return scene->materialCount; +} + +Material* sceGetMaterial( Scene* scene, int index ) +{ + return scene->materials[index]; +} + +void sceDestroy( Scene* scene ) +{ + int i; + + camDestroy( scene->camera ); + imgDestroy( scene->bgImage ); + + for( i = 0; i < scene->objectCount; ++i ) + { + objDestroy( scene->objects[i] ); + } + + for( i = 0; i < scene->materialCount; ++i ) + { + matDestroy( scene->materials[i] ); + } + + free( scene ); +} + diff --git a/scene.h b/scene.h new file mode 100644 index 0000000..9b9dc14 --- /dev/null +++ b/scene.h @@ -0,0 +1,140 @@ +/** + * @file scene.h Scene: definição e manutenção de cenas. + * + * @author + * - Maira Noronha + * - Thiago Bastos + * + * @date + * Criado em: 02 de Dezembro de 2002 + * Última Modificação: 4 de Junho de 2003 + * + * @version 2.0 + */ + +#ifndef _SCENE_H_ +#define _SCENE_H_ + +#include "image.h" +#include "light.h" +#include "camera.h" +#include "object.h" +#include "material.h" + + +/************************************************************************/ +/* Constantes Exportadas */ +/************************************************************************/ +#define MAX_MATERIALS 64 +#define MAX_OBJECTS 128 +#define MAX_LIGHTS 100 +#define FILENAME_MAXLEN 64 + +#ifndef EPSILON +#define EPSILON 1.0e-10 +#endif + + +/************************************************************************/ +/* Tipos Exportados */ +/************************************************************************/ + +typedef struct _Scene Scene; + + +/************************************************************************/ +/* Funções Exportadas */ +/************************************************************************/ +/** + * Obtém uma cor de fundo traçando um raio dentro de uma cena. + * É necessário que uma câmera tenha sido definida para a cena. + * Se o raio atingir o far plane e houver uma imagem de fundo, a cor é retirada dessa + * imagem. Senão, a cor de fundo padrão é retornada. + * + * @param scene Handle para uma cena. + * @param eye Origem do raio. + * @param ray Direção do raio. + * + * @return Cor de fundo para o raio fornecido na cena fornecida. + */ +Color sceGetBackgroundColor( Scene* scene, Vector eye, Vector ray ); + +/** + * Obtém a luz ambiente de uma cena. + */ +Color sceGetAmbientLight( Scene* scene ); + +/** + * Obtém a câmera de uma cena. + */ +Camera* sceGetCamera( Scene* scene ); + +/** + * Obtém o número de objetos existentes em uma cena. + * + * @param scene Handle para uma cena. + * + * @return Número de objetos na cena. + */ +int sceGetObjectCount( Scene* scene ); + +/** + * Obtém um objeto de uma cena. + * + * @param scene Handle para uma cena. + * @param index Índice do objeto a ser obtido (de 0 a objectCount - 1). + * + * @return Objeto no índice especificado (NULL se o índice for inválido). + */ +Object* sceGetObject( Scene* scene, int index ); + +/** + * Obtém o número de fontes de luz existentes em uma cena. + * + * @param scene Handle para uma cena. + * + * @return Número de luzes na cena. + */ +int sceGetLightCount( Scene* scene ); + +/** + * Obtém uma fonte de luz de uma cena. + * + * @param scene Handle para uma cena. + * @param index Índice da fonte de luz a ser obtida (de 0 a lightCount - 1). + * + * @return A fonte de luz no índice especificado (NULL se o índice for inválido). + */ +Light* sceGetLight( Scene* scene, int index ); + +/** + * Lê uma cena a partir de um arquivo em formato rt4. + * + * @param filename nome do arquivo que contém a cena. + * + * @return Cena criada (NULL se o arquivo for inválido). + */ +Scene* sceLoad( const char *filename ); + +/** + * Obtém o número de materiais de uma cena. + */ +int sceGetMaterialCount( Scene* scene ); + +/** + * Obtém um material de uma cena. + * + * @param scene Handle para uma cena. + * @param index Índice do material (de 0 a materialCount - 1). + * + * @return O material no índice especificado (NULL se o índice for inválido). + */ +Material* sceGetMaterial( Scene* scene, int index ); + +/** + * Destrói uma cena. + */ +void sceDestroy( Scene* scene ); + +#endif + diff --git a/sky.bmp b/sky.bmp new file mode 100644 index 0000000..b1a7a7b Binary files /dev/null and b/sky.bmp differ diff --git a/wall.rt4 b/wall.rt4 new file mode 100644 index 0000000..2fe6b79 --- /dev/null +++ b/wall.rt4 @@ -0,0 +1,9 @@ +RT 4.0 +CAMERA 35. 2. 1.7 0. -15. 0. 0. 0. 1. 60. 1. 100. 400 400 +SCENE 0. 0. 110. 30. 30. 30. null +MATERIAL 255. 0. 0. 0. 0. 0. 50. 0. 0. 1. RedBricks.bmp +LIGHT 35. 2. 2. 255 255 255 +TRIANGLE 0 30. 0. 0. 0. 0. 0. 0. 0. 3. 0. 0. 30. 0. 30. 1. +TRIANGLE 0 30. 0. 0. 0. 0. 3. 30. 0. 3. 0. 0. 30. 1. 0. 1. +TRIANGLE 0 30. -30. 0. 30. 0. 0. 30. 0. 3. 0. 0. 30. 0. 30. 1. +TRIANGLE 0 30. -30. 0. 30. 0. 3. 30. -30. 3. 0. 0. 3. 1. 0. 1. diff --git a/watery.bmp b/watery.bmp new file mode 100644 index 0000000..c2b98fc Binary files /dev/null and b/watery.bmp differ diff --git a/wood.bmp b/wood.bmp new file mode 100644 index 0000000..7459957 Binary files /dev/null and b/wood.bmp differ