home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / graphic / csg_rt / col.c next >
C/C++ Source or Header  |  1993-01-12  |  24KB  |  978 lines

  1. /*
  2.  
  3. COL.C  Colour (within colour fields) code
  4.  
  5. */
  6.  
  7. /*...simprovements:0:*/
  8. /*
  9.  
  10.     INPUT    PRIMITIVE                PASSED DOWN
  11.  
  12.     _,_,_    col(a_rgb)
  13.     x,y,_    col_field2d(bx,by,"fn.bmp")
  14.     x,y,z    col_field3d(bx,by,bz,"fn.tex")
  15.  
  16.     x,y,z    col_interp0(a_col)            x(+1),y,z
  17.     x,y,z    col_interp1(a_col)            x,y(+1),z
  18.     x,y,z    col_interp2(a_col)            x,y,z(+1)
  19.  
  20.     x,y,z    col_remap(a_xyz_base,
  21.               a_xyz_v0,
  22.               a_xyz_v1,a_col)        x',y',z'
  23.     x,y,z    col_cyl(lond,rd,hd,a_col)        lon/lond,r/rd,z/hd
  24.     x,y,z    col_sph(lond,latd,rd,a_col)        lon/lond,lat/latd,r/rd
  25.     x,y,z    col_nomove(a_col)            x,y,z
  26.     a,b,c    col_mat2d(a00,a01,a10,a11)        a',b',c'
  27.     a,b,c    col_mat3d(a00,a01,a02,a10,...,a22)    a',b',c'
  28.  
  29. + origin to bitmaps
  30. + 3d texture files
  31. + optional interpolation
  32. + polar stuff isolated
  33. + more polar possibilities
  34. + no move with object
  35. - more complicated
  36. - huge matrices
  37. - more primitives
  38.  
  39. */
  40. /*...e*/
  41.  
  42. /*...sincludes:0:*/
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <stddef.h>
  46. #include <malloc.h>
  47. #include <memory.h>
  48. #include <math.h>
  49. #include "standard.h"
  50. #include "rt.h"
  51. #include "fio.h"
  52. #include "tex.h"
  53. #include "vector.h"
  54. #include "rgbvec.h"
  55.  
  56. /*...vrt\46\h:0:*/
  57. /*...vfio\46\h:0:*/
  58. /*...vtex\46\h:0:*/
  59. /*...vvector\46\h:0:*/
  60. /*...vrgbvec\46\h:0:*/
  61. /*...e*/
  62.  
  63. typedef byte CTYPE;
  64. #define    CTYPE_CONST    ((CTYPE) 0)
  65. #define    CTYPE_NO_MOVE    ((CTYPE) 1)
  66. #define    CTYPE_INTERP0    ((CTYPE) 2)
  67. #define    CTYPE_INTERP1    ((CTYPE) 3)
  68. #define    CTYPE_INTERP2    ((CTYPE) 4)
  69. #define    CTYPE_FIELD2D    ((CTYPE) 5)
  70. #define    CTYPE_FIELD3D    ((CTYPE) 6)
  71. #define    CTYPE_REMAP    ((CTYPE) 7)
  72. #define    CTYPE_CYLPOLAR    ((CTYPE) 8)
  73. #define    CTYPE_SPHPOLAR    ((CTYPE) 9)
  74. #define    CTYPE_MATRIX2D    ((CTYPE) 10)
  75. #define    CTYPE_MATRIX3D    ((CTYPE) 11)
  76.  
  77. typedef struct _COL COL;
  78.  
  79. typedef struct { int bx,by; BITMAP *bitmap; } FIELD2D;
  80. typedef struct { int bx,by,bz; TEX *tex; } FIELD3D;
  81. typedef struct { VECTOR base,v0,v1,v2; double inv_m [3][3]; COL *col; } REMAP;
  82. typedef struct { double lond,rd,hd; COL *col; } CYLPOLAR;
  83. typedef struct { double lond,latd,rd; COL *col; } SPHPOLAR;
  84. typedef struct { double m [2][2]; COL *col; } MATRIX2D;
  85. typedef struct { double m [3][3]; COL *col; } MATRIX3D;
  86.  
  87. typedef struct _COL
  88.     {
  89.     CTYPE ctype;
  90.     union
  91.         {
  92.         RGBVEC rgbvec;        /* _CONST */
  93.         COL *col;        /* _INTERP?D or _NO_MOVE */
  94.         FIELD2D field2d;    /* _FIELD2D */
  95.         FIELD3D field3d;    /* _FIELD3D */
  96.         REMAP remap;        /* _REMAP */
  97.         CYLPOLAR cylpolar;    /* _CYLPOLAR */
  98.         SPHPOLAR sphpolar;    /* _SPHPOLAR */
  99.         MATRIX2D matrix2d;    /* _MATRIX2D */
  100.         MATRIX3D matrix3d;    /* _MATRIX3D */
  101.         } u;
  102.     };
  103.  
  104. /*...smatrix_multiply:0:*/
  105. static void matrix_multiply(
  106.     double m1 [3][3], 
  107.     double m2 [3][3], 
  108.     double m  [3][3]
  109.     )
  110.     {
  111.     int    row, col;
  112.  
  113.     for ( row = 0; row < 3; row++ )
  114.         for ( col = 0; col < 3; col++ )
  115.             {
  116.             double    tot = 0.0;
  117.             int    i;
  118.  
  119.             for ( i = 0; i < 3; i++ )
  120.                 tot += m1 [row][i] * m2 [i][col];
  121.  
  122.             m [row][col] = tot;
  123.             }
  124.     }
  125. /*...e*/
  126. /*...sinvert_matrix:0:*/
  127. /*
  128.      -1     1          T
  129.     M   = ------ cof(M)
  130.           det(M)
  131. */
  132.  
  133. /*...scofactor:0:*/
  134. /*
  135. See Stephenson p277 for defn of a 'minor'.
  136. See Stephenson p307 for defn of a 'cofactor'.
  137. */
  138.  
  139. static double cofactor(int row, int col, double m [3][3])
  140.     {
  141.     static int lower [] = { 1, 0, 0 };
  142.     static int upper [] = { 2, 2, 1 };
  143.     int    lower_row = lower [row], upper_row = upper [row];
  144.     int    lower_col = lower [col], upper_col = upper [col];
  145.     double    minor = m [lower_row][lower_col] * m [upper_row][upper_col] -
  146.             m [lower_row][upper_col] * m [upper_row][lower_col];
  147.  
  148.     return ( ((row + col) & 1) ? -minor : minor );
  149.     }
  150. /*...e*/
  151.  
  152. static BOOLEAN invert_matrix(double m [3][3], double inv_m [3][3])
  153.     {
  154.     int    row, col;
  155.     double    det = 0.0;
  156.     double    cof_m [3][3];
  157.  
  158.     for ( col = 0; col < 3; col++ )
  159.         {
  160.         for ( row = 0; row < 3; row++ )
  161.             cof_m [row][col] = cofactor(row, col, m);
  162.         det += m [0][col] * cof_m [0][col];
  163.         }
  164.  
  165.     if ( det == 0.0 )
  166.         return ( FALSE );
  167.  
  168.     det = 1.0 / det;
  169.  
  170.     for ( col = 0; col < 3; col++ )
  171.         for ( row = 0; row < 3; row++ )
  172.             inv_m [col][row] = det * cof_m [row][col];
  173.  
  174.     return ( TRUE );
  175.     }
  176. /*...e*/
  177. /*...scompile_inv_m:0:*/
  178. static void compile_inv_m(REMAP *remap)
  179.     {
  180.     double m [3][3];
  181.     VECTOR v0, v1, v2;
  182.  
  183.     v0 = remap -> v0;
  184.     v1 = remap -> v1;
  185.     v2 = remap -> v2;
  186.  
  187.     m [0][0] = v0.x; m [0][1] = v1.x; m [0][2] = v2.x;
  188.     m [1][0] = v0.y; m [1][1] = v1.y; m [1][2] = v2.y;
  189.     m [2][0] = v0.z; m [2][1] = v1.z; m [2][2] = v2.z;
  190.  
  191.     invert_matrix(m, remap -> inv_m);
  192.     }
  193. /*...e*/
  194. /*...sdetermine_coeffs:0:*/
  195. /*
  196.  
  197. Point (p) = base (b) + multiples (c1,c2 and c3) of 3 vectors (v0, v1 and v2).
  198.  
  199.         /                \ /    \     /    \       /                \
  200.         | v0.x v1.x v2.x | | c1 |     | c1 |       | v0.x v1.x v2.x |
  201. p = b + | v0.y v1.y v2.y | | c2 | =>  | c2 | = inv | v0.y v1.y v2.y | ( p - b )
  202. ~   ~   | v0.z v1.z v2.z | | c3 |     | c3 |       | v0.z v1.z v2.z |   ~   ~
  203.         \                / \    /     \    /       \                /
  204.  
  205. The inverse matrix is kept ready computed in the remap structure.
  206.  
  207. */
  208.  
  209. static void determine_coeffs(
  210.     REMAP *remap,
  211.     VECTOR p,
  212.     double *c0, double *c1, double *c2
  213.     )
  214.     {
  215.     VECTOR pb;
  216.  
  217.     pb = vector_difference(p, remap -> base);
  218.     *c0 = remap -> inv_m [0][0] * pb.x +
  219.           remap -> inv_m [0][1] * pb.y +
  220.           remap -> inv_m [0][2] * pb.z;
  221.     *c1 = remap -> inv_m [1][0] * pb.x +
  222.           remap -> inv_m [1][1] * pb.y +
  223.           remap -> inv_m [1][2] * pb.z;
  224.     *c2 = remap -> inv_m [2][0] * pb.x +
  225.           remap -> inv_m [2][1] * pb.y +
  226.           remap -> inv_m [2][2] * pb.z;
  227.     }
  228. /*...e*/
  229.  
  230. /*...screate_const_col:0:*/
  231. COL *create_const_col(RGBVEC rgbvec)
  232.     {
  233.     COL *col;
  234.  
  235.     if ( (col = malloc(sizeof(COL))) == NULL )
  236.         return ( NULL );
  237.     col -> ctype    = CTYPE_CONST;
  238.     col -> u.rgbvec = rgbvec;
  239.     return ( col );
  240.     }
  241. /*...e*/
  242. /*...screate_chain_on_col:0:*/
  243. static COL *create_chain_on_col(CTYPE ctype, COL *col_chain_on)
  244.     {
  245.     COL *col;
  246.  
  247.     if ( (col = malloc(sizeof(COL))) == NULL )
  248.         return ( NULL );
  249.     col -> ctype = ctype;
  250.     col -> u.col = col_chain_on;
  251.     return ( col );
  252.     }
  253. /*...e*/
  254. /*...screate_no_move_col:0:*/
  255. COL *create_no_move_col(COL *col)
  256.     {
  257.     return ( create_chain_on_col(CTYPE_NO_MOVE, col) );
  258.     }
  259. /*...e*/
  260. /*...screate_interp0_col:0:*/
  261. COL *create_interp0_col(COL *col)
  262.     {
  263.     return ( create_chain_on_col(CTYPE_INTERP0, col) );
  264.     }
  265. /*...e*/
  266. /*...screate_interp1_col:0:*/
  267. COL *create_interp1_col(COL *col)
  268.     {
  269.     return ( create_chain_on_col(CTYPE_INTERP1, col) );
  270.     }
  271. /*...e*/
  272. /*...screate_interp2_col:0:*/
  273. COL *create_interp2_col(COL *col)
  274.     {
  275.     return ( create_chain_on_col(CTYPE_INTERP2, col) );
  276.     }
  277. /*...e*/
  278. /*...screate_2d_field_col:0:*/
  279. COL *create_2d_field_col(double bx, double by, BITMAP *bitmap)
  280.     {
  281.     COL *col;
  282.  
  283.     if ( (col = malloc(sizeof(COL))) == NULL )
  284.         return ( NULL );
  285.     col -> ctype            = CTYPE_FIELD2D;
  286.     col -> u.field2d.bx     = (int) bx;
  287.     col -> u.field2d.by     = (int) by;
  288.     col -> u.field2d.bitmap = bitmap;
  289.     return ( col );
  290.     }
  291. /*...e*/
  292. /*...screate_3d_field_col:0:*/
  293. COL *create_3d_field_col(double bx, double by, double bz, TEX *tex)
  294.     {
  295.     COL *col;
  296.  
  297.     if ( (col = malloc(sizeof(COL))) == NULL )
  298.         return ( NULL );
  299.     col -> ctype         = CTYPE_FIELD3D;
  300.     col -> u.field3d.bx  = (int) bx;
  301.     col -> u.field3d.by  = (int) by;
  302.     col -> u.field3d.bz  = (int) bz;
  303.     col -> u.field3d.tex = tex;
  304.     return ( col );
  305.     }
  306. /*...e*/
  307. /*...screate_remap_col:0:*/
  308. COL *create_remap_col(
  309.     VECTOR base,
  310.     VECTOR v0, VECTOR v1, VECTOR v2,
  311.     COL *col_chain_on
  312.     )
  313.     {
  314.     COL *col;
  315.  
  316.     if ( (col = malloc(sizeof(COL))) == NULL )
  317.         return ( NULL );
  318.     col -> ctype        = CTYPE_REMAP;
  319.     col -> u.remap.base = base;
  320.     col -> u.remap.v0   = v0;
  321.     col -> u.remap.v1   = v1;
  322.     col -> u.remap.v2   = v2;
  323.     col -> u.remap.col  = col_chain_on;
  324.     compile_inv_m(&(col -> u.remap));
  325.     return ( col );
  326.     }
  327. /*...e*/
  328. /*...screate_cyl_polar_col:0:*/
  329. COL *create_cyl_polar_col(double lond, double rd, double hd, COL *col_chain_on)
  330.     {
  331.     COL *col;
  332.  
  333.     if ( (col = malloc(sizeof(COL))) == NULL )
  334.         return ( NULL );
  335.     col -> ctype           = CTYPE_CYLPOLAR;
  336.     col -> u.cylpolar.lond = lond;
  337.     col -> u.cylpolar.rd   = rd;
  338.     col -> u.cylpolar.hd   = hd;
  339.     col -> u.cylpolar.col  = col_chain_on;
  340.     return ( col );
  341.     }
  342. /*...e*/
  343. /*...screate_sph_polar_col:0:*/
  344. COL *create_sph_polar_col(double lond, double latd, double rd, COL *col_chain_on)
  345.     {
  346.     COL *col;
  347.  
  348.     if ( (col = malloc(sizeof(COL))) == NULL )
  349.         return ( NULL );
  350.     col -> ctype           = CTYPE_SPHPOLAR;
  351.     col -> u.sphpolar.lond = lond;
  352.     col -> u.sphpolar.latd = latd;
  353.     col -> u.sphpolar.rd   = rd;
  354.     col -> u.sphpolar.col  = col_chain_on;
  355.     return ( col );
  356.     }
  357. /*...e*/
  358. /*...screate_2d_matrix_col:0:*/
  359. COL *create_2d_matrix_col(double m [2][2], COL *col_chain_on)
  360.     {
  361.     COL *col;
  362.  
  363.     if ( (col = malloc(sizeof(COL))) == NULL )
  364.         return ( NULL );
  365.     col -> ctype          = CTYPE_MATRIX2D;
  366.     memcpy(col -> u.matrix2d.m, m, sizeof(col -> u.matrix2d.m));
  367.     col -> u.matrix2d.col = col_chain_on;
  368.     return ( col );
  369.     }
  370. /*...e*/
  371. /*...screate_3d_matrix_col:0:*/
  372. COL *create_3d_matrix_col(double m [3][3], COL *col_chain_on)
  373.     {
  374.     COL *col;
  375.  
  376.     if ( (col = malloc(sizeof(COL))) == NULL )
  377.         return ( NULL );
  378.     col -> ctype          = CTYPE_MATRIX3D;
  379.     memcpy(col -> u.matrix3d.m, m, sizeof(col -> u.matrix3d.m));
  380.     col -> u.matrix3d.col = col_chain_on;
  381.     return ( col );
  382.     }
  383. /*...e*/
  384.  
  385. /*...scopy_col:0:*/
  386. COL *copy_col(COL *col)
  387.     {
  388.     COL *copy;
  389.  
  390.     if ( (copy = malloc(sizeof(COL))) == NULL )
  391.         return ( NULL );
  392.  
  393.     copy -> ctype = col -> ctype;
  394.     switch ( col -> ctype )
  395.         {
  396.         case CTYPE_CONST:
  397.             copy -> u.rgbvec = col -> u.rgbvec;
  398.             break;
  399.         case CTYPE_NO_MOVE:
  400.         case CTYPE_INTERP0:
  401.         case CTYPE_INTERP1:
  402.         case CTYPE_INTERP2:
  403.             if ( (copy -> u.col = copy_col(col -> u.col)) == NULL )
  404.                 {
  405.                 free(col);
  406.                 return ( NULL );
  407.                 }
  408.             break;
  409.         case CTYPE_FIELD2D:
  410.             copy -> u.field2d.bx = col -> u.field2d.bx;
  411.             copy -> u.field2d.by = col -> u.field2d.by;
  412.             if ( (copy -> u.field2d.bitmap = fio_copy_bitmap(col -> u.field2d.bitmap)) == NULL )
  413.                 {
  414.                 free(col);
  415.                 return ( NULL );
  416.                 }
  417.             break;
  418.         case CTYPE_FIELD3D:
  419.             copy -> u.field3d.bx = col -> u.field3d.bx;
  420.             copy -> u.field3d.by = col -> u.field3d.by;
  421.             copy -> u.field3d.bz = col -> u.field3d.bz;
  422.             if ( (copy -> u.field3d.tex = copy_tex(col -> u.field3d.tex)) == NULL )
  423.                 {
  424.                 free(col);
  425.                 return ( NULL );
  426.                 }
  427.             break;
  428.         case CTYPE_REMAP:
  429.             copy -> u.remap = col -> u.remap;
  430.             if ( (copy -> u.remap.col = copy_col(col -> u.remap.col)) == NULL )
  431.                 {
  432.                 free(col);
  433.                 return ( NULL );
  434.                 }
  435.             break;
  436.         case CTYPE_SPHPOLAR:
  437.             copy -> u.sphpolar = col -> u.sphpolar;
  438.             if ( (copy -> u.sphpolar.col = copy_col(col -> u.sphpolar.col)) == NULL )
  439.                 {
  440.                 free(col);
  441.                 return ( NULL );
  442.                 }
  443.             break;
  444.         case CTYPE_CYLPOLAR:
  445.             copy -> u.cylpolar = col -> u.cylpolar;
  446.             if ( (copy -> u.cylpolar.col = copy_col(col -> u.cylpolar.col)) == NULL )
  447.                 {
  448.                 free(col);
  449.                 return ( NULL );
  450.                 }
  451.             break;
  452.         case CTYPE_MATRIX2D:
  453.             copy -> u.matrix2d = col -> u.matrix2d;
  454.             if ( (copy -> u.matrix2d.col = copy_col(col -> u.matrix2d.col)) == NULL )
  455.                 {
  456.                 free(col);
  457.                 return ( NULL );
  458.                 }
  459.             break;
  460.         case CTYPE_MATRIX3D:
  461.             copy -> u.matrix3d = col -> u.matrix3d;
  462.             if ( (copy -> u.matrix3d.col = copy_col(col -> u.matrix3d.col)) == NULL )
  463.                 {
  464.                 free(col);
  465.                 return ( NULL );
  466.                 }
  467.             break;
  468.         }
  469.  
  470.     return ( copy );
  471.     }
  472. /*...e*/
  473. /*...sdestroy_col:0:*/
  474. void destroy_col(COL *col)
  475.     {
  476.     switch ( col -> ctype )
  477.         {
  478.         case CTYPE_NO_MOVE:
  479.         case CTYPE_INTERP0:
  480.         case CTYPE_INTERP1:
  481.         case CTYPE_INTERP2:
  482.             destroy_col(col -> u.col);
  483.             break;
  484.         case CTYPE_FIELD2D:
  485.             fio_destroy_bitmap(col -> u.field2d.bitmap);
  486.             break;
  487.         case CTYPE_FIELD3D:
  488.             destroy_tex(col -> u.field3d.tex);
  489.             break;
  490.         case CTYPE_REMAP:
  491.             destroy_col(col -> u.remap.col);
  492.             break;
  493.         case CTYPE_SPHPOLAR:
  494.             destroy_col(col -> u.sphpolar.col);
  495.             break;
  496.         case CTYPE_CYLPOLAR:
  497.             destroy_col(col -> u.cylpolar.col);
  498.             break;
  499.         case CTYPE_MATRIX2D:
  500.             destroy_col(col -> u.matrix2d.col);
  501.             break;
  502.         case CTYPE_MATRIX3D:
  503.             destroy_col(col -> u.matrix3d.col);
  504.             break;
  505.         }
  506.     free(col);
  507.     }
  508. /*...e*/
  509.  
  510. /*...strans_x_col:0:*/
  511. void trans_x_col(COL *col, double t)
  512.     {
  513.     switch ( col -> ctype )
  514.         {
  515.         case CTYPE_INTERP0:
  516.         case CTYPE_INTERP1:
  517.         case CTYPE_INTERP2:
  518.             trans_x_col(col -> u.col, t);
  519.             break;
  520.         case CTYPE_REMAP:
  521.             col -> u.remap.base.x += t;
  522.             break;
  523.         case CTYPE_SPHPOLAR:
  524.             trans_x_col(col -> u.sphpolar.col, t);
  525.             break;
  526.         case CTYPE_CYLPOLAR:
  527.             trans_x_col(col -> u.cylpolar.col, t);
  528.             break;
  529.         case CTYPE_MATRIX2D:
  530.             trans_x_col(col -> u.matrix2d.col, t);
  531.             break;
  532.         case CTYPE_MATRIX3D:
  533.             trans_x_col(col -> u.matrix3d.col, t);
  534.             break;
  535.         }
  536.     }
  537. /*...e*/
  538. /*...strans_y_col:0:*/
  539. void trans_y_col(COL *col, double t)
  540.     {
  541.     switch ( col -> ctype )
  542.         {
  543.         case CTYPE_INTERP0:
  544.         case CTYPE_INTERP1:
  545.         case CTYPE_INTERP2:
  546.             trans_y_col(col -> u.col, t);
  547.             break;
  548.         case CTYPE_REMAP:
  549.             col -> u.remap.base.y += t;
  550.             break;
  551.         case CTYPE_SPHPOLAR:
  552.             trans_y_col(col -> u.sphpolar.col, t);
  553.             break;
  554.         case CTYPE_CYLPOLAR:
  555.             trans_y_col(col -> u.cylpolar.col, t);
  556.             break;
  557.         case CTYPE_MATRIX2D:
  558.             trans_y_col(col -> u.matrix2d.col, t);
  559.             break;
  560.         case CTYPE_MATRIX3D:
  561.             trans_y_col(col -> u.matrix3d.col, t);
  562.             break;
  563.         }
  564.     }
  565. /*...e*/
  566. /*...strans_z_col:0:*/
  567. void trans_z_col(COL *col, double t)
  568.     {
  569.     switch ( col -> ctype )
  570.         {
  571.         case CTYPE_INTERP0:
  572.         case CTYPE_INTERP1:
  573.         case CTYPE_INTERP2:
  574.             trans_z_col(col -> u.col, t);
  575.             break;
  576.         case CTYPE_REMAP:
  577.             col -> u.remap.base.z += t;
  578.             break;
  579.         case CTYPE_SPHPOLAR:
  580.             trans_z_col(col -> u.sphpolar.col, t);
  581.             break;
  582.         case CTYPE_CYLPOLAR:
  583.             trans_z_col(col -> u.cylpolar.col, t);
  584.             break;
  585.         case CTYPE_MATRIX2D:
  586.             trans_z_col(col -> u.matrix2d.col, t);
  587.             break;
  588.         case CTYPE_MATRIX3D:
  589.             trans_z_col(col -> u.matrix3d.col, t);
  590.             break;
  591.         }
  592.     }
  593. /*...e*/
  594. /*...sscale_x_col:0:*/
  595. /*
  596. How to scale a colour is quite tricky to define.
  597. If a bitmap is mapped onto a surface of a shape, then if the shape expands,
  598. then we would expect the bitmap to 'expand' to cover the new shape.
  599. To do this we enlarge the basis vectors for a CTYPE_REMAP.
  600. Remapping between coordinate systems and general matrix manipulation of
  601. parameters p0,p1 and p2 remain untouched for now.
  602. */
  603.  
  604. void scale_x_col(COL *col, double factor)
  605.     {
  606.     switch ( col -> ctype )
  607.         {
  608.         case CTYPE_INTERP0:
  609.         case CTYPE_INTERP1:
  610.         case CTYPE_INTERP2:
  611.             scale_x_col(col -> u.col, factor);
  612.             break;
  613.         case CTYPE_REMAP:
  614.             {
  615.             REMAP    *remap = &(col -> u.remap);
  616.  
  617.             remap -> base.x *= factor;
  618.             remap -> v0.x   *= factor;
  619.             remap -> v1.x   *= factor;
  620.             remap -> v2.x   *= factor;
  621.             compile_inv_m(remap);
  622.             }
  623.             break;
  624.         case CTYPE_SPHPOLAR:
  625.             scale_x_col(col -> u.sphpolar.col, factor);
  626.             break;
  627.         case CTYPE_CYLPOLAR:
  628.             scale_x_col(col -> u.cylpolar.col, factor);
  629.             break;
  630.         case CTYPE_MATRIX2D:
  631.             scale_x_col(col -> u.matrix2d.col, factor);
  632.             break;
  633.         case CTYPE_MATRIX3D:
  634.             scale_x_col(col -> u.matrix3d.col, factor);
  635.             break;
  636.         }
  637.     }
  638. /*...e*/
  639. /*...sscale_y_col:0:*/
  640. void scale_y_col(COL *col, double factor)
  641.     {
  642.     switch ( col -> ctype )
  643.         {
  644.         case CTYPE_INTERP0:
  645.         case CTYPE_INTERP1:
  646.         case CTYPE_INTERP2:
  647.             scale_y_col(col -> u.col, factor);
  648.             break;
  649.         case CTYPE_REMAP:
  650.             {
  651.             REMAP    *remap = &(col -> u.remap);
  652.  
  653.             remap -> base.y *= factor;
  654.             remap -> v0.y   *= factor;
  655.             remap -> v1.y   *= factor;
  656.             remap -> v2.y   *= factor;
  657.             compile_inv_m(remap);
  658.             }
  659.             break;
  660.         case CTYPE_SPHPOLAR:
  661.             scale_y_col(col -> u.sphpolar.col, factor);
  662.             break;
  663.         case CTYPE_CYLPOLAR:
  664.             scale_y_col(col -> u.cylpolar.col, factor);
  665.             break;
  666.         case CTYPE_MATRIX2D:
  667.             scale_y_col(col -> u.matrix2d.col, factor);
  668.             break;
  669.         case CTYPE_MATRIX3D:
  670.             scale_y_col(col -> u.matrix3d.col, factor);
  671.             break;
  672.         }
  673.     }
  674. /*...e*/
  675. /*...sscale_z_col:0:*/
  676. void scale_z_col(COL *col, double factor)
  677.     {
  678.     switch ( col -> ctype )
  679.         {
  680.         case CTYPE_INTERP0:
  681.         case CTYPE_INTERP1:
  682.         case CTYPE_INTERP2:
  683.             scale_z_col(col -> u.col, factor);
  684.             break;
  685.         case CTYPE_REMAP:
  686.             {
  687.             REMAP    *remap = &(col -> u.remap);
  688.  
  689.             remap -> base.z *= factor;
  690.             remap -> v0.z   *= factor;
  691.             remap -> v1.z   *= factor;
  692.             remap -> v2.z   *= factor;
  693.             compile_inv_m(remap);
  694.             }
  695.             break;
  696.         case CTYPE_SPHPOLAR:
  697.             scale_z_col(col -> u.sphpolar.col, factor);
  698.             break;
  699.         case CTYPE_CYLPOLAR:
  700.             scale_z_col(col -> u.cylpolar.col, factor);
  701.             break;
  702.         case CTYPE_MATRIX2D:
  703.             scale_z_col(col -> u.matrix2d.col, factor);
  704.             break;
  705.         case CTYPE_MATRIX3D:
  706.             scale_z_col(col -> u.matrix3d.col, factor);
  707.             break;
  708.         }
  709.     }
  710. /*...e*/
  711. /*...srot_x_col:0:*/
  712. void rot_x_col(COL *col, double angle)
  713.     {
  714.     switch ( col -> ctype )
  715.         {
  716.         case CTYPE_INTERP0:
  717.         case CTYPE_INTERP1:
  718.         case CTYPE_INTERP2:
  719.             rot_x_col(col -> u.col, angle);
  720.             break;
  721.         case CTYPE_REMAP:
  722.             {
  723.             REMAP    *remap = &(col -> u.remap);
  724.  
  725.             remap -> base = rot_x_vector(remap -> base, angle);
  726.             remap -> v0   = rot_x_vector(remap -> v0  , angle);
  727.             remap -> v1   = rot_x_vector(remap -> v1  , angle);
  728.             remap -> v2   = rot_x_vector(remap -> v2  , angle);
  729.             compile_inv_m(remap);
  730.             }
  731.             break;
  732.         case CTYPE_SPHPOLAR:
  733.             rot_x_col(col -> u.sphpolar.col, angle);
  734.             break;
  735.         case CTYPE_CYLPOLAR:
  736.             rot_x_col(col -> u.cylpolar.col, angle);
  737.             break;
  738.         case CTYPE_MATRIX2D:
  739.             rot_x_col(col -> u.matrix2d.col, angle);
  740.             break;
  741.         case CTYPE_MATRIX3D:
  742.             rot_x_col(col -> u.matrix3d.col, angle);
  743.             break;
  744.         }
  745.     }
  746. /*...e*/
  747. /*...srot_y_col:0:*/
  748. void rot_y_col(COL *col, double angle)
  749.     {
  750.     switch ( col -> ctype )
  751.         {
  752.         case CTYPE_INTERP0:
  753.         case CTYPE_INTERP1:
  754.         case CTYPE_INTERP2:
  755.             rot_y_col(col -> u.col, angle);
  756.             break;
  757.         case CTYPE_REMAP:
  758.             {
  759.             REMAP    *remap = &(col -> u.remap);
  760.  
  761.             remap -> base = rot_y_vector(remap -> base, angle);
  762.             remap -> v0   = rot_y_vector(remap -> v0  , angle);
  763.             remap -> v1   = rot_y_vector(remap -> v1  , angle);
  764.             remap -> v2   = rot_y_vector(remap -> v2  , angle);
  765.             compile_inv_m(remap);
  766.             }
  767.             break;
  768.         case CTYPE_SPHPOLAR:
  769.             rot_y_col(col -> u.sphpolar.col, angle);
  770.             break;
  771.         case CTYPE_CYLPOLAR:
  772.             rot_y_col(col -> u.cylpolar.col, angle);
  773.             break;
  774.         case CTYPE_MATRIX2D:
  775.             rot_y_col(col -> u.matrix2d.col, angle);
  776.             break;
  777.         case CTYPE_MATRIX3D:
  778.             rot_y_col(col -> u.matrix3d.col, angle);
  779.             break;
  780.         }
  781.     }
  782. /*...e*/
  783. /*...srot_z_col:0:*/
  784. void rot_z_col(COL *col, double angle)
  785.     {
  786.     switch ( col -> ctype )
  787.         {
  788.         case CTYPE_INTERP0:
  789.         case CTYPE_INTERP1:
  790.         case CTYPE_INTERP2:
  791.             rot_z_col(col -> u.col, angle);
  792.             break;
  793.         case CTYPE_REMAP:
  794.             {
  795.             REMAP    *remap = &(col -> u.remap);
  796.  
  797.             remap -> base = rot_z_vector(remap -> base, angle);
  798.             remap -> v0   = rot_z_vector(remap -> v0  , angle);
  799.             remap -> v1   = rot_z_vector(remap -> v1  , angle);
  800.             remap -> v2   = rot_z_vector(remap -> v2  , angle);
  801.             compile_inv_m(remap);
  802.             }
  803.             break;
  804.         case CTYPE_SPHPOLAR:
  805.             rot_z_col(col -> u.sphpolar.col, angle);
  806.             break;
  807.         case CTYPE_CYLPOLAR:
  808.             rot_z_col(col -> u.cylpolar.col, angle);
  809.             break;
  810.         case CTYPE_MATRIX2D:
  811.             rot_z_col(col -> u.matrix2d.col, angle);
  812.             break;
  813.         case CTYPE_MATRIX3D:
  814.             rot_z_col(col -> u.matrix3d.col, angle);
  815.             break;
  816.         }
  817.     }
  818. /*...e*/
  819.  
  820. /*...sevaluate_col:0:*/
  821. /*...spos_fmod:0:*/
  822. static double pos_fmod(double num, double denom)
  823.     {
  824.     if ( num >= 0.0 )
  825.         return ( fmod(num, denom) );
  826.     else
  827.         return ( denom + fmod(num, denom) );
  828.     }
  829. /*...e*/
  830.  
  831. RGBVEC evaluate_col(COL *col, double p0, double p1, double p2)
  832.     {
  833.     static RGBVEC dummy_rgbvec = { 0.0, 0.0, 0.0 };
  834.  
  835.     switch ( col -> ctype )
  836.         {
  837. /*...sCTYPE_CONST:16:*/
  838. case CTYPE_CONST:
  839.     return ( col -> u.rgbvec );
  840. /*...e*/
  841. /*...sCTYPE_NO_MOVE:16:*/
  842. case CTYPE_NO_MOVE:
  843.     return ( evaluate_col(col -> u.col, p0, p1, p2) );
  844. /*...e*/
  845. /*...sCTYPE_INTERP0:16:*/
  846. case CTYPE_INTERP0:
  847.     {
  848.     double fp0 = floor(p0);
  849.     RGBVEC r [2];
  850.     r [0] = evaluate_col(col -> u.col, fp0      , p1, p2);
  851.     r [1] = evaluate_col(col -> u.col, fp0 + 1.0, p1, p2);
  852.     return ( rgbvec_interp_1d(r, pos_fmod(p0, 1.0)) );
  853.     }
  854. /*...e*/
  855. /*...sCTYPE_INTERP1:16:*/
  856. case CTYPE_INTERP1:
  857.     {
  858.     double fp1 = floor(p1);
  859.     RGBVEC r [2];
  860.     r [0] = evaluate_col(col -> u.col, p0, fp1      , p2);
  861.     r [1] = evaluate_col(col -> u.col, p0, fp1 + 1.0, p2);
  862.     return ( rgbvec_interp_1d(r, pos_fmod(p1, 1.0)) );
  863.     }
  864. /*...e*/
  865. /*...sCTYPE_INTERP2:16:*/
  866. case CTYPE_INTERP2:
  867.     {
  868.     double fp2 = floor(p2);
  869.     RGBVEC r [2];
  870.     r [0] = evaluate_col(col -> u.col, p0, p1, fp2      );
  871.     r [1] = evaluate_col(col -> u.col, p0, p1, fp2 + 1.0);
  872.     return ( rgbvec_interp_1d(r, pos_fmod(p2, 1.0)) );
  873.     }
  874. /*...e*/
  875. /*...sCTYPE_FIELD2D:16:*/
  876. case CTYPE_FIELD2D:
  877.     {
  878.     BITMAP *bitmap = col -> u.field2d.bitmap;
  879.     int w = fio_width(bitmap);
  880.     int h = fio_height(bitmap);
  881.     int x = (int) pos_fmod(p0 + col -> u.field2d.bx, (double) w);
  882.     int y = (int) pos_fmod(p1 + col -> u.field2d.by, (double) h);
  883.     byte r, g, b;
  884.     RGBVEC rgbvec;
  885.  
  886.     fio_get_pixel(bitmap, x, y, &r, &g, &b);
  887.     rgbvec.b = ((double) b) / 255.0;
  888.     rgbvec.g = ((double) g) / 255.0;
  889.     rgbvec.r = ((double) r) / 255.0;
  890.     return ( rgbvec );
  891.     }
  892. /*...e*/
  893. /*...sCTYPE_FIELD3D:16:*/
  894. case CTYPE_FIELD3D:
  895.     {
  896.     TEX *tex = col -> u.field3d.tex;
  897.     int w = width_tex(tex);
  898.     int h = height_tex(tex);
  899.     int d = depth_tex(tex);
  900.     int x = (int) pos_fmod(p0 + col -> u.field3d.bx, (double) w);
  901.     int y = (int) pos_fmod(p1 + col -> u.field3d.by, (double) h);
  902.     int z = (int) pos_fmod(p2 + col -> u.field3d.bz, (double) d);
  903.     byte r, g, b;
  904.     RGBVEC rgbvec;
  905.  
  906.     get_voxel_tex(tex, x, y, z, &r, &g, &b);
  907.     rgbvec.b = ((double) b) / 255.0;
  908.     rgbvec.g = ((double) g) / 255.0;
  909.     rgbvec.r = ((double) r) / 255.0;
  910.     return ( rgbvec );
  911.     }
  912. /*...e*/
  913. /*...sCTYPE_REMAP:16:*/
  914. case CTYPE_REMAP:
  915.     {
  916.     VECTOR p;
  917.     double c0, c1, c2;
  918.  
  919.     p.x = p0;
  920.     p.y = p1;
  921.     p.z = p2;
  922.     determine_coeffs(&col -> u.remap, p, &c0, &c1, &c2);
  923.  
  924.     return ( evaluate_col(col -> u.remap.col, c0, c1, c2) );
  925.     }
  926. /*...e*/
  927. /*...sCTYPE_SPHPOLAR:16:*/
  928. case CTYPE_SPHPOLAR:
  929.     {
  930.     double lon = atan2(p1, p0);
  931.     double p01 = p0 * p0 + p1 * p1;
  932.     double lat = atan2(p2, sqrt(p01));
  933.     double p012 = p01 + p2 * p2;
  934.  
  935.     return ( evaluate_col(col -> u.sphpolar.col,
  936.                   lon        / col -> u.sphpolar.lond,
  937.                   lat        / col -> u.sphpolar.latd,
  938.                   sqrt(p012) / col -> u.sphpolar.rd) );
  939.     }
  940. /*...e*/
  941. /*...sCTYPE_CYLPOLAR:16:*/
  942. case CTYPE_CYLPOLAR:
  943.     {
  944.     double lon = atan2(p1, p0);
  945.     double p01 = p0 * p0 + p1 * p1;
  946.  
  947.     return ( evaluate_col(col -> u.cylpolar.col,
  948.                   lon       / col -> u.cylpolar.lond,
  949.                   sqrt(p01) / col -> u.cylpolar.rd  ,
  950.                   p2        / col -> u.cylpolar.hd  ) );
  951.     }
  952. /*...e*/
  953. /*...sCTYPE_MATRIX2D:16:*/
  954. case CTYPE_MATRIX2D:
  955.     {
  956.     double (*m)[2] = col -> u.matrix2d.m;
  957.     double q0 = m [0][0] * p0 + m [0][1] * p1;
  958.     double q1 = m [1][0] * p0 + m [1][1] * p1;
  959.  
  960.     return ( evaluate_col(col -> u.matrix2d.col, q0, q1, p2) );
  961.     }
  962. /*...e*/
  963. /*...sCTYPE_MATRIX3D:16:*/
  964. case CTYPE_MATRIX3D:
  965.     {
  966.     double (*m)[3] = col -> u.matrix3d.m;
  967.     double q0 = m [0][0] * p0 + m [0][1] * p1 + m [0][2] * p2;
  968.     double q1 = m [1][0] * p0 + m [1][1] * p1 + m [1][2] * p2;
  969.     double q2 = m [2][0] * p0 + m [2][1] * p1 + m [2][2] * p2;
  970.  
  971.     return ( evaluate_col(col -> u.matrix3d.col, q0, q1, q2) );
  972.     }
  973. /*...e*/
  974.         }
  975.     return ( dummy_rgbvec ); /* Please fussy C compiler */
  976.     }
  977. /*...e*/
  978.