home *** CD-ROM | disk | FTP | other *** search
- /******************************************************/
- /* Apply mapping and shading on the whole input image */
- /******************************************************/
-
- #include <string.h>
-
- #include <gtk/gtk.h>
-
- #include <libgimp/gimp.h>
-
- #include <gck/gck.h>
-
- #include "mapobject_main.h"
- #include "mapobject_image.h"
- #include "mapobject_shade.h"
-
- /*************/
- /* Main loop */
- /*************/
-
- gdouble imat[4][4];
- gfloat rotmat[16], a[16], b[16];
-
- void init_compute(void)
- {
- gint i;
-
- switch (mapvals.maptype)
- {
- case MAP_SPHERE:
-
- /* Rotate the equator/northpole axis */
- /* ================================= */
-
- 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,gimp_deg_to_rad(mapvals.alpha),
- gimp_deg_to_rad(mapvals.beta),gimp_deg_to_rad(mapvals.gamma));
- gimp_vector3_rotate(&mapvals.secondaxis,gimp_deg_to_rad(mapvals.alpha),
- gimp_deg_to_rad(mapvals.beta),gimp_deg_to_rad(mapvals.gamma));
-
- /* Compute the 2D bounding box of the sphere spanned by the axis */
- /* ============================================================= */
-
- compute_bounding_box();
-
- get_ray_color=get_ray_color_sphere;
-
- break;
-
- case MAP_PLANE:
-
- /* Rotate the plane axis */
- /* ===================== */
-
- 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,gimp_deg_to_rad(mapvals.alpha),
- gimp_deg_to_rad(mapvals.beta),gimp_deg_to_rad(mapvals.gamma));
- gimp_vector3_rotate(&mapvals.secondaxis,gimp_deg_to_rad(mapvals.alpha),
- gimp_deg_to_rad(mapvals.beta),gimp_deg_to_rad(mapvals.gamma));
-
- mapvals.normal=gimp_vector3_cross_product(&mapvals.firstaxis,&mapvals.secondaxis);
-
- if (mapvals.normal.z<0.0)
- gimp_vector3_mul(&mapvals.normal,-1.0);
-
- /* Initialize intersection matrix */
- /* ============================== */
-
- 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;
-
- break;
- case MAP_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);
-
- 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;
- case MAP_CYLINDER:
- get_ray_color=get_ray_color_cylinder;
-
- 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);
-
- 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;
- }
-
- max_depth=(gint)mapvals.maxdepth;
- }
-
- void render(gdouble x,gdouble y,GckRGB *col)
- {
- GimpVector3 pos;
-
- pos.x=x/(gdouble)width;
- pos.y=y/(gdouble)height;
- pos.z=0.0;
-
- *col=get_ray_color(&pos);
- }
-
- void show_progress(gint min,gint max,gint curr)
- {
- gimp_progress_update((gdouble)curr/(gdouble)max);
- }
-
- /**************************************************/
- /* Performs map-to-sphere on the whole input image */
- /* and updates or creates a new GIMP image. */
- /**************************************************/
-
- void compute_image(void)
- {
- gint xcount,ycount;
- GckRGB color;
- glong progress_counter=0;
- GimpVector3 p;
- gint32 new_image_id=-1,new_layer_id=-1;
-
- init_compute();
-
- if (mapvals.create_new_image==TRUE || (mapvals.transparent_background==TRUE
- && input_drawable->bpp!=4))
- {
- /* Create a new image */
- /* ================== */
-
- new_image_id=gimp_image_new(width,height,GIMP_RGB);
-
- if (mapvals.transparent_background==TRUE)
- {
- /* Add a layer with an alpha channel */
- /* ================================= */
-
- new_layer_id=gimp_layer_new(new_image_id,"Background",width,height,GIMP_RGBA_IMAGE,100.0,GIMP_NORMAL_MODE);
- }
- else
- {
- /* Create a "normal" layer */
- /* ======================= */
-
- new_layer_id=gimp_layer_new(new_image_id,"Background",width,height,GIMP_RGB_IMAGE,100.0,GIMP_NORMAL_MODE);
- }
-
- gimp_image_add_layer(new_image_id,new_layer_id,0);
- output_drawable=gimp_drawable_get(new_layer_id);
- }
-
- gimp_pixel_rgn_init (&dest_region, output_drawable, 0, 0, width, height, TRUE, TRUE);
-
- 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_CYLINDER:
- gimp_progress_init("Map to object (cylinder)");
- break;
- }
-
- if (mapvals.antialiasing==FALSE)
- {
- for (ycount=0;ycount<height;ycount++)
- {
- for (xcount=0;xcount<width;xcount++)
- {
- p=int_to_pos(xcount,ycount);
- color=(*get_ray_color)(&p);
- poke(xcount,ycount,&color);
- if ((progress_counter++ % width)==0)
- gimp_progress_update((gdouble)progress_counter/(gdouble)maxcounter);
- }
- }
- }
- else
- gck_adaptive_supersample_area(0,0,width-1,height-1,max_depth,mapvals.pixeltreshold,
- render,poke,show_progress);
-
- /* Update the region */
- /* ================= */
-
- gimp_drawable_flush (output_drawable);
- gimp_drawable_merge_shadow (output_drawable->id, TRUE);
- gimp_drawable_update (output_drawable->id, 0, 0, width,height);
-
- if (new_image_id!=-1)
- {
- gimp_display_new(new_image_id);
- gimp_displays_flush();
- gimp_drawable_detach (output_drawable);
- }
- }
-