home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / macraysh.sit / Code / Source / transform.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-23  |  10.6 KB  |  435 lines

  1. /*
  2.  * transform.c
  3.  *
  4.  * Copyright (C) 1989, 1991, Craig E. Kolb
  5.  * All rights reserved.
  6.  *
  7.  * This software may be freely copied, modified, and redistributed
  8.  * provided that this copyright notice is preserved on all copies.
  9.  *
  10.  * You may not distribute this software, in whole or in part, as part of
  11.  * any commercial product without the express consent of the authors.
  12.  *
  13.  * There is no warranty or other guarantee of fitness of this software
  14.  * for any purpose.  It is provided solely "as is".
  15.  *
  16.  * $Id: transform.c,v 4.0 91/07/17 14:32:25 kolb Exp Locker: kolb $
  17.  *
  18.  * $Log:    transform.c,v $
  19.  * Revision 4.0  91/07/17  14:32:25  kolb
  20.  * Initial version.
  21.  * 
  22.  */
  23. #include "common.h"
  24.  
  25. /*
  26.  * Matrices are indexed row-first; that is:
  27.  * matrix[ROW][COLUMN]
  28.  */
  29. /*
  30.  * Allocate new structure that holds both object-to-world and
  31.  * world-to-object space transformation structures.  It probably
  32.  * should hold pointers to these structures.
  33.  */
  34. Trans *
  35. TransCreate(tr, meth)
  36. TransRef tr;
  37. TransMethods *meth;
  38. {
  39.     Trans *res;
  40.  
  41.     res = (Trans *)share_malloc(sizeof(Trans));
  42.     res->tr = tr;
  43.     res->methods = meth;
  44.     res->animated = FALSE;
  45.     res->assoc = (ExprAssoc *)NULL;
  46.     res->prev = res->next = (Trans *)NULL;
  47.     MatrixInit(&res->trans);
  48.     MatrixInit(&res->itrans);
  49.     return res;
  50. }
  51.  
  52. void
  53. TransFree(trans)
  54. Trans *trans;
  55. {
  56.     if (trans->tr)
  57.         Free((voidstar)trans->tr);
  58.     Free((voidstar)trans);
  59. }
  60.  
  61. void
  62. TransAssoc(trans, ptr, expr)
  63. Trans *trans;
  64. Float *ptr;
  65. Expr *expr;
  66. {
  67.     ExprAssoc *assoc;
  68.  
  69.     if (expr->timevary) {
  70.         /*
  71.          * Gotta store the sucker.
  72.          */
  73.         trans->assoc = AssocCreate(ptr, expr, trans->assoc);
  74.         trans->animated = TRUE;
  75.     } else {
  76.         *ptr = expr->value;
  77.     }
  78.     fflush(stderr);
  79. }
  80.  
  81. /*
  82.  * Allocate new transformation 'matrix'.
  83.  */
  84. RSMatrix *
  85. MatrixCreate()
  86. {
  87.     RSMatrix *res;
  88.  
  89.     res = (RSMatrix *)share_malloc(sizeof(RSMatrix));
  90.     MatrixInit(res);
  91.     return res;
  92. }
  93.  
  94. /*
  95.  * Multiply m1 and m2, copy result into "res".
  96.  */
  97. void
  98. MatrixMult(t1, t2, res)
  99. RSMatrix *t1, *t2, *res;
  100. {
  101.     register int i;
  102.     RSMatrix tmp;
  103.  
  104.     for (i = 0; i < 3; i++) {
  105.         tmp.matrix[i][0] = t1->matrix[i][0] * t2->matrix[0][0] +
  106.                      t1->matrix[i][1] * t2->matrix[1][0] +
  107.                      t1->matrix[i][2] * t2->matrix[2][0];
  108.         tmp.matrix[i][1] = t1->matrix[i][0] * t2->matrix[0][1] +
  109.                      t1->matrix[i][1] * t2->matrix[1][1] +
  110.                      t1->matrix[i][2] * t2->matrix[2][1];
  111.         tmp.matrix[i][2] = t1->matrix[i][0] * t2->matrix[0][2] +
  112.                      t1->matrix[i][1] * t2->matrix[1][2] +
  113.                      t1->matrix[i][2] * t2->matrix[2][2];
  114.     }
  115.  
  116.     tmp.translate.x = t1->translate.x * t2->matrix[0][0] +
  117.               t1->translate.y * t2->matrix[1][0] +
  118.               t1->translate.z * t2->matrix[2][0] + t2->translate.x;
  119.     tmp.translate.y = t1->translate.x * t2->matrix[0][1] +
  120.               t1->translate.y * t2->matrix[1][1] +
  121.               t1->translate.z * t2->matrix[2][1] + t2->translate.y;
  122.     tmp.translate.z = t1->translate.x * t2->matrix[0][2] +
  123.               t1->translate.y * t2->matrix[1][2] +
  124.               t1->translate.z * t2->matrix[2][2] + t2->translate.z;
  125.     MatrixCopy(&tmp, res);
  126. }
  127.  
  128. /*
  129.  * Return transformation information to map the "coordinate system"
  130.  * with the given origin, "up" vector, radius, and up axis lengths to
  131.  * one in which the "up" vector is the Z axis and the x/y/up axes
  132.  * have unit length.  This is useful for transforming a general
  133.  * form of a primitive into a canonical, Z-axis aligned, unit size
  134.  * primitive, facilitating intersection testing.
  135.  * Assumes that "up" is normalized.
  136.  */
  137. void
  138. CoordSysTransform(origin, up, r, len, trans)
  139. Vector *origin, *up;
  140. Float r, len;
  141. Trans *trans;
  142. {
  143.       RSMatrix tmp;
  144.       Vector atmp;
  145.  
  146.       ScaleMatrix(r, r, len, &trans->trans);
  147.       if (1. - fabs(up->z) < EPSILON) {
  148.               atmp.x = 1.;
  149.               atmp.y = atmp.z = 0.;
  150.       } else {
  151.               atmp.x = up->y;
  152.               atmp.y = -up->x;
  153.               atmp.z= 0.;
  154.       }
  155.       /*
  156.        * Might want to make sure that |up->z| is < 1.
  157.        */
  158.       RotationMatrix(atmp.x, atmp.y, atmp.z, -acos(up->z), &tmp);
  159.       MatrixMult(&trans->trans, &tmp, &trans->trans);
  160.       TranslationMatrix(origin->x, origin->y, origin->z, &tmp);
  161.       MatrixMult(&trans->trans, &tmp, &trans->trans);
  162.       MatrixInvert(&trans->trans, &trans->itrans);
  163. }
  164.  
  165. void
  166. TransCopy(from, into)
  167. Trans *into, *from;
  168. {
  169.     MatrixCopy(&from->trans, &into->trans);
  170.     MatrixCopy(&from->itrans, &into->itrans);
  171. }
  172.  
  173. void
  174. TransInvert(from, into)
  175. Trans *into, *from;
  176. {
  177.     RSMatrix ttmp;
  178.     /*
  179.      * In case into == from...
  180.      */
  181.     if (from == into) {
  182.         ttmp = from->trans;
  183.         into->trans = from->itrans;
  184.         into->itrans = ttmp;
  185.     } else {
  186.         into->trans = from->itrans;
  187.         into->itrans = from->trans;
  188.     }
  189. }
  190.  
  191. /*
  192.  * Copy a given transformation structure.
  193.  */
  194. void
  195. MatrixCopy(from, into)
  196. RSMatrix *into, *from;
  197. {
  198.     into->matrix[0][0] = from->matrix[0][0];
  199.     into->matrix[0][1] = from->matrix[0][1];
  200.     into->matrix[0][2] = from->matrix[0][2];
  201.     into->matrix[1][0] = from->matrix[1][0];
  202.     into->matrix[1][1] = from->matrix[1][1];
  203.     into->matrix[1][2] = from->matrix[1][2];
  204.     into->matrix[2][0] = from->matrix[2][0];
  205.     into->matrix[2][1] = from->matrix[2][1];
  206.     into->matrix[2][2] = from->matrix[2][2];
  207.     into->translate = from->translate;
  208. }
  209.  
  210. void
  211. TransInit(trans)
  212. Trans *trans;
  213. {
  214.     MatrixInit(&trans->trans);
  215.     MatrixInit(&trans->itrans);
  216. }
  217.  
  218. void
  219. TransCompose(t1, t2, res)
  220. Trans *t1, *t2, *res;
  221. {
  222.     MatrixMult(&t1->trans, &t2->trans, &res->trans);
  223.     MatrixMult(&t2->itrans, &t1->itrans, &res->itrans);
  224. }
  225.  
  226. /*
  227.  * Initialize transformation structure.
  228.  */
  229. void
  230. MatrixInit(trans)
  231. RSMatrix *trans;
  232. {
  233.     trans->matrix[0][0] = trans->matrix[1][1] = trans->matrix[2][2] = 1.;
  234.     trans->matrix[0][1] = trans->matrix[0][2] = trans->matrix[1][0] =
  235.     trans->matrix[1][2] = trans->matrix[2][0] = trans->matrix[2][1] = 0.;
  236.     trans->translate.x = trans->translate.y = trans->translate.z = 0.;
  237. }
  238.  
  239. /*
  240.  * Calculate inverse of the given transformation structure.
  241.  */
  242. void
  243. MatrixInvert(trans, inverse)
  244. RSMatrix *inverse, *trans;
  245. {
  246.     RSMatrix ttmp;
  247.     int i;
  248.     Float d;
  249.     extern int yylineno;
  250.  
  251.     ttmp.matrix[0][0] = trans->matrix[1][1]*trans->matrix[2][2] -
  252.                 trans->matrix[1][2]*trans->matrix[2][1];
  253.     ttmp.matrix[1][0] = trans->matrix[1][0]*trans->matrix[2][2] -
  254.                 trans->matrix[1][2]*trans->matrix[2][0];
  255.     ttmp.matrix[2][0] = trans->matrix[1][0]*trans->matrix[2][1] -
  256.                 trans->matrix[1][1]*trans->matrix[2][0];
  257.  
  258.     ttmp.matrix[0][1] = trans->matrix[0][1]*trans->matrix[2][2] -
  259.                 trans->matrix[0][2]*trans->matrix[2][1];
  260.     ttmp.matrix[1][1] = trans->matrix[0][0]*trans->matrix[2][2] -
  261.                 trans->matrix[0][2]*trans->matrix[2][0];
  262.     ttmp.matrix[2][1] = trans->matrix[0][0]*trans->matrix[2][1] -
  263.                 trans->matrix[0][1]*trans->matrix[2][0];
  264.  
  265.     ttmp.matrix[0][2] = trans->matrix[0][1]*trans->matrix[1][2] -
  266.                 trans->matrix[0][2]*trans->matrix[1][1];
  267.     ttmp.matrix[1][2] = trans->matrix[0][0]*trans->matrix[1][2] -
  268.                 trans->matrix[0][2]*trans->matrix[1][0];
  269.     ttmp.matrix[2][2] = trans->matrix[0][0]*trans->matrix[1][1] -
  270.                 trans->matrix[0][1]*trans->matrix[1][0];
  271.  
  272.     d = trans->matrix[0][0]*ttmp.matrix[0][0] -
  273.         trans->matrix[0][1]*ttmp.matrix[1][0] +
  274.         trans->matrix[0][2]*ttmp.matrix[2][0];
  275.  
  276.     if (fabs(d) < EPSILON*EPSILON)
  277.         RLerror(RL_PANIC, "Singular matrix.\n",(char *)yylineno,0,0);
  278.  
  279.     ttmp.matrix[0][0] /= d;
  280.     ttmp.matrix[0][2] /= d;
  281.     ttmp.matrix[1][1] /= d;
  282.     ttmp.matrix[2][0] /= d;
  283.     ttmp.matrix[2][2] /= d;
  284.  
  285.     d = -d;
  286.  
  287.     ttmp.matrix[0][1] /= d;
  288.     ttmp.matrix[1][0] /= d;
  289.     ttmp.matrix[1][2] /= d;
  290.     ttmp.matrix[2][1] /= d;
  291.  
  292.     ttmp.translate.x = -(ttmp.matrix[0][0]*trans->translate.x +
  293.                  ttmp.matrix[1][0]*trans->translate.y +
  294.                  ttmp.matrix[2][0]*trans->translate.z);
  295.     ttmp.translate.y = -(ttmp.matrix[0][1]*trans->translate.x +
  296.                  ttmp.matrix[1][1]*trans->translate.y +
  297.                  ttmp.matrix[2][1]*trans->translate.z);
  298.     ttmp.translate.z = -(ttmp.matrix[0][2]*trans->translate.x +
  299.                  ttmp.matrix[1][2]*trans->translate.y +
  300.                  ttmp.matrix[2][2]*trans->translate.z);
  301.  
  302.     MatrixCopy(&ttmp, inverse);
  303. }
  304.  
  305. /*
  306.  * Apply a transformation to a point (translation affects the point).
  307.  */
  308. void
  309. PointTransform(vec, trans)
  310. Vector *vec;
  311. RSMatrix *trans;
  312. {
  313.     Vector tmp;
  314.  
  315.     tmp.x = vec->x * trans->matrix[0][0] + vec->y * trans->matrix[1][0] +
  316.             vec->z * trans->matrix[2][0] + trans->translate.x;
  317.     tmp.y = vec->x * trans->matrix[0][1] + vec->y * trans->matrix[1][1] +
  318.             vec->z * trans->matrix[2][1] + trans->translate.y;
  319.     tmp.z = vec->x * trans->matrix[0][2] + vec->y * trans->matrix[1][2] +
  320.             vec->z * trans->matrix[2][2] + trans->translate.z;
  321.     *vec = tmp;
  322. }
  323.  
  324. /*
  325.  * 'c1x' is the X (0th) component of the first column, and so on.
  326.  */
  327. void
  328. ArbitraryMatrix(c1x, c2x, c3x, c1y, c2y, c3y, c1z, c2z, c3z, tx, ty, tz, trans)
  329. Float c1x, c1y, c1z, c2x, c2y, c2z, c3x, c3y, c3z, tx, ty, tz;
  330. RSMatrix *trans;
  331. {
  332.     trans->matrix[0][0] = c1x;
  333.     trans->matrix[1][0] = c1y;
  334.     trans->matrix[2][0] = c1z;
  335.  
  336.     trans->matrix[0][1] = c2x;
  337.     trans->matrix[1][1] = c2y;
  338.     trans->matrix[2][1] = c2z;
  339.  
  340.     trans->matrix[0][2] = c3x;
  341.     trans->matrix[1][2] = c3y;
  342.     trans->matrix[2][2] = c3z;
  343.  
  344.     trans->translate.x = tx;
  345.     trans->translate.y = ty;
  346.     trans->translate.z = tz;
  347. }
  348.  
  349. /*
  350.  * Apply transformation to a vector (translations have no effect).
  351.  */
  352. void
  353. VecTransform(vec, trans)
  354. Vector *vec;
  355. RSMatrix *trans;
  356. {
  357.     Vector tmp;
  358.  
  359.     tmp.x = vec->x*trans->matrix[0][0] +
  360.         vec->y*trans->matrix[1][0] + vec->z*trans->matrix[2][0];
  361.     tmp.y = vec->x*trans->matrix[0][1] +
  362.         vec->y*trans->matrix[1][1] + vec->z*trans->matrix[2][1];
  363.     tmp.z = vec->x*trans->matrix[0][2] +
  364.         vec->y*trans->matrix[1][2] + vec->z*trans->matrix[2][2];
  365.  
  366.     *vec = tmp;
  367. }
  368.  
  369. /*
  370.  * Transform normal -- multiply by the transpose of the given
  371.  * matrix (which is the inverse of the 'desired' transformation).
  372.  */
  373. void
  374. NormalTransform(norm, it)
  375. Vector *norm;
  376. RSMatrix *it;
  377. {
  378.     Vector onorm;
  379.  
  380.     onorm = *norm;
  381.  
  382.     norm->x = onorm.x*it->matrix[0][0] + onorm.y*it->matrix[0][1] +
  383.                 onorm.z*it->matrix[0][2];
  384.     norm->y = onorm.x*it->matrix[1][0] + onorm.y*it->matrix[1][1] +
  385.                 onorm.z*it->matrix[1][2];
  386.     norm->z = onorm.x*it->matrix[2][0] + onorm.y*it->matrix[2][1] +
  387.                 onorm.z*it->matrix[2][2];
  388.     (void)VecNormalize(norm);
  389. }
  390.  
  391. /*
  392.  * Transform "ray" by transforming the origin point and direction vector.
  393.  */
  394. Float
  395. RayTransform(ray, trans)
  396. Ray *ray;
  397. RSMatrix *trans;
  398. {
  399.     PointTransform(&ray->pos, trans);
  400.     VecTransform(&ray->dir, trans);
  401.     return VecNormalize(&ray->dir);
  402. }
  403.  
  404. void
  405. TransPropagate(trans)
  406. Trans *trans;
  407. {
  408.     (*trans->methods->propagate)(trans->tr, &trans->trans, &trans->itrans);
  409. }
  410.  
  411. void
  412. TransResolveAssoc(trans)
  413. Trans *trans;
  414. {
  415.     Trans *curtrans;
  416.     ExprAssoc *curassoc;
  417.  
  418.     for (curtrans = trans; curtrans; curtrans = curtrans->next) {
  419.         for (curassoc = curtrans->assoc; curassoc; curassoc = curassoc->next) {
  420.             *curassoc->lhs = ExprEval(curassoc->expr);
  421.         }
  422.         if (curtrans->assoc)
  423.             TransPropagate(curtrans);
  424.     }
  425. }
  426.  
  427. void
  428. TransComposeList(list, result)
  429. Trans *list, *result;
  430. {
  431.     TransCopy(list, result);
  432.     for (list = list->next; list; list = list->next)
  433.         TransCompose(list, result, result);
  434. }
  435.