home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 3 / RISC_DISC_3.iso / resources / etexts / gems / gemsv / ch7_2 / vec.h < prev   
Encoding:
C/C++ Source or Header  |  1995-03-08  |  30.1 KB  |  911 lines

  1. /*
  2.  * vec.h --  Vector macros for 2,3, and 4 dimensions,
  3.  *           for any  combination of C scalar types.
  4.  *
  5.  * Author:        Don Hatch (hatch@sgi.com)
  6.  * Last modified:    Fri Sep 30 03:23:02 PDT 1994
  7.  *
  8.  * General description:
  9.  *
  10.  *    The macro name describes its arguments; e.g.
  11.  *            MXS3 is "matrix times scalar in 3 dimensions";
  12.  *            VMV2 is "vector minus vector in 2 dimensions".
  13.  *
  14.  *    If the result of an operation is a scalar, then the macro "returns"
  15.  *    the value; e.g.
  16.  *            result = DOT3(v,w);
  17.  *            result = DET4(m);
  18.  *
  19.  *    If the result of an operation is a vector or matrix, then
  20.  *    the first argument is the destination; e.g.
  21.  *            SET2(tovec, fromvec);
  22.  *            MXM3(result, m1, m2);
  23.  *
  24.  *  WARNING: For the operations that are not done "componentwise"
  25.  *        (e.g. vector cross products and matrix multiplies)
  26.  *        the destination should not be either of the arguments,
  27.  *        for obvious reasons.  For example, the following is wrong:
  28.  *        VXM2(v,v,m);
  29.  *          For such "unsafe" macros, there are safe versions provided,
  30.  *          but you have to specify a type for the temporary
  31.  *        result vector or matrix.  For example, the safe versions
  32.  *        of VXM2 are:
  33.  *              VXM2d(v,v,m)    if v's scalar type is double or float
  34.  *              VXM2i(v,v,m)    if v's scalar type is int or char
  35.  *              VXM2l(v,v,m)    if v's scalar type is long
  36.  *              VXM2r(v,v,m)    if v's scalar type is real
  37.  *              VXM2safe(type,v,v,m) for other scalar types.
  38.  *        These "safe" macros do not evaluate to C expressions
  39.  *        (so, for example, they can't be used inside the parentheses of
  40.  *        a for(...)).
  41.  *
  42.  *  Specific descriptions:
  43.  *
  44.  *    The "?"'s in the following can be 2, 3, or 4.
  45.  *
  46.  *    SET?(to,from)            to = from
  47.  *    SETMAT?(to,from)        to = from
  48.  *    ROUNDVEC?(to,from)        to = from with entries rounded
  49.  *                            to nearest integer
  50.  *    ROUNDMAT?(to,from)        to = from with entries rounded
  51.  *                            to nearest integer
  52.  *    FILLVEC?(v,s)            set each entry of vector v to be s
  53.  *    FILLMAT?(m,s)            set each entry of matrix m to be s
  54.  *    ZEROVEC?(v)            v = 0
  55.  *    ISZEROVEC?(v)            v == 0
  56.  *    EQVEC?(v,w)            v == w
  57.  *    EQMAT?(m1,m2)            m1 == m2
  58.  *    ZEROMAT?(m)            m = 0
  59.  *    IDENTMAT?(m)            m = 1
  60.  *    TRANSPOSE?(to,from)        (matrix to) = (transpose of matrix from)
  61.  *    ADJOINT?(to,from)        (matrix to) = (adjoint of matrix from)
  62.  *                     i.e. its determinant times its inverse
  63.  *
  64.  *    V{P,M}V?(to,v,w)        to = v {+,-} w
  65.  *    M{P,M}M?(to,m1,m2)        to = m1 {+,-} m2
  66.  *    SX{V,M}?(to,s,from)        to = s * from
  67.  *    M{V,M}?(to,from)        to = -from
  68.  *    {V,M}{X,D}S?(to,from,s)        to = from {*,/} s
  69.  *    MXM?(to,m1,m2)            to = m1 * m2
  70.  *    VXM?(to,v,m)            (row vec to) = (row vec v) * m
  71.  *    MXV?(to,m,v)            (column vec to) = m * (column vec v)
  72.  *    LERP?(to,v0,v1,t)        to = v0 + t*(v1-v0)
  73.  *
  74.  *    DET?(m)                determinant of m
  75.  *    TRACE?(m)            trace (sum of diagonal entries) of m
  76.  *    DOT?(v,w)            dot (scalar) product of v and w
  77.  *    NORMSQRD?(v)            square of |v|
  78.  *    DISTSQRD?(v,w)            square of |v-w|
  79.  *
  80.  *    XV2(to,v)            to = v rotated by 90 degrees
  81.  *    VXV3(to,v1,v2)            to = cross (vector) product of v1 and v2
  82.  *    VXVXV4(to,v1,v2,v3)        to = 4-dimensional vector cross product
  83.  *                     of v1,v2,v3 (a vector orthogonal to
  84.  *                     v1,v2,v3 whose length equals the
  85.  *                     volume of the spanned parallelotope)
  86.  *    VXV2(v0,v1)            determinant of matrix with rows v0,v1
  87.  *    VXVXV3(v0,v1,v2)        determinant of matrix with rows v0,v1,v2
  88.  *    VXVXVXV4(v0,v1,v2,v3)        determinant of matrix with rows v0,..,v3
  89.  *
  90.  *   The following macros mix objects from different dimensions.
  91.  *   For example, V3XM4 would be used to apply a composite
  92.  *   4x4 rotation-and-translation matrix to a 3d vector.
  93.  *
  94.  *    SET3from2(to,from,pad)        (3d vec to) = (2d vec from) with pad
  95.  *    SET4from3(to,from,pad)        (4d vec to) = (3d vec from) with pad
  96.  *    SETMAT3from2(to,from,pad0,pad1) (3x3 mat to) = (2x2 mat from)
  97.  *                     padded with pad0 on the sides
  98.  *                     and pad1 in the corner
  99.  *    SETMAT4from3(to,from,pad0,pad1) (4x4 mat to) = (3x3 mat from)
  100.  *                     padded with pad0 on the sides
  101.  *                     and pad1 in the corner
  102.  *    V2XM3(to2,v2,m3)       (2d row vec to2) = (2d row vec v2) * (3x3 mat m3)
  103.  *    V3XM4(to3,v3,m4)       (3d row vec to3) = (3d row vec v2) * (4x4 mat m4)
  104.  *    M3XV2(to2,m3,v2)       (2d col vec to2) = (3x3 mat m3) * (2d col vec v2)
  105.  *    M4XV3(to3,m4,v3)       (3d col vec to3) = (4x4 mat m4) * (3d col vec v3)
  106.  *    M2XM3(to3,m2,m3)       (3x3 mat to3) = (2x2 mat m2) * (3x3 mat m3)
  107.  *    M3XM4(to4,m3,m4)       (4x4 mat to4) = (3x3 mat m3) * (4x4 mat m4)
  108.  *    M3XM2(to3,m3,m2)       (3x3 mat to3) = (3x3 mat m3) * (2x2 mat m2)
  109.  *    M4XM3(to4,m4,m3)       (4x4 mat to4) = (4x4 mat m4) * (3x3 mat m3)
  110.  *
  111.  *
  112.  *   This file is machine-generated and can be regenerated
  113.  *   for any number of dimensions.
  114.  *   The program that generated it is available upon request.
  115.  */
  116.  
  117. #ifndef VEC_H
  118. #define VEC_H 4
  119. #include <math.h>    /* for definition of floor() */
  120. #define SET2(to,from)    \
  121.         ((to)[0] = (from)[0], \
  122.          (to)[1] = (from)[1])
  123. #define SETMAT2(to,from)    \
  124.         (SET2((to)[0], (from)[0]), \
  125.          SET2((to)[1], (from)[1]))
  126. #define ROUNDVEC2(to,from)    \
  127.         ((to)[0] = floor((from)[0]+.5), \
  128.          (to)[1] = floor((from)[1]+.5))
  129. #define ROUNDMAT2(to,from)    \
  130.         (ROUNDVEC2((to)[0], (from)[0]), \
  131.          ROUNDVEC2((to)[1], (from)[1]))
  132. #define FILLVEC2(v,s)    \
  133.         ((v)[0] = (s), \
  134.          (v)[1] = (s))
  135. #define FILLMAT2(m,s)    \
  136.         (FILLVEC2((m)[0], s), \
  137.          FILLVEC2((m)[1], s))
  138. #define ZEROVEC2(v)    \
  139.         ((v)[0] = 0, \
  140.          (v)[1] = 0)
  141. #define ISZEROVEC2(v)    \
  142.         ((v)[0] == 0 && \
  143.          (v)[1] == 0)
  144. #define EQVEC2(v,w)    \
  145.         ((v)[0] == (w)[0] && \
  146.          (v)[1] == (w)[1])
  147. #define EQMAT2(m1,m2)    \
  148.         (EQVEC2((m1)[0], (m2)[0]) && \
  149.          EQVEC2((m1)[1], (m2)[1]))
  150. #define ZEROMAT2(m)    \
  151.         (ZEROVEC2((m)[0]), \
  152.          ZEROVEC2((m)[1]))
  153. #define IDENTMAT2(m)    \
  154.         (ZEROVEC2((m)[0]), (m)[0][0]=1, \
  155.          ZEROVEC2((m)[1]), (m)[1][1]=1)
  156. #define TRANSPOSE2(to,from)    \
  157.         (_SETcol2((to)[0], from, 0), \
  158.          _SETcol2((to)[1], from, 1))
  159. #define VPV2(to,v,w)    \
  160.         ((to)[0] = (v)[0] + (w)[0], \
  161.          (to)[1] = (v)[1] + (w)[1])
  162. #define VMV2(to,v,w)    \
  163.         ((to)[0] = (v)[0] - (w)[0], \
  164.          (to)[1] = (v)[1] - (w)[1])
  165. #define MPM2(to,m1,m2)    \
  166.         (VPV2((to)[0], (m1)[0], (m2)[0]), \
  167.          VPV2((to)[1], (m1)[1], (m2)[1]))
  168. #define MMM2(to,m1,m2)    \
  169.         (VMV2((to)[0], (m1)[0], (m2)[0]), \
  170.          VMV2((to)[1], (m1)[1], (m2)[1]))
  171. #define SXV2(to,s,from)    \
  172.         ((to)[0] = (s) * (from)[0], \
  173.          (to)[1] = (s) * (from)[1])
  174. #define SXM2(to,s,from)    \
  175.         (SXV2((to)[0], s, (from)[0]), \
  176.          SXV2((to)[1], s, (from)[1]))
  177. #define MV2(to,from)    \
  178.         ((to)[0] = -(from)[0], \
  179.          (to)[1] = -(from)[1])
  180. #define MM2(to,from)    \
  181.         (MV2((to)[0], (from)[0]), \
  182.          MV2((to)[1], (from)[1]))
  183. #define VXS2(to,from,s)    \
  184.         ((to)[0] = (from)[0] * (s), \
  185.          (to)[1] = (from)[1] * (s))
  186. #define VDS2(to,from,s)    \
  187.         ((to)[0] = (from)[0] / (s), \
  188.          (to)[1] = (from)[1] / (s))
  189. #define MXS2(to,from,s)    \
  190.         (VXS2((to)[0], (from)[0], s), \
  191.          VXS2((to)[1], (from)[1], s))
  192. #define MDS2(to,from,s)    \
  193.         (VDS2((to)[0], (from)[0], s), \
  194.          VDS2((to)[1], (from)[1], s))
  195. #define MXM2(to,m1,m2)    \
  196.         (VXM2((to)[0], (m1)[0], m2), \
  197.          VXM2((to)[1], (m1)[1], m2))
  198. #define VXM2(to,v,m)    \
  199.         ((to)[0] = _DOTcol2(v, m, 0), \
  200.          (to)[1] = _DOTcol2(v, m, 1))
  201. #define MXV2(to,m,v)    \
  202.         ((to)[0] = DOT2((m)[0], v), \
  203.          (to)[1] = DOT2((m)[1], v))
  204. #define LERP2(to,v0,v1,t)    \
  205.         ((to)[0]=(v0)[0]+(t)*((v1)[0]-(v0)[0]), \
  206.          (to)[1]=(v0)[1]+(t)*((v1)[1]-(v0)[1]))
  207. #define TRACE2(m)    \
  208.         ((m)[0][0] + \
  209.          (m)[1][1])
  210. #define DOT2(v,w)    \
  211.         ((v)[0] * (w)[0] + \
  212.          (v)[1] * (w)[1])
  213. #define NORMSQRD2(v)    \
  214.         ((v)[0] * (v)[0] + \
  215.          (v)[1] * (v)[1])
  216. #define DISTSQRD2(v,w)    \
  217.         (((v)[0]-(w)[0])*((v)[0]-(w)[0]) + \
  218.          ((v)[1]-(w)[1])*((v)[1]-(w)[1]))
  219. #define _DOTcol2(v,m,j)    \
  220.         ((v)[0] * (m)[0][j] + \
  221.          (v)[1] * (m)[1][j])
  222. #define _SETcol2(v,m,j)    \
  223.         ((v)[0] = (m)[0][j], \
  224.          (v)[1] = (m)[1][j])
  225. #define _MXVcol2(to,m,M,j)    \
  226.         ((to)[0][j] = _DOTcol2((m)[0],M,j), \
  227.          (to)[1][j] = _DOTcol2((m)[1],M,j))
  228. #define _DET2(v0,v1,i0,i1)    \
  229.         ((v0)[i0]* _DET1(v1,i1) + \
  230.          (v0)[i1]*-_DET1(v1,i0))
  231. #define XV2(to,v1)    \
  232.         ((to)[0] = -_DET1(v1, 1), \
  233.          (to)[1] =  _DET1(v1, 0))
  234. #define V2XM3(to2,v2,m3)    \
  235.         ((to2)[0] = _DOTcol2(v2,m3,0) + (m3)[2][0], \
  236.          (to2)[1] = _DOTcol2(v2,m3,1) + (m3)[2][1])
  237. #define M3XV2(to2,m3,v2)    \
  238.         ((to2)[0] = DOT2((m3)[0],v2) + (m3)[0][2], \
  239.          (to2)[1] = DOT2((m3)[1],v2) + (m3)[1][2])
  240. #define _DET1(v0,i0)    \
  241.         ((v0)[i0])
  242. #define VXV2(v0,v1)    \
  243.         (_DET2(v0,v1,0,1))
  244. #define DET2(m)    \
  245.         (VXV2((m)[0],(m)[1]))
  246. #define ADJOINT2(to,m)    \
  247.         ( _ADJOINTcol2(to,0,m,1), \
  248.          __ADJOINTcol2(to,1,m,0))
  249. #define _ADJOINTcol2(to,col,m,i1)    \
  250.         ((to)[0][col] =  _DET1(m[i1], 1), \
  251.          (to)[1][col] = -_DET1(m[i1], 0))
  252. #define __ADJOINTcol2(to,col,m,i1)    \
  253.         ((to)[0][col] = -_DET1(m[i1], 1), \
  254.          (to)[1][col] =  _DET1(m[i1], 0))
  255. #define SET3(to,from)    \
  256.         ((to)[0] = (from)[0], \
  257.          (to)[1] = (from)[1], \
  258.          (to)[2] = (from)[2])
  259. #define SETMAT3(to,from)    \
  260.         (SET3((to)[0], (from)[0]), \
  261.          SET3((to)[1], (from)[1]), \
  262.          SET3((to)[2], (from)[2]))
  263. #define ROUNDVEC3(to,from)    \
  264.         ((to)[0] = floor((from)[0]+.5), \
  265.          (to)[1] = floor((from)[1]+.5), \
  266.          (to)[2] = floor((from)[2]+.5))
  267. #define ROUNDMAT3(to,from)    \
  268.         (ROUNDVEC3((to)[0], (from)[0]), \
  269.          ROUNDVEC3((to)[1], (from)[1]), \
  270.          ROUNDVEC3((to)[2], (from)[2]))
  271. #define FILLVEC3(v,s)    \
  272.         ((v)[0] = (s), \
  273.          (v)[1] = (s), \
  274.          (v)[2] = (s))
  275. #define FILLMAT3(m,s)    \
  276.         (FILLVEC3((m)[0], s), \
  277.          FILLVEC3((m)[1], s), \
  278.          FILLVEC3((m)[2], s))
  279. #define ZEROVEC3(v)    \
  280.         ((v)[0] = 0, \
  281.          (v)[1] = 0, \
  282.          (v)[2] = 0)
  283. #define ISZEROVEC3(v)    \
  284.         ((v)[0] == 0 && \
  285.          (v)[1] == 0 && \
  286.          (v)[2] == 0)
  287. #define EQVEC3(v,w)    \
  288.         ((v)[0] == (w)[0] && \
  289.          (v)[1] == (w)[1] && \
  290.          (v)[2] == (w)[2])
  291. #define EQMAT3(m1,m2)    \
  292.         (EQVEC3((m1)[0], (m2)[0]) && \
  293.          EQVEC3((m1)[1], (m2)[1]) && \
  294.          EQVEC3((m1)[2], (m2)[2]))
  295. #define ZEROMAT3(m)    \
  296.         (ZEROVEC3((m)[0]), \
  297.          ZEROVEC3((m)[1]), \
  298.          ZEROVEC3((m)[2]))
  299. #define IDENTMAT3(m)    \
  300.         (ZEROVEC3((m)[0]), (m)[0][0]=1, \
  301.          ZEROVEC3((m)[1]), (m)[1][1]=1, \
  302.          ZEROVEC3((m)[2]), (m)[2][2]=1)
  303. #define TRANSPOSE3(to,from)    \
  304.         (_SETcol3((to)[0], from, 0), \
  305.          _SETcol3((to)[1], from, 1), \
  306.          _SETcol3((to)[2], from, 2))
  307. #define VPV3(to,v,w)    \
  308.         ((to)[0] = (v)[0] + (w)[0], \
  309.          (to)[1] = (v)[1] + (w)[1], \
  310.          (to)[2] = (v)[2] + (w)[2])
  311. #define VMV3(to,v,w)    \
  312.         ((to)[0] = (v)[0] - (w)[0], \
  313.          (to)[1] = (v)[1] - (w)[1], \
  314.          (to)[2] = (v)[2] - (w)[2])
  315. #define MPM3(to,m1,m2)    \
  316.         (VPV3((to)[0], (m1)[0], (m2)[0]), \
  317.          VPV3((to)[1], (m1)[1], (m2)[1]), \
  318.          VPV3((to)[2], (m1)[2], (m2)[2]))
  319. #define MMM3(to,m1,m2)    \
  320.         (VMV3((to)[0], (m1)[0], (m2)[0]), \
  321.          VMV3((to)[1], (m1)[1], (m2)[1]), \
  322.          VMV3((to)[2], (m1)[2], (m2)[2]))
  323. #define SXV3(to,s,from)    \
  324.         ((to)[0] = (s) * (from)[0], \
  325.          (to)[1] = (s) * (from)[1], \
  326.          (to)[2] = (s) * (from)[2])
  327. #define SXM3(to,s,from)    \
  328.         (SXV3((to)[0], s, (from)[0]), \
  329.          SXV3((to)[1], s, (from)[1]), \
  330.          SXV3((to)[2], s, (from)[2]))
  331. #define MV3(to,from)    \
  332.         ((to)[0] = -(from)[0], \
  333.          (to)[1] = -(from)[1], \
  334.          (to)[2] = -(from)[2])
  335. #define MM3(to,from)    \
  336.         (MV3((to)[0], (from)[0]), \
  337.          MV3((to)[1], (from)[1]), \
  338.          MV3((to)[2], (from)[2]))
  339. #define VXS3(to,from,s)    \
  340.         ((to)[0] = (from)[0] * (s), \
  341.          (to)[1] = (from)[1] * (s), \
  342.          (to)[2] = (from)[2] * (s))
  343. #define VDS3(to,from,s)    \
  344.         ((to)[0] = (from)[0] / (s), \
  345.          (to)[1] = (from)[1] / (s), \
  346.          (to)[2] = (from)[2] / (s))
  347. #define MXS3(to,from,s)    \
  348.         (VXS3((to)[0], (from)[0], s), \
  349.          VXS3((to)[1], (from)[1], s), \
  350.          VXS3((to)[2], (from)[2], s))
  351. #define MDS3(to,from,s)    \
  352.         (VDS3((to)[0], (from)[0], s), \
  353.          VDS3((to)[1], (from)[1], s), \
  354.          VDS3((to)[2], (from)[2], s))
  355. #define MXM3(to,m1,m2)    \
  356.         (VXM3((to)[0], (m1)[0], m2), \
  357.          VXM3((to)[1], (m1)[1], m2), \
  358.          VXM3((to)[2], (m1)[2], m2))
  359. #define VXM3(to,v,m)    \
  360.         ((to)[0] = _DOTcol3(v, m, 0), \
  361.          (to)[1] = _DOTcol3(v, m, 1), \
  362.          (to)[2] = _DOTcol3(v, m, 2))
  363. #define MXV3(to,m,v)    \
  364.         ((to)[0] = DOT3((m)[0], v), \
  365.          (to)[1] = DOT3((m)[1], v), \
  366.          (to)[2] = DOT3((m)[2], v))
  367. #define LERP3(to,v0,v1,t)    \
  368.         ((to)[0]=(v0)[0]+(t)*((v1)[0]-(v0)[0]), \
  369.          (to)[1]=(v0)[1]+(t)*((v1)[1]-(v0)[1]), \
  370.          (to)[2]=(v0)[2]+(t)*((v1)[2]-(v0)[2]))
  371. #define TRACE3(m)    \
  372.         ((m)[0][0] + \
  373.          (m)[1][1] + \
  374.          (m)[2][2])
  375. #define DOT3(v,w)    \
  376.         ((v)[0] * (w)[0] + \
  377.          (v)[1] * (w)[1] + \
  378.          (v)[2] * (w)[2])
  379. #define NORMSQRD3(v)    \
  380.         ((v)[0] * (v)[0] + \
  381.          (v)[1] * (v)[1] + \
  382.          (v)[2] * (v)[2])
  383. #define DISTSQRD3(v,w)    \
  384.         (((v)[0]-(w)[0])*((v)[0]-(w)[0]) + \
  385.          ((v)[1]-(w)[1])*((v)[1]-(w)[1]) + \
  386.          ((v)[2]-(w)[2])*((v)[2]-(w)[2]))
  387. #define _DOTcol3(v,m,j)    \
  388.         ((v)[0] * (m)[0][j] + \
  389.          (v)[1] * (m)[1][j] + \
  390.          (v)[2] * (m)[2][j])
  391. #define _SETcol3(v,m,j)    \
  392.         ((v)[0] = (m)[0][j], \
  393.          (v)[1] = (m)[1][j], \
  394.          (v)[2] = (m)[2][j])
  395. #define _MXVcol3(to,m,M,j)    \
  396.         ((to)[0][j] = _DOTcol3((m)[0],M,j), \
  397.          (to)[1][j] = _DOTcol3((m)[1],M,j), \
  398.          (to)[2][j] = _DOTcol3((m)[2],M,j))
  399. #define _DET3(v0,v1,v2,i0,i1,i2)    \
  400.         ((v0)[i0]* _DET2(v1,v2,i1,i2) + \
  401.          (v0)[i1]*-_DET2(v1,v2,i0,i2) + \
  402.          (v0)[i2]* _DET2(v1,v2,i0,i1))
  403. #define VXV3(to,v1,v2)    \
  404.         ((to)[0] =  _DET2(v1,v2, 1,2), \
  405.          (to)[1] = -_DET2(v1,v2, 0,2), \
  406.          (to)[2] =  _DET2(v1,v2, 0,1))
  407. #define SET3from2(to,from,pad)    \
  408.         ((to)[0] = (from)[0], \
  409.          (to)[1] = (from)[1], \
  410.          (to)[2] = (pad))
  411. #define SETMAT3from2(to,from,pad0,pad1)    \
  412.         (SET3from2((to)[0], (from)[0], pad0), \
  413.          SET3from2((to)[1], (from)[1], pad0), \
  414.          FILLVEC2((to)[2], (pad0)), (to)[2][2] = (pad1))
  415. #define M2XM3(to3,m2,m3)    \
  416.         (_MXVcol2(to3,m2,m3,0), (to3)[2][0]=(m3)[2][0], \
  417.          _MXVcol2(to3,m2,m3,1), (to3)[2][1]=(m3)[2][1], \
  418.          _MXVcol2(to3,m2,m3,2), (to3)[2][2]=(m3)[2][2])
  419. #define M3XM2(to3,m3,m2)    \
  420.         (VXM2((to3)[0],(m3)[0],m2), (to3)[0][2]=(m3)[0][2], \
  421.          VXM2((to3)[1],(m3)[1],m2), (to3)[1][2]=(m3)[1][2], \
  422.          VXM2((to3)[2],(m3)[2],m2), (to3)[2][2]=(m3)[2][2])
  423. #define V3XM4(to3,v3,m4)    \
  424.         ((to3)[0] = _DOTcol3(v3,m4,0) + (m4)[3][0], \
  425.          (to3)[1] = _DOTcol3(v3,m4,1) + (m4)[3][1], \
  426.          (to3)[2] = _DOTcol3(v3,m4,2) + (m4)[3][2])
  427. #define M4XV3(to3,m4,v3)    \
  428.         ((to3)[0] = DOT3((m4)[0],v3) + (m4)[0][3], \
  429.          (to3)[1] = DOT3((m4)[1],v3) + (m4)[1][3], \
  430.          (to3)[2] = DOT3((m4)[2],v3) + (m4)[2][3])
  431. #define VXVXV3(v0,v1,v2)    \
  432.         (_DET3(v0,v1,v2,0,1,2))
  433. #define DET3(m)    \
  434.         (VXVXV3((m)[0],(m)[1],(m)[2]))
  435. #define ADJOINT3(to,m)    \
  436.         ( _ADJOINTcol3(to,0,m,1,2), \
  437.          __ADJOINTcol3(to,1,m,0,2), \
  438.           _ADJOINTcol3(to,2,m,0,1))
  439. #define _ADJOINTcol3(to,col,m,i1,i2)    \
  440.         ((to)[0][col] =  _DET2(m[i1],m[i2], 1,2), \
  441.          (to)[1][col] = -_DET2(m[i1],m[i2], 0,2), \
  442.          (to)[2][col] =  _DET2(m[i1],m[i2], 0,1))
  443. #define __ADJOINTcol3(to,col,m,i1,i2)    \
  444.         ((to)[0][col] = -_DET2(m[i1],m[i2], 1,2), \
  445.          (to)[1][col] =  _DET2(m[i1],m[i2], 0,2), \
  446.          (to)[2][col] = -_DET2(m[i1],m[i2], 0,1))
  447. #define SET4(to,from)    \
  448.         ((to)[0] = (from)[0], \
  449.          (to)[1] = (from)[1], \
  450.          (to)[2] = (from)[2], \
  451.          (to)[3] = (from)[3])
  452. #define SETMAT4(to,from)    \
  453.         (SET4((to)[0], (from)[0]), \
  454.          SET4((to)[1], (from)[1]), \
  455.          SET4((to)[2], (from)[2]), \
  456.          SET4((to)[3], (from)[3]))
  457. #define ROUNDVEC4(to,from)    \
  458.         ((to)[0] = floor((from)[0]+.5), \
  459.          (to)[1] = floor((from)[1]+.5), \
  460.          (to)[2] = floor((from)[2]+.5), \
  461.          (to)[3] = floor((from)[3]+.5))
  462. #define ROUNDMAT4(to,from)    \
  463.         (ROUNDVEC4((to)[0], (from)[0]), \
  464.          ROUNDVEC4((to)[1], (from)[1]), \
  465.          ROUNDVEC4((to)[2], (from)[2]), \
  466.          ROUNDVEC4((to)[3], (from)[3]))
  467. #define FILLVEC4(v,s)    \
  468.         ((v)[0] = (s), \
  469.          (v)[1] = (s), \
  470.          (v)[2] = (s), \
  471.          (v)[3] = (s))
  472. #define FILLMAT4(m,s)    \
  473.         (FILLVEC4((m)[0], s), \
  474.          FILLVEC4((m)[1], s), \
  475.          FILLVEC4((m)[2], s), \
  476.          FILLVEC4((m)[3], s))
  477. #define ZEROVEC4(v)    \
  478.         ((v)[0] = 0, \
  479.          (v)[1] = 0, \
  480.          (v)[2] = 0, \
  481.          (v)[3] = 0)
  482. #define ISZEROVEC4(v)    \
  483.         ((v)[0] == 0 && \
  484.          (v)[1] == 0 && \
  485.          (v)[2] == 0 && \
  486.          (v)[3] == 0)
  487. #define EQVEC4(v,w)    \
  488.         ((v)[0] == (w)[0] && \
  489.          (v)[1] == (w)[1] && \
  490.          (v)[2] == (w)[2] && \
  491.          (v)[3] == (w)[3])
  492. #define EQMAT4(m1,m2)    \
  493.         (EQVEC4((m1)[0], (m2)[0]) && \
  494.          EQVEC4((m1)[1], (m2)[1]) && \
  495.          EQVEC4((m1)[2], (m2)[2]) && \
  496.          EQVEC4((m1)[3], (m2)[3]))
  497. #define ZEROMAT4(m)    \
  498.         (ZEROVEC4((m)[0]), \
  499.          ZEROVEC4((m)[1]), \
  500.          ZEROVEC4((m)[2]), \
  501.          ZEROVEC4((m)[3]))
  502. #define IDENTMAT4(m)    \
  503.         (ZEROVEC4((m)[0]), (m)[0][0]=1, \
  504.          ZEROVEC4((m)[1]), (m)[1][1]=1, \
  505.          ZEROVEC4((m)[2]), (m)[2][2]=1, \
  506.          ZEROVEC4((m)[3]), (m)[3][3]=1)
  507. #define TRANSPOSE4(to,from)    \
  508.         (_SETcol4((to)[0], from, 0), \
  509.          _SETcol4((to)[1], from, 1), \
  510.          _SETcol4((to)[2], from, 2), \
  511.          _SETcol4((to)[3], from, 3))
  512. #define VPV4(to,v,w)    \
  513.         ((to)[0] = (v)[0] + (w)[0], \
  514.          (to)[1] = (v)[1] + (w)[1], \
  515.          (to)[2] = (v)[2] + (w)[2], \
  516.          (to)[3] = (v)[3] + (w)[3])
  517. #define VMV4(to,v,w)    \
  518.         ((to)[0] = (v)[0] - (w)[0], \
  519.          (to)[1] = (v)[1] - (w)[1], \
  520.          (to)[2] = (v)[2] - (w)[2], \
  521.          (to)[3] = (v)[3] - (w)[3])
  522. #define MPM4(to,m1,m2)    \
  523.         (VPV4((to)[0], (m1)[0], (m2)[0]), \
  524.          VPV4((to)[1], (m1)[1], (m2)[1]), \
  525.          VPV4((to)[2], (m1)[2], (m2)[2]), \
  526.          VPV4((to)[3], (m1)[3], (m2)[3]))
  527. #define MMM4(to,m1,m2)    \
  528.         (VMV4((to)[0], (m1)[0], (m2)[0]), \
  529.          VMV4((to)[1], (m1)[1], (m2)[1]), \
  530.          VMV4((to)[2], (m1)[2], (m2)[2]), \
  531.          VMV4((to)[3], (m1)[3], (m2)[3]))
  532. #define SXV4(to,s,from)    \
  533.         ((to)[0] = (s) * (from)[0], \
  534.          (to)[1] = (s) * (from)[1], \
  535.          (to)[2] = (s) * (from)[2], \
  536.          (to)[3] = (s) * (from)[3])
  537. #define SXM4(to,s,from)    \
  538.         (SXV4((to)[0], s, (from)[0]), \
  539.          SXV4((to)[1], s, (from)[1]), \
  540.          SXV4((to)[2], s, (from)[2]), \
  541.          SXV4((to)[3], s, (from)[3]))
  542. #define MV4(to,from)    \
  543.         ((to)[0] = -(from)[0], \
  544.          (to)[1] = -(from)[1], \
  545.          (to)[2] = -(from)[2], \
  546.          (to)[3] = -(from)[3])
  547. #define MM4(to,from)    \
  548.         (MV4((to)[0], (from)[0]), \
  549.          MV4((to)[1], (from)[1]), \
  550.          MV4((to)[2], (from)[2]), \
  551.          MV4((to)[3], (from)[3]))
  552. #define VXS4(to,from,s)    \
  553.         ((to)[0] = (from)[0] * (s), \
  554.          (to)[1] = (from)[1] * (s), \
  555.          (to)[2] = (from)[2] * (s), \
  556.          (to)[3] = (from)[3] * (s))
  557. #define VDS4(to,from,s)    \
  558.         ((to)[0] = (from)[0] / (s), \
  559.          (to)[1] = (from)[1] / (s), \
  560.          (to)[2] = (from)[2] / (s), \
  561.          (to)[3] = (from)[3] / (s))
  562. #define MXS4(to,from,s)    \
  563.         (VXS4((to)[0], (from)[0], s), \
  564.          VXS4((to)[1], (from)[1], s), \
  565.          VXS4((to)[2], (from)[2], s), \
  566.          VXS4((to)[3], (from)[3], s))
  567. #define MDS4(to,from,s)    \
  568.         (VDS4((to)[0], (from)[0], s), \
  569.          VDS4((to)[1], (from)[1], s), \
  570.          VDS4((to)[2], (from)[2], s), \
  571.          VDS4((to)[3], (from)[3], s))
  572. #define MXM4(to,m1,m2)    \
  573.         (VXM4((to)[0], (m1)[0], m2), \
  574.          VXM4((to)[1], (m1)[1], m2), \
  575.          VXM4((to)[2], (m1)[2], m2), \
  576.          VXM4((to)[3], (m1)[3], m2))
  577. #define VXM4(to,v,m)    \
  578.         ((to)[0] = _DOTcol4(v, m, 0), \
  579.          (to)[1] = _DOTcol4(v, m, 1), \
  580.          (to)[2] = _DOTcol4(v, m, 2), \
  581.          (to)[3] = _DOTcol4(v, m, 3))
  582. #define MXV4(to,m,v)    \
  583.         ((to)[0] = DOT4((m)[0], v), \
  584.          (to)[1] = DOT4((m)[1], v), \
  585.          (to)[2] = DOT4((m)[2], v), \
  586.          (to)[3] = DOT4((m)[3], v))
  587. #define LERP4(to,v0,v1,t)    \
  588.         ((to)[0]=(v0)[0]+(t)*((v1)[0]-(v0)[0]), \
  589.          (to)[1]=(v0)[1]+(t)*((v1)[1]-(v0)[1]), \
  590.          (to)[2]=(v0)[2]+(t)*((v1)[2]-(v0)[2]), \
  591.          (to)[3]=(v0)[3]+(t)*((v1)[3]-(v0)[3]))
  592. #define TRACE4(m)    \
  593.         ((m)[0][0] + \
  594.          (m)[1][1] + \
  595.          (m)[2][2] + \
  596.          (m)[3][3])
  597. #define DOT4(v,w)    \
  598.         ((v)[0] * (w)[0] + \
  599.          (v)[1] * (w)[1] + \
  600.          (v)[2] * (w)[2] + \
  601.          (v)[3] * (w)[3])
  602. #define NORMSQRD4(v)    \
  603.         ((v)[0] * (v)[0] + \
  604.          (v)[1] * (v)[1] + \
  605.          (v)[2] * (v)[2] + \
  606.          (v)[3] * (v)[3])
  607. #define DISTSQRD4(v,w)    \
  608.         (((v)[0]-(w)[0])*((v)[0]-(w)[0]) + \
  609.          ((v)[1]-(w)[1])*((v)[1]-(w)[1]) + \
  610.          ((v)[2]-(w)[2])*((v)[2]-(w)[2]) + \
  611.          ((v)[3]-(w)[3])*((v)[3]-(w)[3]))
  612. #define _DOTcol4(v,m,j)    \
  613.         ((v)[0] * (m)[0][j] + \
  614.          (v)[1] * (m)[1][j] + \
  615.          (v)[2] * (m)[2][j] + \
  616.          (v)[3] * (m)[3][j])
  617. #define _SETcol4(v,m,j)    \
  618.         ((v)[0] = (m)[0][j], \
  619.          (v)[1] = (m)[1][j], \
  620.          (v)[2] = (m)[2][j], \
  621.          (v)[3] = (m)[3][j])
  622. #define _MXVcol4(to,m,M,j)    \
  623.         ((to)[0][j] = _DOTcol4((m)[0],M,j), \
  624.          (to)[1][j] = _DOTcol4((m)[1],M,j), \
  625.          (to)[2][j] = _DOTcol4((m)[2],M,j), \
  626.          (to)[3][j] = _DOTcol4((m)[3],M,j))
  627. #define _DET4(v0,v1,v2,v3,i0,i1,i2,i3)    \
  628.         ((v0)[i0]* _DET3(v1,v2,v3,i1,i2,i3) + \
  629.          (v0)[i1]*-_DET3(v1,v2,v3,i0,i2,i3) + \
  630.          (v0)[i2]* _DET3(v1,v2,v3,i0,i1,i3) + \
  631.          (v0)[i3]*-_DET3(v1,v2,v3,i0,i1,i2))
  632. #define VXVXV4(to,v1,v2,v3)    \
  633.         ((to)[0] = -_DET3(v1,v2,v3, 1,2,3), \
  634.          (to)[1] =  _DET3(v1,v2,v3, 0,2,3), \
  635.          (to)[2] = -_DET3(v1,v2,v3, 0,1,3), \
  636.          (to)[3] =  _DET3(v1,v2,v3, 0,1,2))
  637. #define SET4from3(to,from,pad)    \
  638.         ((to)[0] = (from)[0], \
  639.          (to)[1] = (from)[1], \
  640.          (to)[2] = (from)[2], \
  641.          (to)[3] = (pad))
  642. #define SETMAT4from3(to,from,pad0,pad1)    \
  643.         (SET4from3((to)[0], (from)[0], pad0), \
  644.          SET4from3((to)[1], (from)[1], pad0), \
  645.          SET4from3((to)[2], (from)[2], pad0), \
  646.          FILLVEC3((to)[3], (pad0)), (to)[3][3] = (pad1))
  647. #define M3XM4(to4,m3,m4)    \
  648.         (_MXVcol3(to4,m3,m4,0), (to4)[3][0]=(m4)[3][0], \
  649.          _MXVcol3(to4,m3,m4,1), (to4)[3][1]=(m4)[3][1], \
  650.          _MXVcol3(to4,m3,m4,2), (to4)[3][2]=(m4)[3][2], \
  651.          _MXVcol3(to4,m3,m4,3), (to4)[3][3]=(m4)[3][3])
  652. #define M4XM3(to4,m4,m3)    \
  653.         (VXM3((to4)[0],(m4)[0],m3), (to4)[0][3]=(m4)[0][3], \
  654.          VXM3((to4)[1],(m4)[1],m3), (to4)[1][3]=(m4)[1][3], \
  655.          VXM3((to4)[2],(m4)[2],m3), (to4)[2][3]=(m4)[2][3], \
  656.          VXM3((to4)[3],(m4)[3],m3), (to4)[3][3]=(m4)[3][3])
  657. #define VXVXVXV4(v0,v1,v2,v3)    \
  658.         (_DET4(v0,v1,v2,v3,0,1,2,3))
  659. #define DET4(m)    \
  660.         (VXVXVXV4((m)[0],(m)[1],(m)[2],(m)[3]))
  661. #define ADJOINT4(to,m)    \
  662.         ( _ADJOINTcol4(to,0,m,1,2,3), \
  663.          __ADJOINTcol4(to,1,m,0,2,3), \
  664.           _ADJOINTcol4(to,2,m,0,1,3), \
  665.          __ADJOINTcol4(to,3,m,0,1,2))
  666. #define _ADJOINTcol4(to,col,m,i1,i2,i3)    \
  667.         ((to)[0][col] =  _DET3(m[i1],m[i2],m[i3], 1,2,3), \
  668.          (to)[1][col] = -_DET3(m[i1],m[i2],m[i3], 0,2,3), \
  669.          (to)[2][col] =  _DET3(m[i1],m[i2],m[i3], 0,1,3), \
  670.          (to)[3][col] = -_DET3(m[i1],m[i2],m[i3], 0,1,2))
  671. #define __ADJOINTcol4(to,col,m,i1,i2,i3)    \
  672.         ((to)[0][col] = -_DET3(m[i1],m[i2],m[i3], 1,2,3), \
  673.          (to)[1][col] =  _DET3(m[i1],m[i2],m[i3], 0,2,3), \
  674.          (to)[2][col] = -_DET3(m[i1],m[i2],m[i3], 0,1,3), \
  675.          (to)[3][col] =  _DET3(m[i1],m[i2],m[i3], 0,1,2))
  676. #define TRANSPOSE2safe(type,to,from) \
  677.         do {type _vec_h_temp_[2][2]; \
  678.             TRANSPOSE2(_vec_h_temp_,from); \
  679.             SETMAT2(to, _vec_h_temp_); \
  680.         } while (0)
  681. #define TRANSPOSE2d(to,from) TRANSPOSE2safe(double,to,from)
  682. #define TRANSPOSE2i(to,from) TRANSPOSE2safe(int,to,from)
  683. #define TRANSPOSE2l(to,from) TRANSPOSE2safe(long,to,from)
  684. #define TRANSPOSE2r(to,from) TRANSPOSE2safe(real,to,from)
  685. #define MXM2safe(type,to,m1,m2) \
  686.         do {type _vec_h_temp_[2][2]; \
  687.             MXM2(_vec_h_temp_,m1,m2); \
  688.             SETMAT2(to, _vec_h_temp_); \
  689.         } while (0)
  690. #define MXM2d(to,m1,m2) MXM2safe(double,to,m1,m2)
  691. #define MXM2i(to,m1,m2) MXM2safe(int,to,m1,m2)
  692. #define MXM2l(to,m1,m2) MXM2safe(long,to,m1,m2)
  693. #define MXM2r(to,m1,m2) MXM2safe(real,to,m1,m2)
  694. #define VXM2safe(type,to,v,m) \
  695.         do {type _vec_h_temp_[2]; \
  696.             VXM2(_vec_h_temp_,v,m); \
  697.             SET2(to, _vec_h_temp_); \
  698.         } while (0)
  699. #define VXM2d(to,v,m) VXM2safe(double,to,v,m)
  700. #define VXM2i(to,v,m) VXM2safe(int,to,v,m)
  701. #define VXM2l(to,v,m) VXM2safe(long,to,v,m)
  702. #define VXM2r(to,v,m) VXM2safe(real,to,v,m)
  703. #define MXV2safe(type,to,m,v) \
  704.         do {type _vec_h_temp_[2]; \
  705.             MXV2(_vec_h_temp_,m,v); \
  706.             SET2(to, _vec_h_temp_); \
  707.         } while (0)
  708. #define MXV2d(to,m,v) MXV2safe(double,to,m,v)
  709. #define MXV2i(to,m,v) MXV2safe(int,to,m,v)
  710. #define MXV2l(to,m,v) MXV2safe(long,to,m,v)
  711. #define MXV2r(to,m,v) MXV2safe(real,to,m,v)
  712. #define XV2safe(type,to,v1) \
  713.         do {type _vec_h_temp_[2]; \
  714.             XV2(_vec_h_temp_,v1); \
  715.             SET2(to, _vec_h_temp_); \
  716.         } while (0)
  717. #define XV2d(to,v1) XV2safe(double,to,v1)
  718. #define XV2i(to,v1) XV2safe(int,to,v1)
  719. #define XV2l(to,v1) XV2safe(long,to,v1)
  720. #define XV2r(to,v1) XV2safe(real,to,v1)
  721. #define V2XM3safe(type,to2,v2,m3) \
  722.         do {type _vec_h_temp_[2]; \
  723.             V2XM3(_vec_h_temp_,v2,m3); \
  724.             SET2(to2, _vec_h_temp_); \
  725.         } while (0)
  726. #define V2XM3d(to2,v2,m3) V2XM3safe(double,to2,v2,m3)
  727. #define V2XM3i(to2,v2,m3) V2XM3safe(int,to2,v2,m3)
  728. #define V2XM3l(to2,v2,m3) V2XM3safe(long,to2,v2,m3)
  729. #define V2XM3r(to2,v2,m3) V2XM3safe(real,to2,v2,m3)
  730. #define M3XV2safe(type,to2,m3,v2) \
  731.         do {type _vec_h_temp_[2]; \
  732.             M3XV2(_vec_h_temp_,m3,v2); \
  733.             SET2(to2, _vec_h_temp_); \
  734.         } while (0)
  735. #define M3XV2d(to2,m3,v2) M3XV2safe(double,to2,m3,v2)
  736. #define M3XV2i(to2,m3,v2) M3XV2safe(int,to2,m3,v2)
  737. #define M3XV2l(to2,m3,v2) M3XV2safe(long,to2,m3,v2)
  738. #define M3XV2r(to2,m3,v2) M3XV2safe(real,to2,m3,v2)
  739. #define ADJOINT2safe(type,to,m) \
  740.         do {type _vec_h_temp_[2][2]; \
  741.             ADJOINT2(_vec_h_temp_,m); \
  742.             SETMAT2(to, _vec_h_temp_); \
  743.         } while (0)
  744. #define ADJOINT2d(to,m) ADJOINT2safe(double,to,m)
  745. #define ADJOINT2i(to,m) ADJOINT2safe(int,to,m)
  746. #define ADJOINT2l(to,m) ADJOINT2safe(long,to,m)
  747. #define ADJOINT2r(to,m) ADJOINT2safe(real,to,m)
  748. #define TRANSPOSE3safe(type,to,from) \
  749.         do {type _vec_h_temp_[3][3]; \
  750.             TRANSPOSE3(_vec_h_temp_,from); \
  751.             SETMAT3(to, _vec_h_temp_); \
  752.         } while (0)
  753. #define TRANSPOSE3d(to,from) TRANSPOSE3safe(double,to,from)
  754. #define TRANSPOSE3i(to,from) TRANSPOSE3safe(int,to,from)
  755. #define TRANSPOSE3l(to,from) TRANSPOSE3safe(long,to,from)
  756. #define TRANSPOSE3r(to,from) TRANSPOSE3safe(real,to,from)
  757. #define MXM3safe(type,to,m1,m2) \
  758.         do {type _vec_h_temp_[3][3]; \
  759.             MXM3(_vec_h_temp_,m1,m2); \
  760.             SETMAT3(to, _vec_h_temp_); \
  761.         } while (0)
  762. #define MXM3d(to,m1,m2) MXM3safe(double,to,m1,m2)
  763. #define MXM3i(to,m1,m2) MXM3safe(int,to,m1,m2)
  764. #define MXM3l(to,m1,m2) MXM3safe(long,to,m1,m2)
  765. #define MXM3r(to,m1,m2) MXM3safe(real,to,m1,m2)
  766. #define VXM3safe(type,to,v,m) \
  767.         do {type _vec_h_temp_[3]; \
  768.             VXM3(_vec_h_temp_,v,m); \
  769.             SET3(to, _vec_h_temp_); \
  770.         } while (0)
  771. #define VXM3d(to,v,m) VXM3safe(double,to,v,m)
  772. #define VXM3i(to,v,m) VXM3safe(int,to,v,m)
  773. #define VXM3l(to,v,m) VXM3safe(long,to,v,m)
  774. #define VXM3r(to,v,m) VXM3safe(real,to,v,m)
  775. #define MXV3safe(type,to,m,v) \
  776.         do {type _vec_h_temp_[3]; \
  777.             MXV3(_vec_h_temp_,m,v); \
  778.             SET3(to, _vec_h_temp_); \
  779.         } while (0)
  780. #define MXV3d(to,m,v) MXV3safe(double,to,m,v)
  781. #define MXV3i(to,m,v) MXV3safe(int,to,m,v)
  782. #define MXV3l(to,m,v) MXV3safe(long,to,m,v)
  783. #define MXV3r(to,m,v) MXV3safe(real,to,m,v)
  784. #define VXV3safe(type,to,v1,v2) \
  785.         do {type _vec_h_temp_[3]; \
  786.             VXV3(_vec_h_temp_,v1,v2); \
  787.             SET3(to, _vec_h_temp_); \
  788.         } while (0)
  789. #define VXV3d(to,v1,v2) VXV3safe(double,to,v1,v2)
  790. #define VXV3i(to,v1,v2) VXV3safe(int,to,v1,v2)
  791. #define VXV3l(to,v1,v2) VXV3safe(long,to,v1,v2)
  792. #define VXV3r(to,v1,v2) VXV3safe(real,to,v1,v2)
  793. #define M2XM3safe(type,to3,m2,m3) \
  794.         do {type _vec_h_temp_[3][3]; \
  795.             M2XM3(_vec_h_temp_,m2,m3); \
  796.             SETMAT3(to3, _vec_h_temp_); \
  797.         } while (0)
  798. #define M2XM3d(to3,m2,m3) M2XM3safe(double,to3,m2,m3)
  799. #define M2XM3i(to3,m2,m3) M2XM3safe(int,to3,m2,m3)
  800. #define M2XM3l(to3,m2,m3) M2XM3safe(long,to3,m2,m3)
  801. #define M2XM3r(to3,m2,m3) M2XM3safe(real,to3,m2,m3)
  802. #define M3XM2safe(type,to3,m3,m2) \
  803.         do {type _vec_h_temp_[3][3]; \
  804.             M3XM2(_vec_h_temp_,m3,m2); \
  805.             SETMAT3(to3, _vec_h_temp_); \
  806.         } while (0)
  807. #define M3XM2d(to3,m3,m2) M3XM2safe(double,to3,m3,m2)
  808. #define M3XM2i(to3,m3,m2) M3XM2safe(int,to3,m3,m2)
  809. #define M3XM2l(to3,m3,m2) M3XM2safe(long,to3,m3,m2)
  810. #define M3XM2r(to3,m3,m2) M3XM2safe(real,to3,m3,m2)
  811. #define V3XM4safe(type,to3,v3,m4) \
  812.         do {type _vec_h_temp_[3]; \
  813.             V3XM4(_vec_h_temp_,v3,m4); \
  814.             SET3(to3, _vec_h_temp_); \
  815.         } while (0)
  816. #define V3XM4d(to3,v3,m4) V3XM4safe(double,to3,v3,m4)
  817. #define V3XM4i(to3,v3,m4) V3XM4safe(int,to3,v3,m4)
  818. #define V3XM4l(to3,v3,m4) V3XM4safe(long,to3,v3,m4)
  819. #define V3XM4r(to3,v3,m4) V3XM4safe(real,to3,v3,m4)
  820. #define M4XV3safe(type,to3,m4,v3) \
  821.         do {type _vec_h_temp_[3]; \
  822.             M4XV3(_vec_h_temp_,m4,v3); \
  823.             SET3(to3, _vec_h_temp_); \
  824.         } while (0)
  825. #define M4XV3d(to3,m4,v3) M4XV3safe(double,to3,m4,v3)
  826. #define M4XV3i(to3,m4,v3) M4XV3safe(int,to3,m4,v3)
  827. #define M4XV3l(to3,m4,v3) M4XV3safe(long,to3,m4,v3)
  828. #define M4XV3r(to3,m4,v3) M4XV3safe(real,to3,m4,v3)
  829. #define ADJOINT3safe(type,to,m) \
  830.         do {type _vec_h_temp_[3][3]; \
  831.             ADJOINT3(_vec_h_temp_,m); \
  832.             SETMAT3(to, _vec_h_temp_); \
  833.         } while (0)
  834. #define ADJOINT3d(to,m) ADJOINT3safe(double,to,m)
  835. #define ADJOINT3i(to,m) ADJOINT3safe(int,to,m)
  836. #define ADJOINT3l(to,m) ADJOINT3safe(long,to,m)
  837. #define ADJOINT3r(to,m) ADJOINT3safe(real,to,m)
  838. #define TRANSPOSE4safe(type,to,from) \
  839.         do {type _vec_h_temp_[4][4]; \
  840.             TRANSPOSE4(_vec_h_temp_,from); \
  841.             SETMAT4(to, _vec_h_temp_); \
  842.         } while (0)
  843. #define TRANSPOSE4d(to,from) TRANSPOSE4safe(double,to,from)
  844. #define TRANSPOSE4i(to,from) TRANSPOSE4safe(int,to,from)
  845. #define TRANSPOSE4l(to,from) TRANSPOSE4safe(long,to,from)
  846. #define TRANSPOSE4r(to,from) TRANSPOSE4safe(real,to,from)
  847. #define MXM4safe(type,to,m1,m2) \
  848.         do {type _vec_h_temp_[4][4]; \
  849.             MXM4(_vec_h_temp_,m1,m2); \
  850.             SETMAT4(to, _vec_h_temp_); \
  851.         } while (0)
  852. #define MXM4d(to,m1,m2) MXM4safe(double,to,m1,m2)
  853. #define MXM4i(to,m1,m2) MXM4safe(int,to,m1,m2)
  854. #define MXM4l(to,m1,m2) MXM4safe(long,to,m1,m2)
  855. #define MXM4r(to,m1,m2) MXM4safe(real,to,m1,m2)
  856. #define VXM4safe(type,to,v,m) \
  857.         do {type _vec_h_temp_[4]; \
  858.             VXM4(_vec_h_temp_,v,m); \
  859.             SET4(to, _vec_h_temp_); \
  860.         } while (0)
  861. #define VXM4d(to,v,m) VXM4safe(double,to,v,m)
  862. #define VXM4i(to,v,m) VXM4safe(int,to,v,m)
  863. #define VXM4l(to,v,m) VXM4safe(long,to,v,m)
  864. #define VXM4r(to,v,m) VXM4safe(real,to,v,m)
  865. #define MXV4safe(type,to,m,v) \
  866.         do {type _vec_h_temp_[4]; \
  867.             MXV4(_vec_h_temp_,m,v); \
  868.             SET4(to, _vec_h_temp_); \
  869.         } while (0)
  870. #define MXV4d(to,m,v) MXV4safe(double,to,m,v)
  871. #define MXV4i(to,m,v) MXV4safe(int,to,m,v)
  872. #define MXV4l(to,m,v) MXV4safe(long,to,m,v)
  873. #define MXV4r(to,m,v) MXV4safe(real,to,m,v)
  874. #define VXVXV4safe(type,to,v1,v2,v3) \
  875.         do {type _vec_h_temp_[4]; \
  876.             VXVXV4(_vec_h_temp_,v1,v2,v3); \
  877.             SET4(to, _vec_h_temp_); \
  878.         } while (0)
  879. #define VXVXV4d(to,v1,v2,v3) VXVXV4safe(double,to,v1,v2,v3)
  880. #define VXVXV4i(to,v1,v2,v3) VXVXV4safe(int,to,v1,v2,v3)
  881. #define VXVXV4l(to,v1,v2,v3) VXVXV4safe(long,to,v1,v2,v3)
  882. #define VXVXV4r(to,v1,v2,v3) VXVXV4safe(real,to,v1,v2,v3)
  883. #define M3XM4safe(type,to4,m3,m4) \
  884.         do {type _vec_h_temp_[4][4]; \
  885.             M3XM4(_vec_h_temp_,m3,m4); \
  886.             SETMAT4(to4, _vec_h_temp_); \
  887.         } while (0)
  888. #define M3XM4d(to4,m3,m4) M3XM4safe(double,to4,m3,m4)
  889. #define M3XM4i(to4,m3,m4) M3XM4safe(int,to4,m3,m4)
  890. #define M3XM4l(to4,m3,m4) M3XM4safe(long,to4,m3,m4)
  891. #define M3XM4r(to4,m3,m4) M3XM4safe(real,to4,m3,m4)
  892. #define M4XM3safe(type,to4,m4,m3) \
  893.         do {type _vec_h_temp_[4][4]; \
  894.             M4XM3(_vec_h_temp_,m4,m3); \
  895.             SETMAT4(to4, _vec_h_temp_); \
  896.         } while (0)
  897. #define M4XM3d(to4,m4,m3) M4XM3safe(double,to4,m4,m3)
  898. #define M4XM3i(to4,m4,m3) M4XM3safe(int,to4,m4,m3)
  899. #define M4XM3l(to4,m4,m3) M4XM3safe(long,to4,m4,m3)
  900. #define M4XM3r(to4,m4,m3) M4XM3safe(real,to4,m4,m3)
  901. #define ADJOINT4safe(type,to,m) \
  902.         do {type _vec_h_temp_[4][4]; \
  903.             ADJOINT4(_vec_h_temp_,m); \
  904.             SETMAT4(to, _vec_h_temp_); \
  905.         } while (0)
  906. #define ADJOINT4d(to,m) ADJOINT4safe(double,to,m)
  907. #define ADJOINT4i(to,m) ADJOINT4safe(int,to,m)
  908. #define ADJOINT4l(to,m) ADJOINT4safe(long,to,m)
  909. #define ADJOINT4r(to,m) ADJOINT4safe(real,to,m)
  910. #endif /* VEC_H */
  911.