1998-03-20 10:42:24 +08:00
|
|
|
/******************************************************/
|
|
|
|
/* Apply mapping and shading on the whole input image */
|
|
|
|
/******************************************************/
|
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
#include "config.h"
|
|
|
|
|
2000-06-07 05:33:19 +08:00
|
|
|
#include <string.h>
|
|
|
|
|
2000-02-18 21:59:18 +08:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
|
|
|
#include <libgimp/gimp.h>
|
2005-09-26 05:22:39 +08:00
|
|
|
#include <libgimp/gimpui.h>
|
2000-02-18 21:59:18 +08:00
|
|
|
|
2008-03-25 02:33:25 +08:00
|
|
|
#include "map-object-main.h"
|
|
|
|
#include "map-object-image.h"
|
|
|
|
#include "map-object-shade.h"
|
|
|
|
#include "map-object-apply.h"
|
1998-03-20 10:42:24 +08:00
|
|
|
|
2004-05-23 20:43:13 +08:00
|
|
|
#include "libgimp/stdplugins-intl.h"
|
|
|
|
|
|
|
|
|
1998-03-20 10:42:24 +08:00
|
|
|
/*************/
|
|
|
|
/* Main loop */
|
|
|
|
/*************/
|
|
|
|
|
2008-03-29 17:25:34 +08:00
|
|
|
gdouble imat[4][4];
|
|
|
|
gfloat rotmat[16];
|
|
|
|
static gfloat a[16], b[16];
|
1998-03-20 10:42:24 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
void
|
|
|
|
init_compute (void)
|
1998-03-20 10:42:24 +08:00
|
|
|
{
|
1998-07-16 08:45:41 +08:00
|
|
|
gint i;
|
1998-03-20 10:42:24 +08:00
|
|
|
|
|
|
|
switch (mapvals.maptype)
|
|
|
|
{
|
|
|
|
case MAP_SPHERE:
|
|
|
|
|
|
|
|
/* Rotate the equator/northpole axis */
|
|
|
|
/* ================================= */
|
2003-12-15 01:17:56 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
gimp_vector3_set (&mapvals.firstaxis, 0.0, 0.0, -1.0);
|
|
|
|
gimp_vector3_set (&mapvals.secondaxis, 0.0, 1.0, 0.0);
|
|
|
|
|
|
|
|
gimp_vector3_rotate (&mapvals.firstaxis,
|
2011-02-20 22:23:22 +08:00
|
|
|
gimp_deg_to_rad (mapvals.alpha),
|
|
|
|
gimp_deg_to_rad (mapvals.beta),
|
|
|
|
gimp_deg_to_rad (mapvals.gamma));
|
2000-12-30 08:23:34 +08:00
|
|
|
gimp_vector3_rotate (&mapvals.secondaxis,
|
2011-02-20 22:23:22 +08:00
|
|
|
gimp_deg_to_rad (mapvals.alpha),
|
|
|
|
gimp_deg_to_rad (mapvals.beta),
|
|
|
|
gimp_deg_to_rad (mapvals.gamma));
|
2000-12-30 08:23:34 +08:00
|
|
|
|
1998-03-20 10:42:24 +08:00
|
|
|
/* Compute the 2D bounding box of the sphere spanned by the axis */
|
|
|
|
/* ============================================================= */
|
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
compute_bounding_box ();
|
|
|
|
|
|
|
|
get_ray_color = get_ray_color_sphere;
|
1998-03-20 10:42:24 +08:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MAP_PLANE:
|
|
|
|
|
|
|
|
/* Rotate the plane axis */
|
|
|
|
/* ===================== */
|
2003-12-15 01:17:56 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
gimp_vector3_set (&mapvals.firstaxis, 1.0, 0.0, 0.0);
|
|
|
|
gimp_vector3_set (&mapvals.secondaxis, 0.0, 1.0, 0.0);
|
|
|
|
gimp_vector3_set (&mapvals.normal, 0.0, 0.0, 1.0);
|
|
|
|
|
|
|
|
gimp_vector3_rotate (&mapvals.firstaxis,
|
2011-02-20 22:23:22 +08:00
|
|
|
gimp_deg_to_rad (mapvals.alpha),
|
|
|
|
gimp_deg_to_rad (mapvals.beta),
|
|
|
|
gimp_deg_to_rad (mapvals.gamma));
|
2000-12-30 08:23:34 +08:00
|
|
|
gimp_vector3_rotate (&mapvals.secondaxis,
|
2011-02-20 22:23:22 +08:00
|
|
|
gimp_deg_to_rad (mapvals.alpha),
|
|
|
|
gimp_deg_to_rad (mapvals.beta),
|
|
|
|
gimp_deg_to_rad (mapvals.gamma));
|
2000-12-30 08:23:34 +08:00
|
|
|
|
|
|
|
mapvals.normal = gimp_vector3_cross_product (&mapvals.firstaxis,
|
2011-02-20 22:23:22 +08:00
|
|
|
&mapvals.secondaxis);
|
2000-12-30 08:23:34 +08:00
|
|
|
|
|
|
|
if (mapvals.normal.z < 0.0)
|
|
|
|
gimp_vector3_mul (&mapvals.normal, -1.0);
|
|
|
|
|
1998-03-20 10:42:24 +08:00
|
|
|
/* Initialize intersection matrix */
|
|
|
|
/* ============================== */
|
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
imat[0][1] = -mapvals.firstaxis.x;
|
|
|
|
imat[1][1] = -mapvals.firstaxis.y;
|
|
|
|
imat[2][1] = -mapvals.firstaxis.z;
|
|
|
|
|
|
|
|
imat[0][2] = -mapvals.secondaxis.x;
|
|
|
|
imat[1][2] = -mapvals.secondaxis.y;
|
|
|
|
imat[2][2] = -mapvals.secondaxis.z;
|
|
|
|
|
|
|
|
imat[0][3] = mapvals.position.x - mapvals.viewpoint.x;
|
|
|
|
imat[1][3] = mapvals.position.y - mapvals.viewpoint.y;
|
|
|
|
imat[2][3] = mapvals.position.z - mapvals.viewpoint.z;
|
|
|
|
|
|
|
|
get_ray_color = get_ray_color_plane;
|
1998-03-20 10:42:24 +08:00
|
|
|
|
1998-07-16 08:45:41 +08:00
|
|
|
break;
|
2000-12-30 08:23:34 +08:00
|
|
|
|
1998-07-16 08:45:41 +08:00
|
|
|
case MAP_BOX:
|
2000-12-30 08:23:34 +08:00
|
|
|
get_ray_color = get_ray_color_box;
|
|
|
|
|
|
|
|
gimp_vector3_set (&mapvals.firstaxis, 1.0, 0.0, 0.0);
|
|
|
|
gimp_vector3_set (&mapvals.secondaxis, 0.0, 1.0, 0.0);
|
|
|
|
gimp_vector3_set (&mapvals.normal, 0.0, 0.0, 1.0);
|
1998-07-16 08:45:41 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
ident_mat (rotmat);
|
1998-07-16 08:45:41 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
rotatemat (mapvals.alpha, &mapvals.firstaxis, a);
|
1998-07-16 08:45:41 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
matmul (a, rotmat, b);
|
1998-07-16 08:45:41 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
memcpy (rotmat, b, sizeof (gfloat) * 16);
|
1998-07-16 08:45:41 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
rotatemat (mapvals.beta, &mapvals.secondaxis, a);
|
|
|
|
matmul (a, rotmat, b);
|
1998-07-16 08:45:41 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
memcpy (rotmat, b, sizeof (gfloat) * 16);
|
1998-07-16 08:45:41 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
rotatemat (mapvals.gamma, &mapvals.normal, a);
|
|
|
|
matmul (a, rotmat, b);
|
|
|
|
|
|
|
|
memcpy (rotmat, b, sizeof (gfloat) * 16);
|
1998-07-16 08:45:41 +08:00
|
|
|
|
|
|
|
/* Set up pixel regions for the box face images */
|
|
|
|
/* ============================================ */
|
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
for (i = 0; i < 6; i++)
|
1998-07-16 08:45:41 +08:00
|
|
|
{
|
2011-02-20 22:23:22 +08:00
|
|
|
box_drawables[i] = gimp_drawable_get (mapvals.boxmap_id[i]);
|
2000-12-30 08:23:34 +08:00
|
|
|
|
2011-02-20 22:23:22 +08:00
|
|
|
gimp_pixel_rgn_init (&box_regions[i], box_drawables[i],
|
1998-07-16 08:45:41 +08:00
|
|
|
0, 0,
|
2000-12-30 08:23:34 +08:00
|
|
|
box_drawables[i]->width,
|
2011-02-20 22:23:22 +08:00
|
|
|
box_drawables[i]->height,
|
1998-07-16 08:45:41 +08:00
|
|
|
FALSE, FALSE);
|
|
|
|
}
|
2000-12-30 08:23:34 +08:00
|
|
|
|
1998-07-17 04:14:54 +08:00
|
|
|
break;
|
2000-12-30 08:23:34 +08:00
|
|
|
|
1998-07-17 04:14:54 +08:00
|
|
|
case MAP_CYLINDER:
|
2000-12-30 08:23:34 +08:00
|
|
|
get_ray_color = get_ray_color_cylinder;
|
1998-07-17 04:14:54 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
gimp_vector3_set (&mapvals.firstaxis, 1.0, 0.0, 0.0);
|
|
|
|
gimp_vector3_set (&mapvals.secondaxis, 0.0, 1.0, 0.0);
|
|
|
|
gimp_vector3_set (&mapvals.normal, 0.0, 0.0, 1.0);
|
1998-07-16 08:45:41 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
ident_mat (rotmat);
|
1998-07-17 04:14:54 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
rotatemat (mapvals.alpha, &mapvals.firstaxis, a);
|
1998-07-17 04:14:54 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
matmul (a, rotmat, b);
|
1998-07-17 04:14:54 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
memcpy (rotmat, b, sizeof (gfloat) * 16);
|
1998-07-17 04:14:54 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
rotatemat (mapvals.beta, &mapvals.secondaxis, a);
|
|
|
|
matmul (a, rotmat, b);
|
1998-07-17 04:14:54 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
memcpy (rotmat, b, sizeof (gfloat) * 16);
|
1998-07-17 04:14:54 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
rotatemat (mapvals.gamma, &mapvals.normal, a);
|
|
|
|
matmul (a, rotmat, b);
|
|
|
|
|
|
|
|
memcpy (rotmat, b, sizeof (gfloat) * 16);
|
1998-07-17 04:14:54 +08:00
|
|
|
|
|
|
|
/* Set up pixel regions for the cylinder cap images */
|
|
|
|
/* ================================================ */
|
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
for (i = 0; i < 2; i++)
|
1998-07-17 04:14:54 +08:00
|
|
|
{
|
2011-02-20 22:23:22 +08:00
|
|
|
cylinder_drawables[i] =
|
|
|
|
gimp_drawable_get (mapvals.cylindermap_id[i]);
|
2000-12-30 08:23:34 +08:00
|
|
|
|
2011-02-20 22:23:22 +08:00
|
|
|
gimp_pixel_rgn_init (&cylinder_regions[i], cylinder_drawables[i],
|
1998-07-17 04:14:54 +08:00
|
|
|
0, 0,
|
2000-12-30 08:23:34 +08:00
|
|
|
cylinder_drawables[i]->width,
|
2011-02-20 22:23:22 +08:00
|
|
|
cylinder_drawables[i]->height,
|
1998-07-17 04:14:54 +08:00
|
|
|
FALSE, FALSE);
|
|
|
|
}
|
2000-12-30 08:23:34 +08:00
|
|
|
|
1998-03-20 10:42:24 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
max_depth = (gint) mapvals.maxdepth;
|
1998-03-20 10:42:24 +08:00
|
|
|
}
|
|
|
|
|
2006-10-31 05:36:08 +08:00
|
|
|
static void
|
2001-01-23 08:53:12 +08:00
|
|
|
render (gdouble x,
|
2011-02-20 22:23:22 +08:00
|
|
|
gdouble y,
|
|
|
|
GimpRGB *col,
|
|
|
|
gpointer data)
|
1998-03-20 10:42:24 +08:00
|
|
|
{
|
2000-02-15 00:29:41 +08:00
|
|
|
GimpVector3 pos;
|
2000-12-30 08:23:34 +08:00
|
|
|
|
|
|
|
pos.x = x / (gdouble) width;
|
|
|
|
pos.y = y / (gdouble) height;
|
|
|
|
pos.z = 0.0;
|
|
|
|
|
|
|
|
*col = get_ray_color (&pos);
|
1998-03-20 10:42:24 +08:00
|
|
|
}
|
|
|
|
|
2006-10-31 05:36:08 +08:00
|
|
|
static void
|
2001-01-23 08:53:12 +08:00
|
|
|
show_progress (gint min,
|
2011-02-20 22:23:22 +08:00
|
|
|
gint max,
|
|
|
|
gint curr,
|
|
|
|
gpointer data)
|
1998-03-20 10:42:24 +08:00
|
|
|
{
|
2000-12-30 08:23:34 +08:00
|
|
|
gimp_progress_update ((gdouble) curr / (gdouble) max);
|
1998-03-20 10:42:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************/
|
|
|
|
/* Performs map-to-sphere on the whole input image */
|
|
|
|
/* and updates or creates a new GIMP image. */
|
|
|
|
/**************************************************/
|
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
void
|
|
|
|
compute_image (void)
|
1998-03-20 10:42:24 +08:00
|
|
|
{
|
2000-12-30 08:23:34 +08:00
|
|
|
gint xcount, ycount;
|
2011-02-20 20:49:58 +08:00
|
|
|
GimpRGB color;
|
2000-12-30 08:23:34 +08:00
|
|
|
glong progress_counter = 0;
|
|
|
|
GimpVector3 p;
|
|
|
|
gint32 new_image_id = -1;
|
|
|
|
gint32 new_layer_id = -1;
|
2011-02-20 20:49:58 +08:00
|
|
|
gboolean insert_layer = FALSE;
|
2000-12-30 08:23:34 +08:00
|
|
|
|
|
|
|
init_compute ();
|
|
|
|
|
2011-02-20 20:49:58 +08:00
|
|
|
if (mapvals.create_new_image)
|
1998-03-20 10:42:24 +08:00
|
|
|
{
|
2000-12-30 08:23:34 +08:00
|
|
|
new_image_id = gimp_image_new (width, height, GIMP_RGB);
|
2011-02-20 20:00:13 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
new_image_id = image_id;
|
|
|
|
}
|
1998-03-20 10:42:24 +08:00
|
|
|
|
2011-02-20 20:20:38 +08:00
|
|
|
gimp_image_undo_group_start (new_image_id);
|
|
|
|
|
2011-02-20 20:00:13 +08:00
|
|
|
if (mapvals.create_new_image ||
|
|
|
|
mapvals.create_new_layer ||
|
|
|
|
(mapvals.transparent_background &&
|
|
|
|
output_drawable->bpp != 4))
|
|
|
|
{
|
2011-02-20 20:49:58 +08:00
|
|
|
gchar *layername[] = {_("Map to plane"), _("Map to sphere"), _("Map to box"),
|
|
|
|
_("Map to cylinder"), _("Background")};
|
2011-02-20 20:00:13 +08:00
|
|
|
|
2011-02-20 20:49:58 +08:00
|
|
|
new_layer_id = gimp_layer_new (new_image_id, layername[mapvals.create_new_image ? 4 :
|
|
|
|
mapvals.maptype],
|
2011-02-20 20:00:13 +08:00
|
|
|
width, height,
|
|
|
|
mapvals.transparent_background ? GIMP_RGBA_IMAGE
|
|
|
|
: GIMP_RGB_IMAGE,
|
|
|
|
100.0,
|
|
|
|
GIMP_NORMAL_MODE);
|
1998-03-20 10:42:24 +08:00
|
|
|
|
2011-02-20 20:49:58 +08:00
|
|
|
insert_layer = TRUE;
|
2000-12-30 08:23:34 +08:00
|
|
|
output_drawable = gimp_drawable_get (new_layer_id);
|
1998-03-20 10:42:24 +08:00
|
|
|
}
|
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
gimp_pixel_rgn_init (&dest_region, output_drawable,
|
2011-02-20 22:23:22 +08:00
|
|
|
0, 0, width, height, TRUE, TRUE);
|
1998-03-20 10:42:24 +08:00
|
|
|
|
1998-07-16 08:45:41 +08:00
|
|
|
switch (mapvals.maptype)
|
|
|
|
{
|
1998-07-17 04:14:54 +08:00
|
|
|
case MAP_PLANE:
|
2005-09-30 16:16:10 +08:00
|
|
|
gimp_progress_init (_("Map to plane"));
|
1998-07-17 04:14:54 +08:00
|
|
|
break;
|
|
|
|
case MAP_SPHERE:
|
2005-09-30 16:16:10 +08:00
|
|
|
gimp_progress_init (_("Map to sphere"));
|
1998-07-17 04:14:54 +08:00
|
|
|
break;
|
|
|
|
case MAP_BOX:
|
2005-09-30 16:16:10 +08:00
|
|
|
gimp_progress_init (_("Map to box"));
|
1998-07-17 04:14:54 +08:00
|
|
|
break;
|
|
|
|
case MAP_CYLINDER:
|
2005-09-30 16:16:10 +08:00
|
|
|
gimp_progress_init (_("Map to cylinder"));
|
1998-07-17 04:14:54 +08:00
|
|
|
break;
|
1998-07-16 08:45:41 +08:00
|
|
|
}
|
1998-07-17 04:14:54 +08:00
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
if (mapvals.antialiasing == FALSE)
|
1998-03-20 10:42:24 +08:00
|
|
|
{
|
2000-12-30 08:23:34 +08:00
|
|
|
for (ycount = 0; ycount < height; ycount++)
|
1998-03-20 10:42:24 +08:00
|
|
|
{
|
2000-12-30 08:23:34 +08:00
|
|
|
for (xcount = 0; xcount < width; xcount++)
|
1998-03-20 10:42:24 +08:00
|
|
|
{
|
2000-12-30 08:23:34 +08:00
|
|
|
p = int_to_pos (xcount, ycount);
|
|
|
|
color = (* get_ray_color) (&p);
|
2001-01-23 08:53:12 +08:00
|
|
|
poke (xcount, ycount, &color, NULL);
|
2000-12-30 08:23:34 +08:00
|
|
|
|
|
|
|
if ((progress_counter++ % width) == 0)
|
|
|
|
gimp_progress_update ((gdouble) progress_counter /
|
2011-02-20 22:23:22 +08:00
|
|
|
(gdouble) maxcounter);
|
1998-03-20 10:42:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2000-12-30 08:23:34 +08:00
|
|
|
{
|
2001-01-23 08:53:12 +08:00
|
|
|
gimp_adaptive_supersample_area (0, 0,
|
2011-02-20 22:23:22 +08:00
|
|
|
width - 1, height - 1,
|
|
|
|
max_depth,
|
|
|
|
mapvals.pixeltreshold,
|
|
|
|
render,
|
|
|
|
NULL,
|
|
|
|
poke,
|
|
|
|
NULL,
|
|
|
|
show_progress,
|
|
|
|
NULL);
|
2000-12-30 08:23:34 +08:00
|
|
|
}
|
1998-03-20 10:42:24 +08:00
|
|
|
|
|
|
|
/* Update the region */
|
|
|
|
/* ================= */
|
|
|
|
|
|
|
|
gimp_drawable_flush (output_drawable);
|
2011-02-20 20:49:58 +08:00
|
|
|
if (insert_layer)
|
|
|
|
gimp_image_insert_layer (new_image_id, new_layer_id, -1, 0);
|
2001-06-15 04:07:38 +08:00
|
|
|
gimp_drawable_merge_shadow (output_drawable->drawable_id, TRUE);
|
|
|
|
gimp_drawable_update (output_drawable->drawable_id, 0, 0, width, height);
|
1998-03-20 10:42:24 +08:00
|
|
|
|
2011-02-20 20:00:13 +08:00
|
|
|
if (new_image_id != image_id)
|
1998-03-20 10:42:24 +08:00
|
|
|
{
|
2000-12-30 08:23:34 +08:00
|
|
|
gimp_display_new (new_image_id);
|
|
|
|
gimp_displays_flush ();
|
1998-03-20 10:42:24 +08:00
|
|
|
gimp_drawable_detach (output_drawable);
|
|
|
|
}
|
2011-02-20 20:20:38 +08:00
|
|
|
|
|
|
|
gimp_image_undo_group_end (new_image_id);
|
1998-03-20 10:42:24 +08:00
|
|
|
}
|