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