From b5b15171ca48d94c8b6594b0113d9ad9f7aa56ba Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Thu, 16 Jul 1998 00:45:41 +0000 Subject: [PATCH] Updated MapObject plug-in. --Sven --- ChangeLog | 4 + plug-ins/MapObject/CHANGES | 3 +- plug-ins/MapObject/README | 9 +- plug-ins/MapObject/TODO | 2 +- plug-ins/MapObject/mapobject_apply.c | 58 ++- plug-ins/MapObject/mapobject_apply.h | 2 +- plug-ins/MapObject/mapobject_image.c | 68 ++++ plug-ins/MapObject/mapobject_image.h | 22 +- plug-ins/MapObject/mapobject_main.c | 142 ++++--- plug-ins/MapObject/mapobject_main.h | 7 +- plug-ins/MapObject/mapobject_preview.c | 106 +++++- plug-ins/MapObject/mapobject_shade.c | 505 ++++++++++++++++++++++++- plug-ins/MapObject/mapobject_shade.h | 10 +- plug-ins/MapObject/mapobject_ui.c | 212 +++++++++-- plug-ins/MapObject/mapobject_ui.h | 2 +- 15 files changed, 1045 insertions(+), 107 deletions(-) diff --git a/ChangeLog b/ChangeLog index f20ac608ef..322b499bc9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Thu Jul 16 02:43:51 MEST 1998 Sven Neumann + + updated MapObject plug-in + Wed Jul 15 04:55:30 PDT 1998 Jay Cox * app/gimpbrushgenerated.c diff --git a/plug-ins/MapObject/CHANGES b/plug-ins/MapObject/CHANGES index 0afb49c296..51d710e004 100644 --- a/plug-ins/MapObject/CHANGES +++ b/plug-ins/MapObject/CHANGES @@ -13,4 +13,5 @@ Changes (post 0.31): annoying bugs. Better support for partial transparency (only filtered transparency now, perhaps additive later). Compiles without warnings with -Wall and -ansi. - +-> 1.10 Added box object and changed PDB interface accordingly; this will unfortunately + break old scripts. The transparency code should be a little saner now. diff --git a/plug-ins/MapObject/README b/plug-ins/MapObject/README index 753551a344..1c1aef505c 100644 --- a/plug-ins/MapObject/README +++ b/plug-ins/MapObject/README @@ -1,10 +1,12 @@ -MapObject 1.00 -- image filter plug-in for The GIMP program +MapObject 1.10 -- image filter plug-in for The GIMP program =========================================================== Copyright (C) 1996-98 Tom Bech Copyright (C) 1996-98 Federico Mena Quintero +Released 17th of July, 1998 + You can reach the author(s) via E-mail: tomb@gimp.org (Tom) or quartic@gimp.org (Federico). @@ -36,14 +38,14 @@ In other words, you can't sue us for whatever happens while using this ;) Compiling ========= -To compile you'll need The GIMP 0.99.20 and GTK+ 0.99.7 or later. +To compile you'll need The GIMP 1.0 and GTK+ 1.0.4 or later. You'll also need GCK 1.00 (http://www.ii.uib.no/~tomb/gck.html) 1) Edit the Makefile to reflect your system setup. 2) Type "make" and then "make install" -You should now be ready to run. "make install" puts the executable "map_object" +You should now be ready to run. "make install" puts the executable "MapObject" in the standard plug-in directory. Documentation @@ -56,3 +58,4 @@ Please send me a mail if you find any bugs. Have fun, Tom + diff --git a/plug-ins/MapObject/TODO b/plug-ins/MapObject/TODO index 97544f1afb..cab622e37c 100644 --- a/plug-ins/MapObject/TODO +++ b/plug-ins/MapObject/TODO @@ -6,7 +6,7 @@ The MapObject plug-in "todo"-list: * Rotation by mouse (doesn't work correctly yet and is disabled). * Faster mapping code * Multiple light-sources -* More objects - at least cube and cylinder. +* More objects - cylinder? * Presets (including save/load) * Gray-scale/channels support * Documentation diff --git a/plug-ins/MapObject/mapobject_apply.c b/plug-ins/MapObject/mapobject_apply.c index e8c2b6a9b3..3b9dcfceff 100644 --- a/plug-ins/MapObject/mapobject_apply.c +++ b/plug-ins/MapObject/mapobject_apply.c @@ -9,9 +9,11 @@ /*************/ gdouble imat[4][4]; +gfloat rotmat[16], a[16], b[16]; void init_compute(void) { + gint i; switch (mapvals.maptype) { @@ -73,6 +75,45 @@ void init_compute(void) get_ray_color=get_ray_color_plane; + break; + case MAP_BOX: + gck_vector3_set(&mapvals.firstaxis, 1.0,0.0,0.0); + gck_vector3_set(&mapvals.secondaxis,0.0,1.0,0.0); + gck_vector3_set(&mapvals.normal,0.0,0.0,1.0); + + get_ray_color=get_ray_color_box; + + ident_mat(rotmat); + + rotatemat(mapvals.alpha, &mapvals.firstaxis, a); + + matmul(a,rotmat,b); + + memcpy(rotmat, b, sizeof(gfloat)*16); + + rotatemat(mapvals.beta, &mapvals.secondaxis, a); + matmul(a,rotmat,b); + + memcpy(rotmat, b, sizeof(gfloat)*16); + + rotatemat(mapvals.gamma, &mapvals.normal, a); + matmul(a,rotmat,b); + + memcpy(rotmat, b, sizeof(gfloat)*16); + + /* Set up pixel regions for the box face images */ + /* ============================================ */ + + for (i=0;i<6;i++) + { + box_drawables[i] = gimp_drawable_get (mapvals.boxmap_id[i]); + + gimp_pixel_rgn_init (&box_regions[i], box_drawables[i], + 0, 0, + box_drawables[i]->width, box_drawables[i]->height, + FALSE, FALSE); + } + break; } @@ -139,11 +180,18 @@ void compute_image(void) gimp_pixel_rgn_init (&dest_region, output_drawable, 0, 0, width, height, TRUE, TRUE); - if (mapvals.maptype==MAP_PLANE) - gimp_progress_init("Map to object (plane)"); - else - gimp_progress_init("Map to object (sphere)"); - + switch (mapvals.maptype) + { + case MAP_PLANE: + gimp_progress_init("Map to object (plane)"); + break; + case MAP_SPHERE: + gimp_progress_init("Map to object (sphere)"); + break; + case MAP_BOX: + gimp_progress_init("Map to object (box)"); + break; + } if (mapvals.antialiasing==FALSE) { for (ycount=0;ycountbpp==4) + { + if (gimp_drawable_has_alpha(box_drawables[image]->id)) + color.a=(gdouble)(data[3])/255.0; + else + color.a=1.0; + } + else + color.a=1.0; + + return(color); +} + void poke(gint x,gint y,GckRGB *color) { static guchar data[4]; @@ -68,6 +95,19 @@ gint checkbounds(gint x,gint y) return(TRUE); } +gint checkbounds_image(gint image, gint x,gint y) +{ + gint w,h; + + w = box_drawables[image]->width; + h = box_drawables[image]->height; + + if (x<0 || y<0 || x>=w || y>=h) + return(FALSE); + else + return(TRUE); +} + GckVector3 int_to_pos(gint x,gint y) { GckVector3 pos; @@ -139,6 +179,34 @@ GckRGB get_image_color(gdouble u,gdouble v,gint *inside) return(gck_bilinear_rgba(u * width, v * height, p)); } +GckRGB get_box_image_color(gint image,gdouble u,gdouble v) +{ + gint w,h, x1, y1, x2, y2; + GckRGB p[4]; + + w = box_drawables[image]->width; + h = box_drawables[image]->height; + + x1 = (gint)((u*(gdouble)w)); + y1 = (gint)((v*(gdouble)h)); + + if (checkbounds_image(image, x1,y1)==FALSE) + return(background); + + x2 = (x1 + 1); + y2 = (y1 + 1); + + if (checkbounds_image(image, x2,y2)==FALSE) + return(peek_image(image, x1,y1)); + + p[0] = peek_image(image, x1, y1); + p[1] = peek_image(image, x2, y1); + p[2] = peek_image(image, x1, y2); + p[3] = peek_image(image, x2, y2); + + return(gck_bilinear_rgba(u*w, v*h, p)); +} + /****************************************/ /* Allocate memory for temporary images */ /****************************************/ diff --git a/plug-ins/MapObject/mapobject_image.h b/plug-ins/MapObject/mapobject_image.h index 33be0345b4..fec791462f 100644 --- a/plug-ins/MapObject/mapobject_image.h +++ b/plug-ins/MapObject/mapobject_image.h @@ -20,6 +20,9 @@ extern GDrawable *input_drawable,*output_drawable; extern GPixelRgn source_region,dest_region; +extern GDrawable *box_drawables[6]; +extern GPixelRgn box_regions[6]; + extern guchar *preview_rgb_data; extern GdkImage *image; @@ -35,14 +38,15 @@ extern GTile *current_in_tile, *current_out_tile; /* Externally visible functions */ /* ============================ */ -extern gint image_setup (GDrawable *drawable,gint interactive); -extern glong in_xy_to_index (gint x,gint y); -extern glong out_xy_to_index (gint x,gint y); -extern gint checkbounds (gint x,gint y); -extern GckRGB peek (gint x,gint y); -extern void poke (gint x,gint y,GckRGB *color); -extern GckVector3 int_to_pos (gint x,gint y); -extern void pos_to_int (gdouble x,gdouble y,gint *scr_x,gint *scr_y); -extern GckRGB get_image_color (gdouble u,gdouble v,gint *inside); +extern gint image_setup (GDrawable *drawable,gint interactive); +extern glong in_xy_to_index (gint x,gint y); +extern glong out_xy_to_index (gint x,gint y); +extern gint checkbounds (gint x,gint y); +extern GckRGB peek (gint x,gint y); +extern void poke (gint x,gint y,GckRGB *color); +extern GckVector3 int_to_pos (gint x,gint y); +extern void pos_to_int (gdouble x,gdouble y,gint *scr_x,gint *scr_y); +extern GckRGB get_image_color (gdouble u,gdouble v,gint *inside); +extern GckRGB get_box_image_color (gint image, gdouble u,gdouble v); #endif diff --git a/plug-ins/MapObject/mapobject_main.c b/plug-ins/MapObject/mapobject_main.c index f38ae8d3a8..98f9033638 100644 --- a/plug-ins/MapObject/mapobject_main.c +++ b/plug-ins/MapObject/mapobject_main.c @@ -1,5 +1,5 @@ /*********************************************************************************/ -/* MapObject 1.00 -- image filter plug-in for The Gimp program */ +/* MapObject 1.10 -- image filter plug-in for The Gimp program */ /* Copyright (C) 1996-98 Tom Bech */ /* Copyright (C) 1996-98 Federico Mena Quintero */ /*===============================================================================*/ @@ -17,7 +17,7 @@ /*===============================================================================*/ /* You should have received a copy of the GNU General Public License along with */ /* this program (read the "COPYING" file); if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /*===============================================================================*/ /* In other words, you can't sue us for whatever happens while using this ;) */ /*********************************************************************************/ @@ -42,6 +42,8 @@ void mapobject_noninteractive (GDrawable *drawable); void set_default_settings(void) { + gint i; + gck_vector3_set(&mapvals.viewpoint, 0.5,0.5,2.0); gck_vector3_set(&mapvals.firstaxis, 1.0,0.0,0.0); gck_vector3_set(&mapvals.secondaxis, 0.0,1.0,0.0); @@ -49,6 +51,7 @@ void set_default_settings(void) gck_vector3_set(&mapvals.position, 0.5,0.5,0.0); gck_vector3_set(&mapvals.lightsource.position, -0.5,-0.5,2.0); gck_vector3_set(&mapvals.lightsource.direction, -1.0,-1.0,1.0); + gck_vector3_set(&mapvals.scale, 0.5,0.5,0.5); mapvals.maptype=MAP_PLANE; @@ -76,52 +79,83 @@ void set_default_settings(void) mapvals.material.diffuse_ref = 0.5; mapvals.material.specular_ref = 0.5; mapvals.material.highlight = 27.0; + + for (i=0;i<6;i++) + mapvals.boxmap_id[i] = -1; } -MAIN() +void check_drawables(GDrawable *drawable) +{ + gint i; + + /* Check that boxmap images are valid */ + /* ================================== */ + + for (i=0;iid; + else if (mapvals.boxmap_id[i]!=-1 && gimp_drawable_image_id(mapvals.boxmap_id[i])==-1) + mapvals.boxmap_id[i] = drawable->id; + else if (gimp_drawable_gray(mapvals.boxmap_id[i])) + mapvals.boxmap_id[i] = drawable->id; + } +} + +MAIN(); static void query(void) { static GParamDef args[] = { - { PARAM_INT32, "run_mode", "Interactive (0), non-interactive (1)" }, - { PARAM_IMAGE, "image", "Input image" }, - { PARAM_DRAWABLE, "drawable", "Input drawable" }, - { PARAM_INT32, "maptype", "Type of mapping (0=plane,1=sphere)" }, - { PARAM_FLOAT, "viewpoint_x", "Position of viewpoint (x,y,z)" }, - { PARAM_FLOAT, "viewpoint_y", "Position of viewpoint (x,y,z)" }, - { PARAM_FLOAT, "viewpoint_z", "Position of viewpoint (x,y,z)" }, - { PARAM_FLOAT, "position_x", "Object position (x,y,z)" }, - { PARAM_FLOAT, "position_y", "Object position (x,y,z)" }, - { PARAM_FLOAT, "position_z", "Object position (x,y,z)" }, - { PARAM_FLOAT, "firstaxis_x", "First axis of object [x,y,z]" }, - { PARAM_FLOAT, "firstaxis_y", "First axis of object [x,y,z]" }, - { PARAM_FLOAT, "firstaxis_z", "First axis of object [x,y,z]" }, - { PARAM_FLOAT, "secondaxis_x", "Second axis of object [x,y,z]" }, - { PARAM_FLOAT, "secondaxis_y", "Second axis of object [x,y,z]" }, - { PARAM_FLOAT, "secondaxis_z", "Second axis of object [x,y,z]" }, - { PARAM_FLOAT, "rotationangle_x", "Axis rotation (xy,xz,yz) in degrees" }, - { PARAM_FLOAT, "rotationangle_y", "Axis rotation (xy,xz,yz) in degrees" }, - { PARAM_FLOAT, "rotationangle_z", "Axis rotation (xy,xz,yz) in degrees" }, - { PARAM_INT32, "lighttype", "Type of lightsource (0=point,1=directional,3=none)" }, - { PARAM_COLOR, "lightcolor", "Lightsource color (r,g,b)" }, - { PARAM_FLOAT, "lightposition_x", "Lightsource position (x,y,z)" }, - { PARAM_FLOAT, "lightposition_y", "Lightsource position (x,y,z)" }, - { PARAM_FLOAT, "lightposition_z", "Lightsource position (x,y,z)" }, - { PARAM_FLOAT, "lightdirection_x", "Lightsource direction [x,y,z]" }, - { PARAM_FLOAT, "lightdirection_y", "Lightsource direction [x,y,z]" }, - { PARAM_FLOAT, "lightdirection_z", "Lightsource direction [x,y,z]" }, - { PARAM_FLOAT, "ambient_intensity", "Material ambient intensity (0..1)" }, - { PARAM_FLOAT, "diffuse_intensity", "Material diffuse intensity (0..1)" }, - { PARAM_FLOAT, "diffuse_reflectivity", "Material diffuse reflectivity (0..1)" }, - { PARAM_FLOAT, "specular_reflectivity", "Material specular reflectivity (0..1)" }, - { PARAM_FLOAT, "highlight", "Material highlight (0..->), note: it's expotential" }, - { PARAM_INT32, "antialiasing", "Apply antialiasing (TRUE/FALSE)" }, - { PARAM_INT32, "tiled", "Tile source image (TRUE/FALSE)" }, - { PARAM_INT32, "newimage", "Create a new image (TRUE/FALSE)" }, - { PARAM_INT32, "transparentbackground", "Make background transparent (TRUE/FALSE)" }, - { PARAM_FLOAT, "radius", "Sphere radius (only used when maptype=1)" } + { PARAM_INT32, "run_mode", "Interactive (0), non-interactive (1)" }, + { PARAM_IMAGE, "image", "Input image" }, + { PARAM_DRAWABLE, "drawable", "Input drawable" }, + { PARAM_INT32, "maptype", "Type of mapping (0=plane,1=sphere,2=box)" }, + { PARAM_FLOAT, "viewpoint_x", "Position of viewpoint (x,y,z)" }, + { PARAM_FLOAT, "viewpoint_y", "Position of viewpoint (x,y,z)" }, + { PARAM_FLOAT, "viewpoint_z", "Position of viewpoint (x,y,z)" }, + { PARAM_FLOAT, "position_x", "Object position (x,y,z)" }, + { PARAM_FLOAT, "position_y", "Object position (x,y,z)" }, + { PARAM_FLOAT, "position_z", "Object position (x,y,z)" }, + { PARAM_FLOAT, "firstaxis_x", "First axis of object [x,y,z]" }, + { PARAM_FLOAT, "firstaxis_y", "First axis of object [x,y,z]" }, + { PARAM_FLOAT, "firstaxis_z", "First axis of object [x,y,z]" }, + { PARAM_FLOAT, "secondaxis_x", "Second axis of object [x,y,z]" }, + { PARAM_FLOAT, "secondaxis_y", "Second axis of object [x,y,z]" }, + { PARAM_FLOAT, "secondaxis_z", "Second axis of object [x,y,z]" }, + { PARAM_FLOAT, "rotationangle_x", "Rotation about X axis in degrees" }, + { PARAM_FLOAT, "rotationangle_y", "Rotation about Y axis in degrees" }, + { PARAM_FLOAT, "rotationangle_z", "Rotation about Z axis in degrees" }, + { PARAM_INT32, "lighttype", "Type of lightsource (0=point,1=directional,3=none)" }, + { PARAM_COLOR, "lightcolor", "Lightsource color (r,g,b)" }, + { PARAM_FLOAT, "lightposition_x", "Lightsource position (x,y,z)" }, + { PARAM_FLOAT, "lightposition_y", "Lightsource position (x,y,z)" }, + { PARAM_FLOAT, "lightposition_z", "Lightsource position (x,y,z)" }, + { PARAM_FLOAT, "lightdirection_x", "Lightsource direction [x,y,z]" }, + { PARAM_FLOAT, "lightdirection_y", "Lightsource direction [x,y,z]" }, + { PARAM_FLOAT, "lightdirection_z", "Lightsource direction [x,y,z]" }, + { PARAM_FLOAT, "ambient_intensity", "Material ambient intensity (0..1)" }, + { PARAM_FLOAT, "diffuse_intensity", "Material diffuse intensity (0..1)" }, + { PARAM_FLOAT, "diffuse_reflectivity", "Material diffuse reflectivity (0..1)" }, + { PARAM_FLOAT, "specular_reflectivity", "Material specular reflectivity (0..1)" }, + { PARAM_FLOAT, "highlight", "Material highlight (0..->), note: it's expotential" }, + { PARAM_INT32, "antialiasing", "Apply antialiasing (TRUE/FALSE)" }, + { PARAM_INT32, "tiled", "Tile source image (TRUE/FALSE)" }, + { PARAM_INT32, "newimage", "Create a new image (TRUE/FALSE)" }, + { PARAM_INT32, "transparentbackground", "Make background transparent (TRUE/FALSE)" }, + { PARAM_FLOAT, "radius", "Sphere radius (only used when maptype=1)" }, + { PARAM_FLOAT, "x_scale", "Box x size (0..->)" }, + { PARAM_FLOAT, "y_scale", "Box y size (0..->)" }, + { PARAM_FLOAT, "z_scale", "Box z size (0..->)"}, + { PARAM_DRAWABLE, "front_drawable", "Box front face (set these to -1 if not used)" }, + { PARAM_DRAWABLE, "back_drawable", "Box back face" }, + { PARAM_DRAWABLE, "top_drawable", "Box top face" }, + { PARAM_DRAWABLE, "bottom_drawable", "Box bottom face" }, + { PARAM_DRAWABLE, "left_drawable", "Box left face" }, + { PARAM_DRAWABLE, "right_drawable", "Box right face" } + }; static GParamDef *return_vals = NULL; @@ -129,12 +163,12 @@ static void query(void) static gint nreturn_vals = 0; gimp_install_procedure ("plug_in_map_object", - "Maps a picture to a object (plane, sphere)", + "Maps a picture to a object (plane, sphere or box)", "No help yet", "Tom Bech & Federico Mena Quintero", "Tom Bech & Federico Mena Quintero", - "Version 1.00, March 15 1998", - "/Filters/Map/Map Object", + "Version 1.10, July 17 1998", + "/Filters/Distorts/Map Object", "RGB*", PROC_PLUG_IN, nargs, nreturn_vals, @@ -151,6 +185,7 @@ static void run(gchar *name, GDrawable *drawable; GRunModeType run_mode; GStatusType status = STATUS_SUCCESS; + gint i; run_mode = param[0].data.d_int32; @@ -178,16 +213,18 @@ static void run(gchar *name, /* ====================== */ gimp_get_data ("plug_in_map_object", &mapvals); + check_drawables(drawable); mapobject_interactive(drawable); gimp_set_data("plug_in_map_object", &mapvals, sizeof(MapObjectValues)); break; case RUN_WITH_LAST_VALS: gimp_get_data ("plug_in_map_object", &mapvals); + check_drawables(drawable); image_setup(drawable,FALSE); compute_image(); break; case RUN_NONINTERACTIVE: - if (nparams != 37) + if (nparams != 46) status = STATUS_CALLING_ERROR; else if (status == STATUS_SUCCESS) { @@ -227,20 +264,26 @@ static void run(gchar *name, mapvals.create_new_image = (gint)param[34].data.d_int32; mapvals.transparent_background = (gint)param[35].data.d_int32; mapvals.radius = param[36].data.d_float; + mapvals.scale.x = param[37].data.d_float; + mapvals.scale.y = param[38].data.d_float; + mapvals.scale.z = param[39].data.d_float; + + for (i=0;i<6;i++) + mapvals.boxmap_id[i] = gimp_drawable_get(param[40+i].data.d_drawable)->id; + check_drawables(drawable); image_setup(drawable, FALSE); compute_image(); } break; } - if (run_mode != RUN_NONINTERACTIVE) - gimp_displays_flush(); - - values[0].data.d_status = status; + + if (run_mode != RUN_NONINTERACTIVE) + gimp_displays_flush(); + gimp_drawable_detach(drawable); - } GPlugInInfo PLUG_IN_INFO = @@ -263,7 +306,6 @@ void mapobject_interactive(GDrawable *drawable) gdk_set_use_xshm(gimp_use_xshm()); gtk_init (&argc, &argv); - gtk_rc_parse (gimp_gtkrc ()); /* Set up ArcBall stuff */ /* ==================== */ diff --git a/plug-ins/MapObject/mapobject_main.h b/plug-ins/MapObject/mapobject_main.h index f0af04bb14..da7a9b7b47 100644 --- a/plug-ins/MapObject/mapobject_main.h +++ b/plug-ins/MapObject/mapobject_main.h @@ -31,7 +31,8 @@ typedef enum { typedef enum { MAP_PLANE, - MAP_SPHERE + MAP_SPHERE, + MAP_BOX } MapType; /* Typedefs */ @@ -57,7 +58,7 @@ typedef struct } LightSettings; typedef struct { - GckVector3 viewpoint,firstaxis,secondaxis,normal,position; + GckVector3 viewpoint,firstaxis,secondaxis,normal,position,scale; LightSettings lightsource; MaterialSettings material; @@ -79,6 +80,8 @@ typedef struct { gdouble pixeltreshold; gdouble radius; + gint32 boxmap_id[6]; + } MapObjectValues; /* Externally visible variables */ diff --git a/plug-ins/MapObject/mapobject_preview.c b/plug-ins/MapObject/mapobject_preview.c index 290ca9f039..6bad536d07 100644 --- a/plug-ins/MapObject/mapobject_preview.c +++ b/plug-ins/MapObject/mapobject_preview.c @@ -16,9 +16,16 @@ BackBuffer backbuf={0,0,0,0,NULL}; void update_light (gint xpos,gint ypos); void draw_light_marker (gint xpos,gint ypos); void clear_light_marker (void); -void draw_wireframe_plane(gint startx,gint starty,gint pw,gint ph); -void draw_wireframe_sphere(gint startx,gint starty,gint pw,gint ph); -void clear_wireframe(void); + +gint draw_line (gint n, gint startx,gint starty,gint pw,gint ph, + gdouble cx1, gdouble cy1, gdouble cx2, gdouble cy2, + GckVector3 a,GckVector3 b); + +void draw_wireframe_plane (gint startx,gint starty,gint pw,gint ph); +void draw_wireframe_sphere (gint startx,gint starty,gint pw,gint ph); +void draw_wireframe_box (gint startx,gint starty,gint pw,gint ph); + +void clear_wireframe (void); /**************************************************************/ /* Computes a preview of the rectangle starting at (x,y) with */ @@ -309,6 +316,9 @@ void draw_wireframe(gint startx,gint starty,gint pw,gint ph) case MAP_SPHERE: draw_wireframe_sphere(startx,starty,pw,ph); break; + case MAP_BOX: + draw_wireframe_box(startx,starty,pw,ph); + break; } } @@ -519,6 +529,96 @@ void draw_wireframe_sphere(gint startx,gint starty,gint pw,gint ph) linetab[n].x1=-1; } +gint draw_line(gint n, gint startx,gint starty,gint pw,gint ph, + gdouble cx1, gdouble cy1, gdouble cx2, gdouble cy2, + GckVector3 a,GckVector3 b) +{ + gdouble x1,y1,x2,y2; + gint i = n; + + gck_3d_to_2d(startx,starty,pw,ph,&x1,&y1,&mapvals.viewpoint,&a); + gck_3d_to_2d(startx,starty,pw,ph,&x2,&y2,&mapvals.viewpoint,&b); + + if (gck_clip_line(&x1,&y1,&x2,&y2,cx1,cy1,cx2,cy2)==TRUE) + { + linetab[i].x1=(gint)(x1+0.5); + linetab[i].y1=(gint)(y1+0.5); + linetab[i].x2=(gint)(x2+0.5); + linetab[i].y2=(gint)(y2+0.5); + linetab[i].linewidth=3; + linetab[i].linestyle=GDK_LINE_SOLID; + gdk_gc_set_line_attributes(gc,linetab[i].linewidth,linetab[i].linestyle, + GDK_CAP_NOT_LAST,GDK_JOIN_MITER); + gdk_draw_line(previewarea->window,gc,linetab[i].x1,linetab[i].y1, + linetab[i].x2,linetab[i].y2); + i++; + } + + return(i); +} + +void draw_wireframe_box(gint startx,gint starty,gint pw,gint ph) +{ + GckVector3 p[8], tmp, scale; + gint n=0,i; + gdouble cx1,cy1,cx2,cy2; + + /* Compute wireframe points */ + /* ======================== */ + + init_compute(); + + scale = mapvals.scale; + gck_vector3_mul(&scale,0.5); + + gck_vector3_set(&p[0], -scale.x, -scale.y, scale.z); + gck_vector3_set(&p[1], scale.x, -scale.y, scale.z); + gck_vector3_set(&p[2], scale.x, scale.y, scale.z); + gck_vector3_set(&p[3], -scale.x, scale.y, scale.z); + + gck_vector3_set(&p[4], -scale.x, -scale.y, -scale.z); + gck_vector3_set(&p[5], scale.x, -scale.y, -scale.z); + gck_vector3_set(&p[6], scale.x, scale.y, -scale.z); + gck_vector3_set(&p[7], -scale.x, scale.y, -scale.z); + + /* Rotate and translate points */ + /* =========================== */ + + for (i=0;i<8;i++) + { + vecmulmat(&tmp,&p[i],rotmat); + gck_vector3_add(&p[i],&tmp,&mapvals.position); + } + + /* Draw the box */ + /* ============ */ + + cx1=(gdouble)startx; + cy1=(gdouble)starty; + cx2=cx1+(gdouble)pw; + cy2=cy1+(gdouble)ph; + + n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[0],p[1]); + n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[1],p[2]); + n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[2],p[3]); + n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[3],p[0]); + + n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[4],p[5]); + n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[5],p[6]); + n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[6],p[7]); + n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[7],p[4]); + + n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[0],p[4]); + n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[1],p[5]); + n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[2],p[6]); + n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[3],p[7]); + + /* Mark end of lines */ + /* ================= */ + + linetab[n].x1=-1; +} + void clear_wireframe(void) { gint n=0; diff --git a/plug-ins/MapObject/mapobject_shade.c b/plug-ins/MapObject/mapobject_shade.c index 7d60d98654..7f1cc08784 100644 --- a/plug-ins/MapObject/mapobject_shade.c +++ b/plug-ins/MapObject/mapobject_shade.c @@ -7,6 +7,14 @@ gdouble bx1,by1,bx2,by2; get_ray_color_func get_ray_color; +typedef struct { + gdouble u,v; + gdouble t; + GckVector3 s; + GckVector3 n; + gint face; +} FaceIntersectInfo; + /*****************/ /* Phong shading */ /*****************/ @@ -337,10 +345,10 @@ GckRGB get_ray_color_sphere(GckVector3 *pos) /* Compute a mix of the first and second colors */ /* ============================================ */ - - color.r = color.r*color2.r; - color.g = color.g*color2.g; - color.b = color.b*color2.b; + + color.r = color.r*color.a+(1.0-color.a)*color2.r; + color.g = color.g*color.a+(1.0-color.a)*color2.g; + color.b = color.b*color.a+(1.0-color.a)*color2.b; color.a = color.a+color2.a; gck_rgba_clamp(&color); @@ -411,3 +419,492 @@ void compute_bounding_box(void) bx2=p2.x; by2=p2.y; } + +/* These two were taken from the Mesa source. Mesa is written */ +/* and is (C) by Brian Paul. vecmulmat() performs a post-mul by */ +/* a 4x4 matrix to a 1x4(3) vector. rotmat() creates a matrix */ +/* that by post-mul will rotate a 1x4(3) vector the given angle */ +/* about the given axis. */ +/* ============================================================ */ + +void vecmulmat(GckVector3 *u,GckVector3 *v,gfloat m[16]) +{ + gfloat v0=v->x, v1=v->y, v2=v->z; +#define M(row,col) m[col*4+row] + u->x = v0 * M(0,0) + v1 * M(1,0) + v2 * M(2,0) + M(3,0); + u->y = v0 * M(0,1) + v1 * M(1,1) + v2 * M(2,1) + M(3,1); + u->z = v0 * M(0,2) + v1 * M(1,2) + v2 * M(2,2) + M(3,2); +#undef M +} + +void rotatemat(gfloat angle,GckVector3 *v,gfloat m[16]) +{ + /* This function contributed by Erich Boleyn (erich@uruk.org) */ + gfloat mag, s, c; + gfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c; + gfloat IdentityMat[16]; + gint cnt; + + s = sin( angle * (M_PI / 180.0) ); + c = cos( angle * (M_PI / 180.0) ); + + mag = sqrt( v->x*v->x + v->y*v->y + v->z*v->z ); + + if (mag == 0.0) { + /* generate an identity matrix and return */ + + for (cnt=0;cnt<16;cnt++) + IdentityMat[cnt]=0.0; + + IdentityMat[0] = 1.0; + IdentityMat[5] = 1.0; + IdentityMat[10] = 1.0; + IdentityMat[15] = 1.0; + + memcpy(m, IdentityMat, sizeof(gfloat)*16); + return; + } + + v->x /= mag; + v->y /= mag; + v->z /= mag; + +#define M(row,col) m[col*4+row] + + xx = v->x * v->x; + yy = v->y * v->y; + zz = v->z * v->z; + xy = v->x * v->y; + yz = v->y * v->z; + zx = v->z * v->x; + xs = v->x * s; + ys = v->y * s; + zs = v->z * s; + one_c = 1.0F - c; + + M(0,0) = (one_c * xx) + c; + M(0,1) = (one_c * xy) - zs; + M(0,2) = (one_c * zx) + ys; + M(0,3) = 0.0F; + + M(1,0) = (one_c * xy) + zs; + M(1,1) = (one_c * yy) + c; + M(1,2) = (one_c * yz) - xs; + M(1,3) = 0.0F; + + M(2,0) = (one_c * zx) - ys; + M(2,1) = (one_c * yz) + xs; + M(2,2) = (one_c * zz) + c; + M(2,3) = 0.0F; + + M(3,0) = 0.0F; + M(3,1) = 0.0F; + M(3,2) = 0.0F; + M(3,3) = 1.0F; + +#undef M +} + +/* Transpose the matrix m. If m is orthogonal (like a rotation matrix), */ +/* this is equal to the inverse of the matrix. */ +/* ==================================================================== */ + +void transpose_mat(gfloat m[16]) +{ + gint i,j; + gfloat t; + + for (i=0;i<4;i++) + { + for (j=0;jt = (w-viewp.z)/dir.z; + face_info->s.x = viewp.x + face_info->t*dir.x; + face_info->s.y = viewp.y + face_info->t*dir.y; + face_info->s.z = 0.0; + + if (face_info->s.x>=-u2 && face_info->s.x<=u2 && + face_info->s.y>=-v2 && face_info->s.y<=v2) + { + face_info->u = (face_info->s.x + u2)/u; + face_info->v = (face_info->s.y + v2)/v; + result = TRUE; + } + } + + return(result); +} + +gboolean intersect_box(GckVector3 scale, GckVector3 viewp, GckVector3 dir, + FaceIntersectInfo *face_intersect) +{ + GckVector3 v,d,tmp,axis[3]; + FaceIntersectInfo face_tmp; + gboolean result = FALSE; + gfloat m[16]; + gint i = 0; + + gck_vector3_set(&axis[0], 1.0,0.0,0.0); + gck_vector3_set(&axis[1], 0.0,1.0,0.0); + gck_vector3_set(&axis[2], 0.0,0.0,1.0); + + /* Front side */ + /* ========== */ + + if (intersect_rect(scale.x,scale.y,scale.z/2.0,viewp,dir,&face_intersect[i])==TRUE) + { + face_intersect[i].face = 0; + gck_vector3_set(&face_intersect[i++].n, 0.0,0.0,1.0); + result = TRUE; + } + + /* Back side */ + /* ========= */ + + if (intersect_rect(scale.x,scale.y,-scale.z/2.0,viewp,dir,&face_intersect[i])==TRUE) + { + face_intersect[i].face = 1; + gck_vector3_set(&face_intersect[i++].n, 0.0,0.0,-1.0); + face_intersect[i].u = 1.0 - face_intersect[i].u; + face_intersect[i].v = 1.0 - face_intersect[i].v; + result = TRUE; + } + + /* Check if we've found the two possible intersection points */ + /* ========================================================= */ + + if (i<2) + { + /* Top: Rotate viewpoint and direction into rectangle's local coordinate system */ + /* ============================================================================ */ + + rotatemat(90, &axis[0], m); + vecmulmat(&v,&viewp,m); + vecmulmat(&d,&dir,m); + + if (intersect_rect(scale.x,scale.z,scale.y/2.0,v,d,&face_intersect[i])==TRUE) + { + face_intersect[i].face = 2; + + transpose_mat(m); + vecmulmat(&tmp, &face_intersect[i].s, m); + face_intersect[i].s = tmp; + + gck_vector3_set(&face_intersect[i++].n, 0.0,-1.0,0.0); + result = TRUE; + } + } + + /* Check if we've found the two possible intersection points */ + /* ========================================================= */ + + if (i<2) + { + /* Bottom: Rotate viewpoint and direction into rectangle's local coordinate system */ + /* =============================================================================== */ + + rotatemat(90, &axis[0], m); + vecmulmat(&v,&viewp,m); + vecmulmat(&d,&dir,m); + + if (intersect_rect(scale.x,scale.z,-scale.y/2.0,v,d,&face_intersect[i])==TRUE) + { + face_intersect[i].face = 3; + + transpose_mat(m); + + vecmulmat(&tmp, &face_intersect[i].s, m); + face_intersect[i].s = tmp; + + face_intersect[i].v = 1.0 - face_intersect[i].v; + + gck_vector3_set(&face_intersect[i++].n, 0.0,1.0,0.0); + + result = TRUE; + } + } + + /* Check if we've found the two possible intersection points */ + /* ========================================================= */ + + if (i<2) + { + /* Left side: Rotate viewpoint and direction into rectangle's local coordinate system */ + /* ================================================================================== */ + + rotatemat(90, &axis[1], m); + vecmulmat(&v,&viewp,m); + vecmulmat(&d,&dir,m); + + if (intersect_rect(scale.z,scale.y,scale.x/2.0,v,d,&face_intersect[i])==TRUE) + { + face_intersect[i].face = 4; + + transpose_mat(m); + vecmulmat(&tmp, &face_intersect[i].s, m); + face_intersect[i].s = tmp; + + gck_vector3_set(&face_intersect[i++].n, 1.0,0.0,0.0); + result = TRUE; + } + } + + /* Check if we've found the two possible intersection points */ + /* ========================================================= */ + + if (i<2) + { + /* Right side: Rotate viewpoint and direction into rectangle's local coordinate system */ + /* =================================================================================== */ + + rotatemat(90, &axis[1], m); + vecmulmat(&v,&viewp,m); + vecmulmat(&d,&dir,m); + + if (intersect_rect(scale.z,scale.y,-scale.x/2.0,v,d,&face_intersect[i])==TRUE) + { + face_intersect[i].face = 5; + + transpose_mat(m); + vecmulmat(&tmp, &face_intersect[i].s, m); + + face_intersect[i].u = 1.0 - face_intersect[i].u; + + gck_vector3_set(&face_intersect[i++].n, -1.0,0.0,0.0); + result = TRUE; + } + } + + /* Sort intersection points */ + /* ======================== */ + + if (face_intersect[0].t>face_intersect[1].t) + { + face_tmp = face_intersect[0]; + face_intersect[0] = face_intersect[1]; + face_intersect[1] = face_tmp; + } + + return(result); +} + +GckRGB get_ray_color_box(GckVector3 *pos) +{ + GckVector3 lvp,ldir,vp,p,dir,ns,nn; + GckRGB color, color2; + gfloat m[16]; + gint i; + FaceIntersectInfo face_intersect[2]; + + color=background; + vp = mapvals.viewpoint; + p = *pos; + + /* Translate viewpoint so that the box has its origin */ + /* at its lower left corner. */ + /* ================================================== */ + + vp.x = vp.x - mapvals.position.x; + vp.y = vp.y - mapvals.position.y; + vp.z = vp.z - mapvals.position.z; + + p.x = p.x - mapvals.position.x; + p.y = p.y - mapvals.position.y; + p.z = p.z - mapvals.position.z; + + /* Compute direction */ + /* ================= */ + + gck_vector3_sub(&dir,&p,&vp); + gck_vector3_normalize(&dir); + + /* Compute inverse of rotation matrix and apply it to */ + /* the viewpoint and direction. This transforms the */ + /* observer into the local coordinate system of the box */ + /* ==================================================== */ + + memcpy(m,rotmat,sizeof(gfloat)*16); + + transpose_mat(m); + + vecmulmat(&lvp,&vp,m); + vecmulmat(&ldir,&dir,m); + + /* Ok. Now the observer is in the space where the box is located */ + /* with its lower left corner at the origin and its axis aligned */ + /* to the cartesian basis. Check if the transformed ray hits it. */ + /* ============================================================= */ + + face_intersect[0].t = 1000000.0; + face_intersect[1].t = 1000000.0; + + if (intersect_box(mapvals.scale,lvp,ldir,face_intersect)==TRUE) + { + /* We've hit the box. Transform the hit points and */ + /* normals back into the world coordinate system */ + /* =============================================== */ + + for (i=0;i<2;i++) + { + vecmulmat(&ns,&face_intersect[i].s,rotmat); + vecmulmat(&nn,&face_intersect[i].n,rotmat); + + ns.x = ns.x + mapvals.position.x; + ns.y = ns.y + mapvals.position.y; + ns.z = ns.z + mapvals.position.z; + + face_intersect[i].s = ns; + face_intersect[i].n = nn; + } + + color = get_box_image_color(face_intersect[0].face, + face_intersect[0].u,face_intersect[0].v); + + /* Check for total transparency... */ + /* =============================== */ + + if (color.a<1.0) + { + /* Hey, we can see through here! */ + /* Lets see what's on the other side.. */ + /* =================================== */ + + color=phong_shade( + &face_intersect[0].s, + &mapvals.viewpoint, + &face_intersect[0].n, + &mapvals.lightsource.position, + &color, + &mapvals.lightsource.color, + mapvals.lightsource.type); + + gck_rgba_clamp(&color); + + color2 = get_box_image_color(face_intersect[1].face, + face_intersect[1].u,face_intersect[1].v); + + /* Make the normal point inwards */ + /* ============================= */ + + gck_vector3_mul(&face_intersect[1].n,-1.0); + + color2=phong_shade( + &face_intersect[1].s, + &mapvals.viewpoint, + &face_intersect[1].n, + &mapvals.lightsource.position, + &color2, + &mapvals.lightsource.color, + mapvals.lightsource.type); + + gck_rgba_clamp(&color2); + + if (mapvals.transparent_background==FALSE && color2.a<1.0) + { + color2.r = (color2.r*color2.a)+(background.r*(1.0-color2.a)); + color2.g = (color2.g*color2.a)+(background.g*(1.0-color2.a)); + color2.b = (color2.b*color2.a)+(background.b*(1.0-color2.a)); + color2.a = 1.0; + } + + /* Compute a mix of the first and second colors */ + /* ============================================ */ + + color.r = color.r*color.a+(1.0-color.a)*color2.r; + color.g = color.g*color.a+(1.0-color.a)*color2.g; + color.b = color.b*color.a+(1.0-color.a)*color2.b; + color.a = color.a+color2.a; + + gck_rgba_clamp(&color); + } + else if (color.a!=0.0 && mapvals.lightsource.type!=NO_LIGHT) + { + color=phong_shade( + &face_intersect[0].s, + &mapvals.viewpoint, + &face_intersect[0].n, + &mapvals.lightsource.position, + &color, + &mapvals.lightsource.color, + mapvals.lightsource.type); + + gck_rgba_clamp(&color); + } + } + else + { + if (mapvals.transparent_background==TRUE) + color.a = 0.0; + } + + return(color); +} + diff --git a/plug-ins/MapObject/mapobject_shade.h b/plug-ins/MapObject/mapobject_shade.h index 5f45bc7d8d..fad2b909a2 100644 --- a/plug-ins/MapObject/mapobject_shade.h +++ b/plug-ins/MapObject/mapobject_shade.h @@ -13,9 +13,15 @@ typedef GckRGB (*get_ray_color_func)(GckVector3 *pos); extern get_ray_color_func get_ray_color; -extern GckRGB get_ray_color_plane (GckVector3 *pos); -extern GckRGB get_ray_color_sphere (GckVector3 *pos); +extern GckRGB get_ray_color_plane (GckVector3 *pos); +extern GckRGB get_ray_color_sphere (GckVector3 *pos); +extern GckRGB get_ray_color_box (GckVector3 *pos); extern void compute_bounding_box (void); +extern void vecmulmat (GckVector3 *u,GckVector3 *v,gfloat m[16]); +extern void rotatemat (gfloat angle,GckVector3 *v,gfloat m[16]); +extern void transpose_mat (gfloat m[16]); +extern void matmul (gfloat a[16],gfloat b[16],gfloat c[16]); +extern void ident_mat (gfloat m[16]); #endif diff --git a/plug-ins/MapObject/mapobject_ui.c b/plug-ins/MapObject/mapobject_ui.c index 4afba5610b..e392cac923 100644 --- a/plug-ins/MapObject/mapobject_ui.c +++ b/plug-ins/MapObject/mapobject_ui.c @@ -14,7 +14,8 @@ GtkTooltips *tooltips = NULL; GdkGC *gc = NULL; GtkWidget *previewarea,*pointlightwid,*dirlightwid; -GtkWidget *xentry,*yentry,*zentry; +GtkWidget *xentry,*yentry,*zentry, *scale_table; +GtkWidget *images_page = NULL; GckRGB old_light_color; @@ -24,6 +25,7 @@ guint left_button_pressed = FALSE, light_hit = FALSE; guint32 blackpixel,whitepixel; GckScaleValues angle_scale_vals = { 180, 0.0, -180.0, 180.0, 0.1, 1.0, 1.0, GTK_UPDATE_CONTINUOUS,TRUE }; +GckScaleValues scale_scale_vals = { 180, 0.5, 0.01, 5.0, 0.1, 0.1, 0.1, GTK_UPDATE_CONTINUOUS,TRUE }; GckScaleValues sample_scale_vals = { 128, 3.0, 1.0, 6.0, 1.0, 1.0, 1.0, GTK_UPDATE_CONTINUOUS,TRUE }; gchar *light_labels[] = @@ -38,6 +40,7 @@ gchar *map_labels[] = { "Plane", "Sphere", + "Box", NULL }; @@ -76,13 +79,15 @@ void exit_callback (GtkWidget *widget, gpointer client_data); void color_ok_callback (GtkWidget *widget, gpointer client_data); void color_cancel_callback (GtkWidget *widget, gpointer client_data); void light_color_callback (GtkWidget *widget, gpointer client_data); -gint color_delete_callback (GtkWidget *widget, GdkEvent *event, gpointer client_data); -void color_changed_callback (GtkColorSelection *colorsel, gpointer client_data); + +gint box_constrain (gint32 image_id, gint32 drawable_id, gpointer data); +void box_drawable_callback (gint32 id, gpointer data); GtkWidget *create_options_page (void); GtkWidget *create_light_page (void); GtkWidget *create_material_page (void); GtkWidget *create_orientation_page (void); +GtkWidget *create_images_page (void); /******************/ /* Implementation */ @@ -139,6 +144,24 @@ void angle_update(GtkWidget *widget, GtkScale *scale) draw_preview_wireframe(); } +/***************************************************/ +/* Update scale sliders (redraw grid if necessary) */ +/***************************************************/ + +void boxscale_update(GtkWidget *widget, GtkScale *scale) +{ + gdouble *valueptr; + GtkAdjustment *adjustment; + + valueptr=(gdouble *)gtk_object_get_data(GTK_OBJECT(widget),"ValuePtr"); + adjustment=gtk_range_get_adjustment(GTK_RANGE(scale)); + + *valueptr=(gdouble)adjustment->value; + + if (mapvals.showgrid==TRUE) + draw_preview_wireframe(); +} + void update_light_pos_entries(void) { gchar entrytext[64]; @@ -304,6 +327,8 @@ void lightmenu_callback(GtkWidget *widget, gpointer client_data) void mapmenu_callback(GtkWidget *widget, gpointer client_data) { + GtkWidget *label; + mapvals.maptype=(MapType)gtk_object_get_data(GTK_OBJECT(widget),"_GckOptionMenuItemID"); draw_preview_image(TRUE); @@ -320,6 +345,31 @@ void mapmenu_callback(GtkWidget *widget, gpointer client_data) clear_wireframe(); linetab[0].x1=-1; } + + if (mapvals.maptype==MAP_BOX) + { + gtk_widget_show(scale_table); + + if (images_page==NULL) + { + images_page = create_images_page(); + label=gtk_label_new("Face images"); + gtk_widget_show(label); + + gtk_notebook_append_page(options_note_book,images_page,label); + } + } + else + { + if (images_page!=NULL) + { + gtk_notebook_remove_page(options_note_book, + g_list_length(options_note_book->children)-1); + images_page = NULL; + } + + gtk_widget_hide(scale_table); + } } /******************************************/ @@ -430,12 +480,6 @@ void color_changed_callback (GtkColorSelection *colorsel, gpointer client_data) mapvals.lightsource.color.b=color[2]; } -gint color_delete_callback(GtkWidget *widget, GdkEvent *event, gpointer client_data) -{ - color_select_diag=NULL; - return FALSE; -} - void color_cancel_callback(GtkWidget *widget, gpointer client_data) { gtk_widget_destroy(color_select_diag); @@ -452,8 +496,6 @@ void light_color_callback(GtkWidget *widget, gpointer client_data) gtk_window_position (GTK_WINDOW (color_select_diag), GTK_WIN_POS_MOUSE); gtk_widget_show(color_select_diag); csd=GTK_COLOR_SELECTION_DIALOG(color_select_diag); - gtk_signal_connect(GTK_OBJECT(csd),"delete_event", - (GtkSignalFunc)color_delete_callback,(gpointer)color_select_diag); gtk_signal_connect(GTK_OBJECT(csd->ok_button),"clicked", (GtkSignalFunc)color_ok_callback,(gpointer)color_select_diag); gtk_signal_connect(GTK_OBJECT(csd->cancel_button),"clicked", @@ -463,6 +505,23 @@ void light_color_callback(GtkWidget *widget, gpointer client_data) } } +gint box_constrain(gint32 image_id, gint32 drawable_id, gpointer data) +{ + if (drawable_id == -1) + return(TRUE); + + return (gimp_drawable_color(drawable_id) && !gimp_drawable_indexed(drawable_id)); +} + +void box_drawable_callback(gint32 id, gpointer data) +{ + gint i; + + i = (gint)gtk_object_get_data(GTK_OBJECT(data),"_mapwid_id"); + + mapvals.boxmap_id[i] = id; +} + /******************************/ /* Preview area event handler */ /******************************/ @@ -904,18 +963,21 @@ GtkWidget *create_orientation_page(void) gtk_widget_show(widget2); gtk_widget_show(widget3); - table = gtk_table_new(3,2,FALSE); - gtk_box_pack_start(GTK_BOX(vbox),table,TRUE,TRUE,5); + /* Rotation scales */ + /* =============== */ - label=gck_label_aligned_new("XY:",NULL,GCK_ALIGN_RIGHT,0.7); + table = gtk_table_new(3,2,FALSE); + gtk_box_pack_start(GTK_BOX(vbox),table,FALSE,FALSE,5); + + label=gck_label_aligned_new("XRot:",NULL,GCK_ALIGN_RIGHT,0.7); gtk_table_attach(GTK_TABLE(table),label,0,1,0,1, GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL, 0,0); gtk_widget_show(label); - label=gck_label_aligned_new("YZ:",NULL,GCK_ALIGN_RIGHT,0.7); + label=gck_label_aligned_new("YRot:",NULL,GCK_ALIGN_RIGHT,0.7); gtk_table_attach(GTK_TABLE(table),label,0,1,1,2, GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL, 0,0); gtk_widget_show(label); - label=gck_label_aligned_new("XZ:",NULL,GCK_ALIGN_RIGHT,0.7); + label=gck_label_aligned_new("ZRot:",NULL,GCK_ALIGN_RIGHT,0.7); gtk_table_attach(GTK_TABLE(table),label,0,1,2,3, GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL, 0,0); gtk_widget_show(label); @@ -933,18 +995,109 @@ GtkWidget *create_orientation_page(void) gtk_widget_show(widget1); gtk_widget_show(widget2); gtk_widget_show(widget3); - gtk_widget_show(table); - gtk_widget_show(vbox); - gtk_widget_show(frame); - - gtk_tooltips_set_tip(tooltips,widget1,"XY axis rotation angle",NULL); - gtk_tooltips_set_tip(tooltips,widget2,"YZ axis rotation angle",NULL); - gtk_tooltips_set_tip(tooltips,widget3,"XZ axis rotation angle",NULL); gtk_object_set_data(GTK_OBJECT(widget1),"ValuePtr",(gpointer)&mapvals.alpha); gtk_object_set_data(GTK_OBJECT(widget2),"ValuePtr",(gpointer)&mapvals.beta); gtk_object_set_data(GTK_OBJECT(widget3),"ValuePtr",(gpointer)&mapvals.gamma); + gtk_tooltips_set_tip(tooltips,widget1,"Rotation angle about X axis",NULL); + gtk_tooltips_set_tip(tooltips,widget2,"Rotation angle about Y axis",NULL); + gtk_tooltips_set_tip(tooltips,widget3,"Rotation angle about Z axis",NULL); + + /* Scale scales */ + /* ============ */ + + scale_table = gtk_table_new(3,2,FALSE); + gtk_box_pack_start(GTK_BOX(vbox),scale_table,FALSE,FALSE,5); + + label=gck_label_aligned_new("XScale:",NULL,GCK_ALIGN_RIGHT,0.7); + gtk_table_attach(GTK_TABLE(scale_table),label,0,1,0,1, GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL, 0,0); + gtk_widget_show(label); + + label=gck_label_aligned_new("YScale:",NULL,GCK_ALIGN_RIGHT,0.7); + gtk_table_attach(GTK_TABLE(scale_table),label,0,1,1,2, GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL, 0,0); + gtk_widget_show(label); + + label=gck_label_aligned_new("ZScale:",NULL,GCK_ALIGN_RIGHT,0.7); + gtk_table_attach(GTK_TABLE(scale_table),label,0,1,2,3, GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL, 0,0); + gtk_widget_show(label); + + scale_scale_vals.value = mapvals.scale.x; + widget1=gck_hscale_new(NULL,NULL,&scale_scale_vals,(GtkSignalFunc)boxscale_update); + scale_scale_vals.value = mapvals.scale.y; + widget2=gck_hscale_new(NULL,NULL,&scale_scale_vals,(GtkSignalFunc)boxscale_update); + scale_scale_vals.value = mapvals.scale.z; + widget3=gck_hscale_new(NULL,NULL,&scale_scale_vals,(GtkSignalFunc)boxscale_update); + + gtk_table_attach(GTK_TABLE(scale_table),widget1,1,2,0,1, GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL, 0,0); + gtk_table_attach(GTK_TABLE(scale_table),widget2,1,2,1,2, GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL, 0,0); + gtk_table_attach(GTK_TABLE(scale_table),widget3,1,2,2,3, GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL, 0,0); + + gtk_widget_show(widget1); + gtk_widget_show(widget2); + gtk_widget_show(widget3); + + gtk_object_set_data(GTK_OBJECT(widget1),"ValuePtr",(gpointer)&mapvals.scale.x); + gtk_object_set_data(GTK_OBJECT(widget2),"ValuePtr",(gpointer)&mapvals.scale.y); + gtk_object_set_data(GTK_OBJECT(widget3),"ValuePtr",(gpointer)&mapvals.scale.z); + + gtk_tooltips_set_tip(tooltips,widget1,"X scale (size)",NULL); + gtk_tooltips_set_tip(tooltips,widget2,"Y scale (size)",NULL); + gtk_tooltips_set_tip(tooltips,widget3,"Z scale (size)",NULL); + + if (mapvals.maptype==MAP_BOX) + gtk_widget_show(scale_table); + + gtk_widget_show(table); + gtk_widget_show(vbox); + gtk_widget_show(frame); + + gtk_widget_show(page); + + return page; +} + +GtkWidget *create_images_page(void) +{ + GtkWidget *page,*frame,*vbox,*label,*table; + GtkWidget *widget1,*widget2; + gint i; + gchar *labels[6] = {"Front:","Back:","Top:","Bottom:","Left:","Right:"}; + + page=gck_vbox_new(NULL,FALSE,FALSE,FALSE,0,0,0); + + frame=gck_frame_new("Map images to box faces",page,GTK_SHADOW_ETCHED_IN,TRUE,TRUE,0,5); + vbox=gck_vbox_new(frame,FALSE,FALSE,FALSE,0,0,5); + + table = gtk_table_new(6,2,FALSE); + gtk_table_set_row_spacings(GTK_TABLE(table), 5); + gtk_table_set_col_spacings(GTK_TABLE(table), 5); + gtk_box_pack_start(GTK_BOX(vbox),table,FALSE,FALSE,5); + + /* Option menues */ + /* ============= */ + + for (i=0;i<6;i++) + { + label=gck_label_aligned_new(labels[i],NULL,GCK_ALIGN_RIGHT,0.7); + gtk_table_attach(GTK_TABLE(table),label,0,1,i,i+1, GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL, 0,0); + gtk_widget_show(label); + + widget1=gtk_option_menu_new(); + gtk_table_attach(GTK_TABLE(table),widget1, 1,2, i,i+1, GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL, 0,0); + gtk_widget_show(widget1); + + gtk_object_set_data(GTK_OBJECT(widget1),"_mapwid_id",(gpointer)i); + + widget2 = gimp_drawable_menu_new (box_constrain, box_drawable_callback, + (gpointer)widget1, mapvals.boxmap_id[i]); + gtk_option_menu_set_menu(GTK_OPTION_MENU(widget1), widget2); + } + + gtk_widget_show(table); + gtk_widget_show(vbox); + gtk_widget_show(frame); + gtk_widget_show(page); return page; @@ -987,6 +1140,15 @@ void create_main_notebook(GtkWidget *container) gtk_notebook_append_page(options_note_book,page,label); + if (mapvals.maptype==MAP_BOX) + { + images_page = create_images_page(); + label=gtk_label_new("Face images"); + gtk_widget_show(label); + + gtk_notebook_append_page(options_note_book,images_page,label); + } + gtk_widget_show(GTK_WIDGET(options_note_book)); gck_auto_show(TRUE); @@ -1056,8 +1218,8 @@ void create_main_dialog(void) GDK_EXPOSURE_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK, (GtkSignalFunc)preview_events); - workbox1b=gck_vbox_new(workbox1,TRUE,TRUE,TRUE,0,0,0); - hbox=gck_hbox_new(workbox1b,FALSE,TRUE,TRUE,5,0,0); + workbox1b=gck_vbox_new(workbox1,TRUE,FALSE,FALSE,0,0,0); + hbox=gck_hbox_new(workbox1b,FALSE,FALSE,FALSE,5,0,0); wid=gck_pushbutton_new("Preview!",hbox,TRUE,TRUE,0,(GtkSignalFunc)preview_callback); gtk_tooltips_set_tip(tooltips,wid,"Recompute preview image",NULL); diff --git a/plug-ins/MapObject/mapobject_ui.h b/plug-ins/MapObject/mapobject_ui.h index 958b490f54..e101b68ce4 100644 --- a/plug-ins/MapObject/mapobject_ui.h +++ b/plug-ins/MapObject/mapobject_ui.h @@ -3,11 +3,11 @@ #include #include -#include #include #include #include #include +#include #include "arcball.h" #include "mapobject_main.h"