Updated MapObject plug-in.

--Sven
This commit is contained in:
Sven Neumann 1998-07-16 00:45:41 +00:00
parent a528c42a2e
commit b5b15171ca
15 changed files with 1045 additions and 107 deletions

View File

@ -1,3 +1,7 @@
Thu Jul 16 02:43:51 MEST 1998 Sven Neumann <sven@gimp.org>
updated MapObject plug-in
Wed Jul 15 04:55:30 PDT 1998 Jay Cox <jaycox@earthlink.net>
* app/gimpbrushgenerated.c

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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;ycount<height;ycount++)

View File

@ -12,8 +12,8 @@
#include "mapobject_main.h"
#include "mapobject_image.h"
extern gdouble imat[4][4];
extern gfloat rotmat[16];
extern void init_compute(void);
extern void compute_image(void);

View File

@ -10,6 +10,9 @@
GDrawable *input_drawable,*output_drawable;
GPixelRgn source_region,dest_region;
GDrawable *box_drawables[6];
GPixelRgn box_regions[6];
guchar *preview_rgb_data = NULL;
GdkImage *image = NULL;
@ -48,6 +51,30 @@ GckRGB peek(gint x,gint y)
return(color);
}
GckRGB peek_image(gint image, gint x,gint y)
{
static guchar data[4];
GckRGB color;
gimp_pixel_rgn_get_pixel(&box_regions[image],data,x,y);
color.r=(gdouble)(data[0])/255.0;
color.g=(gdouble)(data[1])/255.0;
color.b=(gdouble)(data[2])/255.0;
if (box_drawables[image]->bpp==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 */
/****************************************/

View File

@ -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

View File

@ -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;i<mapvals.boxmap_id[i];i++)
{
if (mapvals.boxmap_id[i]==-1)
mapvals.boxmap_id[i] = drawable->id;
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",
"<Image>/Filters/Map/Map Object",
"Version 1.10, July 17 1998",
"<Image>/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 */
/* ==================== */

View File

@ -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 */

View File

@ -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;

View File

@ -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;j<i;j++)
{
t = m[j*4+i];
m[j*4+i] = m[i*4+j];
m[i*4+j] = t;
}
}
}
/* Compute the matrix product c=a*b */
/* ================================ */
void matmul(gfloat a[16],gfloat b[16],gfloat c[16])
{
gint i,j,k;
gfloat value;
#define A(row,col) a[col*4+row]
#define B(row,col) b[col*4+row]
#define C(row,col) c[col*4+row]
for (i=0;i<4;i++)
{
for (j=0;j<4;j++)
{
value = 0.0;
for (k=0;k<4;k++)
value += A(i,k)*B(k,j);
C(i,j) = value;
}
}
#undef A
#undef B
#undef C
}
void ident_mat(gfloat m[16])
{
gint i,j;
#define M(row,col) m[col*4+row]
for (i=0;i<4;i++)
{
for (j=0;j<4;j++)
{
if (i==j)
M(i,j) = 1.0;
else
M(i,j) = 0.0;
}
}
#undef M
}
gboolean intersect_rect(gdouble u,gdouble v,gdouble w,
GckVector3 viewp,GckVector3 dir,
FaceIntersectInfo *face_info)
{
gboolean result = FALSE;
gdouble u2,v2;
if (dir.z!=0.0)
{
u2 = u / 2.0;
v2 = v / 2.0;
face_info->t = (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);
}

View File

@ -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

View File

@ -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);

View File

@ -3,11 +3,11 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <gck/gck.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include "arcball.h"
#include "mapobject_main.h"