Commit d13cd99d authored by Manish Singh's avatar Manish Singh
Browse files

MapObject update

-Yosh
parent b2f1e85c
Thu Jul 16 13:13:23 PDT 1998 Manish Singh <yosh@gimp.org>
* updated MapObject again
Thu Jul 16 04:38:19 PDT 1998 Jay Cox <jaycox@earthlink.net>
* brush_edit.[ch]: added a zoom indicator on the preview
......
Changes (post 0.31):
====================
Changes (post 0.3.1):
=====================
-> 0.31 Merged MapPlane and MapSphere. Added support for non-interactive
-> 0.3.1 Merged MapPlane and MapSphere. Added support for non-interactive
execution (for script-fu).
-> 0.32 Fixed a bug in the bilinear interpolation function. Added "tile" option.
-> 0.3.2 Fixed a bug in the bilinear interpolation function. Added "tile" option.
Added some icons to the material page to illustrate the effects of the
parameters. I'm not sure they help much.
-> 0.40 Some source/algorithm cleanups, fixed gtk+ object refcounting bugs. Some
-> 0.4.0 Some source/algorithm cleanups, fixed gtk+ object refcounting bugs. Some
changes to compile with gtk+ 0.99.4.
-> 1.00 First non-beta release. Replaced GckNotebook with GtkNotebook, fixed a few
-> 1.0.0 First non-beta release. Replaced GckNotebook with GtkNotebook, fixed a few
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
-> 1.1.0 Added box object and changed PDB interface accordingly; this will unfortunately
break old scripts. The transparency code should be a little saner now.
-> 1.2.0 Added cylinder object. Fixed a few things, thanks to Yosh <yosh@gimp.org> and
Pedro <pkaempf@master.echo.ch> for pointing them out to me.
MapObject 1.10 -- image filter plug-in for The GIMP program
MapObject 1.2.0 -- 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
Released 16th of July, 1998
You can reach the author(s) via E-mail:
tomb@gimp.org (Tom) or quartic@gimp.org (Federico).
......
......@@ -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 - cylinder?
* More objects?
* Presets (including save/load)
* Gray-scale/channels support
* Documentation
......
......@@ -113,7 +113,44 @@ void init_compute(void)
box_drawables[i]->width, box_drawables[i]->height,
FALSE, FALSE);
}
break;
case MAP_CYLINDER:
get_ray_color=get_ray_color_cylinder;
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);
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 cylinder cap images */
/* ================================================ */
for (i=0;i<2;i++)
{
cylinder_drawables[i] = gimp_drawable_get (mapvals.cylindermap_id[i]);
gimp_pixel_rgn_init (&cylinder_regions[i], cylinder_drawables[i],
0, 0,
cylinder_drawables[i]->width, cylinder_drawables[i]->height,
FALSE, FALSE);
}
break;
}
......@@ -182,16 +219,20 @@ void compute_image(void)
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;
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;
case MAP_CYLINDER:
gimp_progress_init("Map to object (cylinder)");
break;
}
if (mapvals.antialiasing==FALSE)
{
for (ycount=0;ycount<height;ycount++)
......
......@@ -13,6 +13,9 @@ GPixelRgn source_region,dest_region;
GDrawable *box_drawables[6];
GPixelRgn box_regions[6];
GDrawable *cylinder_drawables[2];
GPixelRgn cylinder_regions[2];
guchar *preview_rgb_data = NULL;
GdkImage *image = NULL;
......@@ -51,7 +54,7 @@ GckRGB peek(gint x,gint y)
return(color);
}
GckRGB peek_image(gint image, gint x,gint y)
GckRGB peek_box_image(gint image, gint x,gint y)
{
static guchar data[4];
GckRGB color;
......@@ -75,6 +78,30 @@ GckRGB peek_image(gint image, gint x,gint y)
return(color);
}
GckRGB peek_cylinder_image(gint image, gint x,gint y)
{
static guchar data[4];
GckRGB color;
gimp_pixel_rgn_get_pixel(&cylinder_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 (cylinder_drawables[image]->bpp==4)
{
if (gimp_drawable_has_alpha(cylinder_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];
......@@ -95,7 +122,7 @@ gint checkbounds(gint x,gint y)
return(TRUE);
}
gint checkbounds_image(gint image, gint x,gint y)
gint checkbounds_box_image(gint image, gint x,gint y)
{
gint w,h;
......@@ -108,6 +135,19 @@ gint checkbounds_image(gint image, gint x,gint y)
return(TRUE);
}
gint checkbounds_cylinder_image(gint image, gint x,gint y)
{
gint w,h;
w = cylinder_drawables[image]->width;
h = cylinder_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;
......@@ -190,19 +230,47 @@ GckRGB get_box_image_color(gint image,gdouble u,gdouble v)
x1 = (gint)((u*(gdouble)w));
y1 = (gint)((v*(gdouble)h));
if (checkbounds_image(image, x1,y1)==FALSE)
if (checkbounds_box_image(image, x1,y1)==FALSE)
return(background);
x2 = (x1 + 1);
y2 = (y1 + 1);
if (checkbounds_box_image(image, x2,y2)==FALSE)
return(peek_box_image(image, x1,y1));
p[0] = peek_box_image(image, x1, y1);
p[1] = peek_box_image(image, x2, y1);
p[2] = peek_box_image(image, x1, y2);
p[3] = peek_box_image(image, x2, y2);
return(gck_bilinear_rgba(u*w, v*h, p));
}
GckRGB get_cylinder_image_color(gint image,gdouble u,gdouble v)
{
gint w,h, x1, y1, x2, y2;
GckRGB p[4];
w = cylinder_drawables[image]->width;
h = cylinder_drawables[image]->height;
x1 = (gint)((u*(gdouble)w));
y1 = (gint)((v*(gdouble)h));
if (checkbounds_cylinder_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));
if (checkbounds_cylinder_image(image, x2,y2)==FALSE)
return(peek_cylinder_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);
p[0] = peek_cylinder_image(image, x1, y1);
p[1] = peek_cylinder_image(image, x2, y1);
p[2] = peek_cylinder_image(image, x1, y2);
p[3] = peek_cylinder_image(image, x2, y2);
return(gck_bilinear_rgba(u*w, v*h, p));
}
......
......@@ -23,6 +23,9 @@ extern GPixelRgn source_region,dest_region;
extern GDrawable *box_drawables[6];
extern GPixelRgn box_regions[6];
extern GDrawable *cylinder_drawables[2];
extern GPixelRgn cylinder_regions[2];
extern guchar *preview_rgb_data;
extern GdkImage *image;
......@@ -38,15 +41,17 @@ 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 GckRGB get_box_image_color (gint image, gdouble u,gdouble v);
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);
extern GckRGB get_cylinder_image_color (gint image, gdouble u,gdouble v);
#endif
/*********************************************************************************/
/* MapObject 1.10 -- image filter plug-in for The Gimp program */
/* MapObject 1.2.0 -- image filter plug-in for The Gimp program */
/* Copyright (C) 1996-98 Tom Bech */
/* Copyright (C) 1996-98 Federico Mena Quintero */
/*===============================================================================*/
......@@ -59,6 +59,8 @@ void set_default_settings(void)
mapvals.alpha=mapvals.beta=mapvals.gamma=0.0;
mapvals.maxdepth=3.0;
mapvals.radius=0.25;
mapvals.cylinder_radius=0.25;
mapvals.cylinder_length=1.0;
mapvals.preview_zoom_factor=0;
......@@ -82,6 +84,9 @@ void set_default_settings(void)
for (i=0;i<6;i++)
mapvals.boxmap_id[i] = -1;
for (i=0;i<2;i++)
mapvals.cylindermap_id[i] = -1;
}
void check_drawables(GDrawable *drawable)
......@@ -91,7 +96,7 @@ void check_drawables(GDrawable *drawable)
/* Check that boxmap images are valid */
/* ================================== */
for (i=0;i<mapvals.boxmap_id[i];i++)
for (i=0;i<6;i++)
{
if (mapvals.boxmap_id[i]==-1)
mapvals.boxmap_id[i] = drawable->id;
......@@ -100,19 +105,32 @@ void check_drawables(GDrawable *drawable)
else if (gimp_drawable_gray(mapvals.boxmap_id[i]))
mapvals.boxmap_id[i] = drawable->id;
}
/* Check that cylindermap images are valid */
/* ======================================= */
for (i=0;i<2;i++)
{
if (mapvals.cylindermap_id[i]==-1)
mapvals.cylindermap_id[i] = drawable->id;
else if (mapvals.cylindermap_id[i]!=-1 &&
gimp_drawable_image_id(mapvals.cylindermap_id[i])==-1)
mapvals.cylindermap_id[i] = drawable->id;
else if (gimp_drawable_gray(mapvals.cylindermap_id[i]))
mapvals.cylindermap_id[i] = drawable->id;
}
}
MAIN()
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,2=box)" },
{ PARAM_INT32, "maptype", "Type of mapping (0=plane,1=sphere,2=box,3=cylinder)" },
{ 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)" },
......@@ -145,17 +163,19 @@ static void query(void)
{ 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, "radius", "Sphere/cylinder radius (only used when maptype=1 or 3)" },
{ 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" }
{ PARAM_FLOAT, "cylinder_length", "Cylinder length (0..->)"},
{ PARAM_DRAWABLE, "box_front_drawable", "Box front face (set these to -1 if not used)" },
{ PARAM_DRAWABLE, "box_back_drawable", "Box back face" },
{ PARAM_DRAWABLE, "box_top_drawable", "Box top face" },
{ PARAM_DRAWABLE, "box_bottom_drawable", "Box bottom face" },
{ PARAM_DRAWABLE, "box_left_drawable", "Box left face" },
{ PARAM_DRAWABLE, "box_right_drawable", "Box right face" },
{ PARAM_DRAWABLE, "cyl_top_drawable", "Cylinder top face (set these to -1 if not used)" },
{ PARAM_DRAWABLE, "cyl_bottom_drawable", "Cylinder bottom face" }
};
static GParamDef *return_vals = NULL;
......@@ -163,11 +183,11 @@ static void query(void)
static gint nreturn_vals = 0;
gimp_install_procedure ("plug_in_map_object",
"Maps a picture to a object (plane, sphere or box)",
"Maps a picture to a object (plane, sphere, box or cylinder)",
"No help yet",
"Tom Bech & Federico Mena Quintero",
"Tom Bech & Federico Mena Quintero",
"Version 1.10, July 17 1998",
"Version 1.2.0, July 16 1998",
"<Image>/Filters/Distorts/Map Object",
"RGB*",
PROC_PLUG_IN,
......@@ -224,7 +244,7 @@ static void run(gchar *name,
compute_image();
break;
case RUN_NONINTERACTIVE:
if (nparams != 46)
if (nparams != 49)
status = STATUS_CALLING_ERROR;
else if (status == STATUS_SUCCESS)
{
......@@ -264,12 +284,17 @@ 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.cylinder_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;
mapvals.cylinder_length = param[40].data.d_float;
for (i=0;i<6;i++)
mapvals.boxmap_id[i] = gimp_drawable_get(param[40+i].data.d_drawable)->id;
mapvals.boxmap_id[i] = gimp_drawable_get(param[41+i].data.d_drawable)->id;
for (i=0;i<2;i++)
mapvals.cylindermap_id[i] = gimp_drawable_get(param[47+i].data.d_drawable)->id;
check_drawables(drawable);
image_setup(drawable, FALSE);
......
......@@ -32,7 +32,8 @@ typedef enum {
typedef enum {
MAP_PLANE,
MAP_SPHERE,
MAP_BOX
MAP_BOX,
MAP_CYLINDER
} MapType;
/* Typedefs */
......@@ -72,6 +73,7 @@ typedef struct {
gint tiled;
gint showgrid;
gint tooltips_enabled;
gint showcaps;
glong preview_zoom_factor;
......@@ -79,8 +81,11 @@ typedef struct {
gdouble maxdepth;
gdouble pixeltreshold;
gdouble radius;
gdouble cylinder_radius;
gdouble cylinder_length;
gint32 boxmap_id[6];
gint32 cylindermap_id[2];
} MapObjectValues;
......
......@@ -21,9 +21,10 @@ 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 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 draw_wireframe_cylinder (gint startx,gint starty,gint pw,gint ph);
void clear_wireframe (void);
......@@ -319,6 +320,9 @@ void draw_wireframe(gint startx,gint starty,gint pw,gint ph)
case MAP_BOX:
draw_wireframe_box(startx,starty,pw,ph);
break;
case MAP_CYLINDER:
draw_wireframe_cylinder(startx,starty,pw,ph);
break;
}
}
......@@ -619,6 +623,75 @@ void draw_wireframe_box(gint startx,gint starty,gint pw,gint ph)
linetab[n].x1=-1;
}
void draw_wireframe_cylinder(gint startx,gint starty,gint pw,gint ph)
{
GckVector3 p[2*8], a, axis, scale;
gint n=0,i;
gdouble cx1,cy1,cx2,cy2;
gfloat m[16], l, angle;
/* Compute wireframe points */
/* ======================== */
init_compute();
scale = mapvals.scale;
gck_vector3_mul(&scale,0.5);
l = mapvals.cylinder_length/2.0;
angle = 0;
gck_vector3_set(&axis, 0.0,1.0,0.0);
for (i=0;i<8;i++)
{
rotatemat(angle, &axis, m);
gck_vector3_set(&a, mapvals.cylinder_radius,0.0,0.0);
vecmulmat(&p[i], &a, m);
p[i+8] = p[i];
p[i].y += l;
p[i+8].y -= l;
angle += 360.0/8.0;
}
/* Rotate and translate points */
/* =========================== */
for (i=0;i<16;i++)
{
vecmulmat(&a,&p[i],rotmat);
gck_vector3_add(&p[i],&a,&mapvals.position);
}
/* Draw the box */
/* ============ */
cx1=(gdouble)startx;
cy1=(gdouble)starty;
cx2=cx1+(gdouble)pw;
cy2=cy1+(gdouble)ph;
for (i=0;i<7;i++)
{
n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[i],p[i+1]);
n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[i+8],p[i+9]);
n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[i],p[i+8]);
}
n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[7],p[0]);
n = draw_line(n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[15],p[8]);
/* Mark end of lines */
/* ================= */
linetab[n].x1=-1;
}
void clear_wireframe(void)
{
gint n=0;
......
......@@ -589,7 +589,7 @@ gboolean intersect_rect(gdouble u,gdouble v,gdouble w,
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;
face_info->s.z = w;
if (face_info->s.x>=-u2 && face_info->s.x<=u2 &&
face_info->s.y>=-v2 && face_info->s.y<=v2)
......@@ -908,3 +908,314 @@ GckRGB get_ray_color_box(GckVector3 *pos)
return(color);
}
gboolean intersect_circle(GckVector3 vp,GckVector3 dir,gdouble w,
FaceIntersectInfo *face_info)
{
gboolean result = FALSE;
gdouble r,d;
#define sqr(a) a*a
if (dir.y!=0.0)
{
face_info->t = (w-vp.y)/dir.y;
face_info->s.x = vp.x + face_info->t*dir.x;
face_info->s.y = w;
face_info->s.z = vp.z + face_info->t*dir.z;
r = sqrt(sqr(