home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / MapObject / mapobject_apply.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-24  |  8.3 KB  |  278 lines

  1. /******************************************************/
  2. /* Apply mapping and shading on the whole input image */
  3. /******************************************************/
  4.  
  5. #include <string.h>
  6.  
  7. #include <gtk/gtk.h>
  8.  
  9. #include <libgimp/gimp.h>
  10.  
  11. #include <gck/gck.h>
  12.  
  13. #include "mapobject_main.h"
  14. #include "mapobject_image.h"
  15. #include "mapobject_shade.h"
  16.  
  17. /*************/
  18. /* Main loop */
  19. /*************/
  20.  
  21. gdouble imat[4][4];
  22. gfloat  rotmat[16], a[16], b[16];
  23.  
  24. void init_compute(void)
  25. {
  26.   gint i;
  27.  
  28.   switch (mapvals.maptype)
  29.     {
  30.       case MAP_SPHERE:
  31.  
  32.         /* Rotate the equator/northpole axis */
  33.         /* ================================= */
  34.     
  35.         gimp_vector3_set(&mapvals.firstaxis,0.0,0.0,-1.0);
  36.         gimp_vector3_set(&mapvals.secondaxis,0.0,1.0,0.0);
  37.     
  38.         gimp_vector3_rotate(&mapvals.firstaxis,gimp_deg_to_rad(mapvals.alpha),
  39.                            gimp_deg_to_rad(mapvals.beta),gimp_deg_to_rad(mapvals.gamma));
  40.         gimp_vector3_rotate(&mapvals.secondaxis,gimp_deg_to_rad(mapvals.alpha),
  41.                            gimp_deg_to_rad(mapvals.beta),gimp_deg_to_rad(mapvals.gamma));
  42.     
  43.         /* Compute the 2D bounding box of the sphere spanned by the axis */
  44.         /* ============================================================= */
  45.     
  46.         compute_bounding_box();
  47.  
  48.         get_ray_color=get_ray_color_sphere;
  49.  
  50.         break;
  51.  
  52.       case MAP_PLANE:
  53.  
  54.         /* Rotate the plane axis */
  55.         /* ===================== */
  56.     
  57.         gimp_vector3_set(&mapvals.firstaxis, 1.0,0.0,0.0);
  58.         gimp_vector3_set(&mapvals.secondaxis,0.0,1.0,0.0);
  59.         gimp_vector3_set(&mapvals.normal,0.0,0.0,1.0);
  60.     
  61.         gimp_vector3_rotate(&mapvals.firstaxis,gimp_deg_to_rad(mapvals.alpha),
  62.                            gimp_deg_to_rad(mapvals.beta),gimp_deg_to_rad(mapvals.gamma));
  63.         gimp_vector3_rotate(&mapvals.secondaxis,gimp_deg_to_rad(mapvals.alpha),
  64.                            gimp_deg_to_rad(mapvals.beta),gimp_deg_to_rad(mapvals.gamma));
  65.     
  66.         mapvals.normal=gimp_vector3_cross_product(&mapvals.firstaxis,&mapvals.secondaxis);
  67.     
  68.         if (mapvals.normal.z<0.0)
  69.           gimp_vector3_mul(&mapvals.normal,-1.0);
  70.     
  71.         /* Initialize intersection matrix */
  72.         /* ============================== */
  73.     
  74.         imat[0][1]=-mapvals.firstaxis.x;
  75.         imat[1][1]=-mapvals.firstaxis.y;
  76.         imat[2][1]=-mapvals.firstaxis.z; 
  77.   
  78.         imat[0][2]=-mapvals.secondaxis.x;
  79.         imat[1][2]=-mapvals.secondaxis.y;
  80.         imat[2][2]=-mapvals.secondaxis.z;
  81.     
  82.         imat[0][3]=mapvals.position.x-mapvals.viewpoint.x;
  83.         imat[1][3]=mapvals.position.y-mapvals.viewpoint.y;
  84.         imat[2][3]=mapvals.position.z-mapvals.viewpoint.z;
  85.  
  86.         get_ray_color=get_ray_color_plane;
  87.  
  88.         break;
  89.       case MAP_BOX:
  90.         gimp_vector3_set(&mapvals.firstaxis, 1.0,0.0,0.0);
  91.         gimp_vector3_set(&mapvals.secondaxis,0.0,1.0,0.0);
  92.         gimp_vector3_set(&mapvals.normal,0.0,0.0,1.0);
  93.  
  94.         get_ray_color=get_ray_color_box;
  95.         
  96.         ident_mat(rotmat);
  97.         
  98.         rotatemat(mapvals.alpha, &mapvals.firstaxis, a);
  99.  
  100.         matmul(a,rotmat,b);
  101.  
  102.         memcpy(rotmat, b, sizeof(gfloat)*16);
  103.  
  104.         rotatemat(mapvals.beta, &mapvals.secondaxis, a);
  105.         matmul(a,rotmat,b);
  106.  
  107.         memcpy(rotmat, b, sizeof(gfloat)*16);
  108.  
  109.         rotatemat(mapvals.gamma, &mapvals.normal, a);
  110.         matmul(a,rotmat,b);
  111.  
  112.         memcpy(rotmat, b, sizeof(gfloat)*16);
  113.  
  114.         /* Set up pixel regions for the box face images */
  115.         /* ============================================ */
  116.  
  117.         for (i=0;i<6;i++)
  118.           {
  119.              box_drawables[i] = gimp_drawable_get (mapvals.boxmap_id[i]);
  120.              
  121.              gimp_pixel_rgn_init (&box_regions[i], box_drawables[i],
  122.                                  0, 0,
  123.                                  box_drawables[i]->width, box_drawables[i]->height,
  124.                                  FALSE, FALSE);
  125.           }
  126.         break;
  127.       case MAP_CYLINDER:
  128.         get_ray_color=get_ray_color_cylinder;
  129.  
  130.         gimp_vector3_set(&mapvals.firstaxis, 1.0,0.0,0.0);
  131.         gimp_vector3_set(&mapvals.secondaxis,0.0,1.0,0.0);
  132.         gimp_vector3_set(&mapvals.normal,0.0,0.0,1.0);
  133.  
  134.         ident_mat(rotmat);
  135.         
  136.         rotatemat(mapvals.alpha, &mapvals.firstaxis, a);
  137.  
  138.         matmul(a,rotmat,b);
  139.  
  140.         memcpy(rotmat, b, sizeof(gfloat)*16);
  141.  
  142.         rotatemat(mapvals.beta, &mapvals.secondaxis, a);
  143.         matmul(a,rotmat,b);
  144.  
  145.         memcpy(rotmat, b, sizeof(gfloat)*16);
  146.  
  147.         rotatemat(mapvals.gamma, &mapvals.normal, a);
  148.         matmul(a,rotmat,b);
  149.  
  150.         memcpy(rotmat, b, sizeof(gfloat)*16);
  151.  
  152.         /* Set up pixel regions for the cylinder cap images */
  153.         /* ================================================ */
  154.  
  155.         for (i=0;i<2;i++)
  156.           {
  157.              cylinder_drawables[i] = gimp_drawable_get (mapvals.cylindermap_id[i]);
  158.              
  159.              gimp_pixel_rgn_init (&cylinder_regions[i], cylinder_drawables[i],
  160.                                  0, 0,
  161.                                  cylinder_drawables[i]->width, cylinder_drawables[i]->height,
  162.                                  FALSE, FALSE);
  163.           }
  164.         break;
  165.     }
  166.  
  167.   max_depth=(gint)mapvals.maxdepth;
  168. }
  169.  
  170. void render(gdouble x,gdouble y,GckRGB *col)
  171. {
  172.   GimpVector3 pos;
  173.   
  174.   pos.x=x/(gdouble)width;
  175.   pos.y=y/(gdouble)height;
  176.   pos.z=0.0;
  177.   
  178.   *col=get_ray_color(&pos);
  179. }
  180.  
  181. void show_progress(gint min,gint max,gint curr)
  182. {
  183.   gimp_progress_update((gdouble)curr/(gdouble)max);
  184. }
  185.  
  186. /**************************************************/
  187. /* Performs map-to-sphere on the whole input image */
  188. /* and updates or creates a new GIMP image.       */
  189. /**************************************************/
  190.  
  191. void compute_image(void)
  192. {
  193.   gint xcount,ycount;
  194.   GckRGB color;
  195.   glong progress_counter=0;
  196.   GimpVector3 p;
  197.   gint32 new_image_id=-1,new_layer_id=-1;
  198.  
  199.   init_compute();
  200.   
  201.   if (mapvals.create_new_image==TRUE || (mapvals.transparent_background==TRUE 
  202.       && input_drawable->bpp!=4))
  203.     {
  204.       /* Create a new image */
  205.       /* ================== */
  206.  
  207.       new_image_id=gimp_image_new(width,height,GIMP_RGB);
  208.  
  209.       if (mapvals.transparent_background==TRUE)
  210.         {
  211.           /* Add a layer with an alpha channel */
  212.           /* ================================= */
  213.  
  214.           new_layer_id=gimp_layer_new(new_image_id,"Background",width,height,GIMP_RGBA_IMAGE,100.0,GIMP_NORMAL_MODE);
  215.         }
  216.       else
  217.         {
  218.           /* Create a "normal" layer */
  219.           /* ======================= */
  220.  
  221.           new_layer_id=gimp_layer_new(new_image_id,"Background",width,height,GIMP_RGB_IMAGE,100.0,GIMP_NORMAL_MODE);
  222.         }
  223.  
  224.       gimp_image_add_layer(new_image_id,new_layer_id,0);
  225.       output_drawable=gimp_drawable_get(new_layer_id);
  226.     }
  227.  
  228.   gimp_pixel_rgn_init (&dest_region, output_drawable, 0, 0, width, height, TRUE, TRUE);
  229.  
  230.   switch (mapvals.maptype)
  231.     {
  232.       case MAP_PLANE:
  233.         gimp_progress_init("Map to object (plane)");
  234.         break;
  235.       case MAP_SPHERE:
  236.         gimp_progress_init("Map to object (sphere)");
  237.         break;
  238.       case MAP_BOX:
  239.         gimp_progress_init("Map to object (box)");
  240.         break;
  241.       case MAP_CYLINDER:
  242.         gimp_progress_init("Map to object (cylinder)");
  243.         break;
  244.     }
  245.  
  246.   if (mapvals.antialiasing==FALSE)
  247.     {
  248.       for (ycount=0;ycount<height;ycount++)
  249.         {
  250.           for (xcount=0;xcount<width;xcount++)
  251.             {
  252.               p=int_to_pos(xcount,ycount);
  253.               color=(*get_ray_color)(&p);
  254.               poke(xcount,ycount,&color);
  255.               if ((progress_counter++ % width)==0)
  256.                 gimp_progress_update((gdouble)progress_counter/(gdouble)maxcounter);
  257.             }
  258.         }
  259.     }
  260.   else
  261.     gck_adaptive_supersample_area(0,0,width-1,height-1,max_depth,mapvals.pixeltreshold,
  262.       render,poke,show_progress);
  263.  
  264.   /* Update the region */
  265.   /* ================= */
  266.  
  267.   gimp_drawable_flush (output_drawable);
  268.   gimp_drawable_merge_shadow (output_drawable->id, TRUE);
  269.   gimp_drawable_update (output_drawable->id, 0, 0, width,height);
  270.  
  271.   if (new_image_id!=-1)
  272.     {
  273.       gimp_display_new(new_image_id);
  274.       gimp_displays_flush();
  275.       gimp_drawable_detach (output_drawable);
  276.     }
  277. }
  278.