home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / demos / gpc / matrix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-15  |  21.7 KB  |  781 lines

  1. /* $XConsortium: matrix.c,v 5.1 91/02/16 10:07:44 rws Exp $ */
  2. /***********************************************************
  3. Copyright(c) 1989,1990, 1991 by Sun Microsystems, Inc. and the X Consortium at M.I.T.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its
  8. documentation for any purpose and without fee is hereby granted,
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in
  11. supporting documentation, and that the names of Sun Microsystems,
  12. the X Consortium, and MIT not be used in advertising or publicity
  13. pertaining to distribution of the software without specific, written
  14. prior permission.
  15.  
  16. SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  17. INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
  18. SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
  19. DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  21. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  22. SOFTWARE.
  23.  
  24. ******************************************************************/
  25.  
  26. /*--------------------------------------------------------------------*\
  27. |
  28. |  Copyright (C) 1989,1990, 1991, National Computer Graphics Association
  29. |
  30. |  Permission is granted to any individual or institution to use, copy, or
  31. |  redistribute this software so long as it is not sold for profit, provided
  32. |  this copyright notice is retained.
  33. |
  34. |                         Developed for the
  35. |                National Computer Graphics Association
  36. |                         2722 Merrilee Drive
  37. |                         Fairfax, VA  22031
  38. |                           (703) 698-9600
  39. |
  40. |                                by
  41. |                 SimGraphics Engineering Corporation
  42. |                    1137 Huntington Drive  Unit A
  43. |                      South Pasadena, CA  91030
  44. |                           (213) 255-0900
  45. |---------------------------------------------------------------------
  46. |
  47. | Author       :    nde / SimGraphics Engineering Corportation
  48. |
  49. | File         :    matrix.c
  50. | Date         :    3/16/89
  51. | Project      :    PLB
  52. | Description    :    Matrix formation utilities
  53. | Status       :    Version 1.0
  54. |
  55. | Revisions    :    
  56. |
  57. |    6/28/89        Added matcat.
  58. |
  59. \*--------------------------------------------------------------------*/
  60.  
  61. /*--------------------------------------------------------------------*\
  62. |    Table of Contents
  63. |
  64. |    mx_identity(matrix4)
  65. |        :    Generate an identity matrix
  66. |    void mx_rot_x(float, *float)
  67. |        :    Generate an X rotation matrix
  68. |    mx_rot_y(float, *float)
  69. |        :    Generate a Y rotation matrix
  70. |    mx_rot_z(float, *float)
  71. |        :    Generate a Z rotation matrix
  72. |    mx_scale(float, float, float, *float)
  73. |        :    Generate a scale matrix
  74. |    mx_translate(float, float, float, *float)
  75. |        :    Generate a translation matrix
  76. |    mx_euler_matrix(float, float, float, *float)
  77. |        :    Generate an euler angles  matrix
  78. |    mx_mult(*float, *float, *float)
  79. |        :    Multiply two 4x4 matrices
  80. |    mx_44mult(*float, *float, *float)
  81. |        :    Multiply two 4x4 matrices
  82. |    mx_invert(*float, *float)
  83. |        :    do a GEBS invert of a 4x4 with pivoting
  84. |    int matcat(mat_from, mat_to, concat)
  85. |        :    Concatenate the mat_from and mat_to according to
  86. |    int copyvec3f(a,b)
  87. |        :    copy a into b
  88. |    double dotvec3f(a,b)
  89. |        :    Compute and return the dot product of a and b
  90. |    int crossvec3f(a,b,c)
  91. |        :    Cross a with b return in c
  92. |    int unitvec(vector3)
  93. |        :    Normalize the given vector.
  94. |    int copy44f(mata,matb)
  95. |        :    copy mata into matb (4x4 matrix of type float)
  96. |    print44f(mat)
  97. |        :    print a 4x4 matrix of type float
  98. |    mx_comp(mat1,mat2)
  99. |        :    compares two 4x4 matrix returns TRUE if identical.
  100. |
  101. \*--------------------------------------------------------------------*/
  102.  
  103. /*--------------------------------------------------------------------*\
  104. |    Include files
  105. \*--------------------------------------------------------------------*/
  106. #include <stdio.h>
  107. #include <math.h>
  108. #include "biftypes.h"
  109. #include "bifbuild.h"
  110. #include "bifmacro.h"
  111. #include "ph_map.h"
  112.  
  113. /*--------------------------------------------------------------------*\
  114. |    Local #define
  115. \*--------------------------------------------------------------------*/
  116. #define RADIANS(x) 0.01745329 * (x)
  117. #ifndef FALSE
  118. #define FALSE 0
  119. #endif
  120. #ifndef TRUE
  121. #define TRUE (!FALSE)
  122. #endif
  123.  
  124. /*--------------------------------------------------------------------*\
  125. |    Local global variables
  126. \*--------------------------------------------------------------------*/
  127. typedef float Vector4[4];
  128.  
  129.  
  130. /* ---------------------------------------------------------------------*\
  131. | BEGIN PROCEDURE CODE                                                   |
  132. \*--------------------------------------------------------------------- */
  133.  
  134. /*--------------------------------------------------------------------*\
  135. | Procedure    :    mx_identity(matrix4)
  136. |----------------------------------------------------------------------
  137. | Description    :    Generate an identity matrix
  138. |----------------------------------------------------------------------
  139. | Return    :    
  140. \*--------------------------------------------------------------------*/
  141. mx_identity ( mx )
  142. float mx[4][4];
  143.  
  144. {
  145.  
  146.     mx[ 0 ][ 0 ] =  1.0;
  147.     mx[ 0 ][ 1 ] =  0.0;
  148.     mx[ 0 ][ 2 ] =  0.0;
  149.     mx[ 0 ][ 3 ] =  0.0;
  150.  
  151.     mx[ 1 ][ 0 ] =  0.0;
  152.     mx[ 1 ][ 1 ] =  1.0;
  153.     mx[ 1 ][ 2 ] =  0.0;
  154.     mx[ 1 ][ 3 ] =  0.0;
  155.  
  156.     mx[ 2 ][ 0 ] =  0.0;
  157.     mx[ 2 ][ 1 ] =  0.0;
  158.     mx[ 2 ][ 2 ] =  1.0;
  159.     mx[ 2 ][ 3 ] =  0.0;
  160.  
  161.     mx[ 3 ][ 0 ] =  0.0;
  162.     mx[ 3 ][ 1 ] =  0.0;
  163.     mx[ 3 ][ 2 ] =  0.0;
  164.     mx[ 3 ][ 3 ] =  1.0;
  165.  
  166. }/* End mx_identity */
  167.  
  168. /*--------------------------------------------------------------------*\
  169. | Procedure    :    void mx_rot_x(float, *float)
  170. |-----------------------------------------------------------------------
  171. | Description    :    Generate an X rotation matrix
  172. |-----------------------------------------------------------------------
  173. | Return    :    
  174. \*--------------------------------------------------------------------*/
  175. mx_rot_x ( angle, mx )
  176. float angle;
  177. Pmatrix3 mx;
  178.  
  179. {/* mx_rot_x */
  180.  
  181.     float r_angle;
  182.     float cos_rho, sin_rho;
  183.  
  184.     r_angle = RADIANS( angle );
  185.     cos_rho = cos( r_angle );
  186.     sin_rho = sin( r_angle );
  187.  
  188.     mx[ 0 ][ 0 ] =  1.0;
  189.     mx[ 0 ][ 1 ] =  0.0;
  190.     mx[ 0 ][ 2 ] =  0.0;
  191.     mx[ 0 ][ 3 ] =  0.0;
  192.  
  193.     mx[ 1 ][ 0 ] =  0.0;
  194.     mx[ 1 ][ 1 ] =  cos_rho;
  195.     mx[ 1 ][ 2 ] =  sin_rho;
  196.     mx[ 1 ][ 3 ] =  0.0;
  197.  
  198.     mx[ 2 ][ 0 ] =  0.0;
  199.     mx[ 2 ][ 1 ] = -sin_rho;
  200.     mx[ 2 ][ 2 ] =  cos_rho;
  201.     mx[ 2 ][ 3 ] =  0.0;
  202.  
  203.     mx[ 3 ][ 0 ] =  0.0;
  204.     mx[ 3 ][ 1 ] =  0.0;
  205.     mx[ 3 ][ 2 ] =  0.0;
  206.     mx[ 3 ][ 3 ] =  1.0;
  207.  
  208. }/* mx_rot_x */
  209.  
  210. /*--------------------------------------------------------------------*\
  211. | Procedure    :    mx_rot_y(float, *float)
  212. |-----------------------------------------------------------------------
  213. | Description    :    Generate a Y rotation matrix
  214. |-----------------------------------------------------------------------
  215. | Return    :    
  216. \*--------------------------------------------------------------------*/
  217. mx_rot_y ( angle, mx )
  218. float angle;
  219. Pmatrix3 mx;
  220.  
  221. {/* mx_rot_y */
  222.  
  223.     float r_angle;
  224.     float cos_rho, sin_rho;
  225.  
  226.     r_angle = RADIANS( angle );
  227.     cos_rho = cos( r_angle );
  228.     sin_rho = sin( r_angle );
  229.  
  230.     mx[ 0 ][ 0 ] =  cos_rho;
  231.     mx[ 0 ][ 1 ] =  0.0;
  232.     mx[ 0 ][ 2 ] = -sin_rho;
  233.     mx[ 0 ][ 3 ] =  0.0;
  234.  
  235.     mx[ 1 ][ 0 ] =  0.0;
  236.     mx[ 1 ][ 1 ] =  1.0;
  237.     mx[ 1 ][ 2 ] =  0.0;
  238.     mx[ 1 ][ 3 ] =  0.0;
  239.  
  240.     mx[ 2 ][ 0 ] =  sin_rho;
  241.     mx[ 2 ][ 1 ] =  0.0;
  242.     mx[ 2 ][ 2 ] =  cos_rho;
  243.     mx[ 2 ][ 3 ] =  0.0;
  244.  
  245.     mx[ 3 ][ 0 ] =  0.0;
  246.     mx[ 3 ][ 1 ] =  0.0;
  247.     mx[ 3 ][ 2 ] =  0.0;
  248.     mx[ 3 ][ 3 ] =  1.0;
  249.  
  250. }/* mx_rot_y */
  251.  
  252. /*--------------------------------------------------------------------*\
  253. | Procedure    :    mx_rot_z(float, *float)
  254. |-----------------------------------------------------------------------
  255. | Description    :    Generate a Z rotation matrix
  256. |-----------------------------------------------------------------------
  257. | Return    :    
  258. \*--------------------------------------------------------------------*/
  259. mx_rot_z ( angle, mx )
  260. float angle;
  261. Pmatrix3 mx;
  262.  
  263. {/* mx_rot_z */
  264.  
  265.     float r_angle;
  266.     float cos_rho, sin_rho;
  267.  
  268.     r_angle = RADIANS( angle );
  269.     cos_rho = cos( r_angle );
  270.     sin_rho = sin( r_angle );
  271.  
  272.     mx[ 0 ][ 0 ] =  cos_rho;
  273.     mx[ 0 ][ 1 ] =  sin_rho;
  274.     mx[ 0 ][ 2 ] =  0.0;
  275.     mx[ 0 ][ 3 ] =  0.0;
  276.  
  277.     mx[ 1 ][ 0 ] = -sin_rho;
  278.     mx[ 1 ][ 1 ] =  cos_rho;
  279.     mx[ 1 ][ 2 ] =  0.0;
  280.     mx[ 1 ][ 3 ] =  0.0;
  281.  
  282.     mx[ 2 ][ 0 ] =  0.0;
  283.     mx[ 2 ][ 1 ] =  0.0;
  284.     mx[ 2 ][ 2 ] =  1.0;
  285.     mx[ 2 ][ 3 ] =  0.0;
  286.  
  287.     mx[ 3 ][ 0 ] =  0.0;
  288.     mx[ 3 ][ 1 ] =  0.0;
  289.     mx[ 3 ][ 2 ] =  0.0;
  290.     mx[ 3 ][ 3 ] =  1.0;
  291.  
  292. }/* mx_rot_z */
  293.  
  294. /*--------------------------------------------------------------------*\
  295. | Procedure    :    mx_scale(float, float, float, *float)
  296. |-----------------------------------------------------------------------
  297. | Description    :    Generate a scale matrix
  298. |-----------------------------------------------------------------------
  299. | Return    :    
  300. \*--------------------------------------------------------------------*/
  301. mx_scale ( sx, sy, sz, mx )
  302. float sx;
  303. float sy;
  304. float sz;
  305. Pmatrix3 mx;
  306.  
  307. {/* mx_scale */
  308.  
  309.     mx[ 0 ][ 0 ] =  sx;
  310.     mx[ 0 ][ 1 ] =  0.0;
  311.     mx[ 0 ][ 2 ] =  0.0;
  312.     mx[ 0 ][ 3 ] =  0.0;
  313.  
  314.     mx[ 1 ][ 0 ] =  0.0;
  315.     mx[ 1 ][ 1 ] =  sy;
  316.     mx[ 1 ][ 2 ] =  0.0;
  317.     mx[ 1 ][ 3 ] =  0.0;
  318.  
  319.     mx[ 2 ][ 0 ] =  0.0;
  320.     mx[ 2 ][ 1 ] =  0.0;
  321.     mx[ 2 ][ 2 ] =  sz;
  322.     mx[ 2 ][ 3 ] =  0.0;
  323.  
  324.     mx[ 3 ][ 0 ] =  0.0;
  325.     mx[ 3 ][ 1 ] =  0.0;
  326.     mx[ 3 ][ 2 ] =  0.0;
  327.     mx[ 3 ][ 3 ] =  1.0;
  328.  
  329. }/* mx_scale */
  330.  
  331. /*--------------------------------------------------------------------*\
  332. | Procedure    :    mx_translate(float, float, float, *float)
  333. |-----------------------------------------------------------------------
  334. | Description    :    Generate a translation matrix
  335. |-----------------------------------------------------------------------
  336. | Return    :    
  337. \*--------------------------------------------------------------------*/
  338. mx_translate ( tx, ty, tz, mx )
  339. float tx;
  340. float ty;
  341. float tz;
  342. Pmatrix3 mx;
  343.  
  344. {/* mx_translate */
  345.  
  346.     mx[ 0 ][ 0 ] =  1.0;
  347.     mx[ 0 ][ 1 ] =  0.0;
  348.     mx[ 0 ][ 2 ] =  0.0;
  349.     mx[ 0 ][ 3 ] =  0.0;
  350.  
  351.     mx[ 1 ][ 0 ] =  0.0;
  352.     mx[ 1 ][ 1 ] =  1.0;
  353.     mx[ 1 ][ 2 ] =  0.0;
  354.     mx[ 1 ][ 3 ] =  0.0;
  355.  
  356.     mx[ 2 ][ 0 ] =  0.0;
  357.     mx[ 2 ][ 1 ] =  0.0;
  358.     mx[ 2 ][ 2 ] =  1.0;
  359.     mx[ 2 ][ 3 ] =  0.0;
  360.  
  361.     mx[ 3 ][ 0 ] =  tx;
  362.     mx[ 3 ][ 1 ] =  ty;
  363.     mx[ 3 ][ 2 ] =  tz;
  364.     mx[ 3 ][ 3 ] =  1.0;
  365.  
  366. }/* mx_translate */
  367.  
  368. /*--------------------------------------------------------------------*\
  369. | Procedure    :    mx_euler_matrix(float, float, float, *float)
  370. |-----------------------------------------------------------------------
  371. | Description    :    Generate an euler angles  matrix
  372. |-----------------------------------------------------------------------
  373. | Return    :    
  374. \*--------------------------------------------------------------------*/
  375. mx_euler_matrix ( ax, ay, az, mat )
  376. /*                                                                    */
  377. /*                                                                    */
  378. /*                                                                    */
  379. float ax, ay, az;
  380. Pmatrix3 mat;
  381.  
  382. {/* mx_euler_matrix */
  383.  
  384.     float rax, ray, raz;
  385.     float sin_ax, sin_ay, sin_az;
  386.     float cos_ax, cos_ay, cos_az;
  387.  
  388.     rax = RADIANS( ax );
  389.     ray = RADIANS( ay );
  390.     raz = RADIANS( az );
  391.     sin_ax = sin( rax );
  392.     sin_ay = sin( ray );
  393.     sin_az = sin( raz );
  394.     cos_ax = cos( rax );
  395.     cos_ay = cos( ray );
  396.     cos_az = cos( raz );
  397.  
  398.     mat[ 0 ][ 0 ] =  cos_ay*cos_az;
  399.     mat[ 0 ][ 1 ] =  cos_ay*sin_az;
  400.     mat[ 0 ][ 2 ] = -sin_ay;
  401.     mat[ 0 ][ 3 ] =  0.;
  402.  
  403.     mat[ 1 ][ 0 ] =  sin_ax*sin_ay*cos_az - cos_ax*sin_az;
  404.     mat[ 1 ][ 1 ] =  sin_ax*sin_ay*sin_az + cos_ax*cos_az;
  405.     mat[ 1 ][ 2 ] =  sin_ax*cos_ay;
  406.     mat[ 1 ][ 3 ] =  0.;
  407.  
  408.     mat[ 2 ][ 0 ] =  cos_ax*sin_ay*cos_az + sin_ax*sin_az;
  409.     mat[ 2 ][ 1 ] =  cos_ax*sin_ay*sin_az - sin_ax*cos_az;
  410.     mat[ 2 ][ 2 ] =  cos_ax*cos_ay;
  411.     mat[ 2 ][ 3 ] =  0.;
  412.  
  413.     mat[ 3 ][ 0 ] =  0.;
  414.     mat[ 3 ][ 1 ] =  0.;
  415.     mat[ 3 ][ 2 ] =  0.;
  416.     mat[ 3 ][ 3 ] =  1.;
  417.  
  418. }/* mx_euler_matrix */
  419.  
  420. /*--------------------------------------------------------------------*\
  421. | Procedure    :    mx_mult(*float, *float, *float)
  422. |-----------------------------------------------------------------------
  423. | Description    :    Multiply two 4x4 matrices
  424. |-----------------------------------------------------------------------
  425. | Return    :    
  426. \*--------------------------------------------------------------------*/
  427. mx_mult(matrix1,matrix2,result)
  428. Pmatrix3 matrix1,matrix2,result;
  429. {
  430.     float *row11,*row12,*row13,*row14;
  431.     float *row21,*row22,*row23,*row24;
  432.  
  433.     row11 = matrix1[0];
  434.     row12 = matrix1[1];
  435.     row13 = matrix1[2];
  436.     row14 = matrix1[3];
  437.  
  438.     row21 = result[0];
  439.     row22 = result[1];
  440.     row23 = result[2];
  441.     row24 = result[3];
  442.  
  443.     mx_44mult(matrix2,row11,row21);
  444.     mx_44mult(matrix2,row12,row22);
  445.     mx_44mult(matrix2,row13,row23);
  446.     mx_44mult(matrix2,row14,row24);
  447. }
  448.  
  449. /*--------------------------------------------------------------------*\
  450. | Procedure    :    mx_44mult(*float, *float, *float)
  451. |-----------------------------------------------------------------------
  452. | Description    :    Multiply two 4x4 matrices
  453. |-----------------------------------------------------------------------
  454. | Return    :    
  455. \*--------------------------------------------------------------------*/
  456. mx_44mult(matrix,vector,result)
  457. Pmatrix3 matrix;
  458. Vector4 vector;
  459. Vector4 result;
  460. {
  461.     float *row1,*row2,*row3,*row4;
  462.     
  463.     row1 = matrix[0];
  464.     row2 = matrix[1];
  465.     row3 = matrix[2];
  466.     row4 = matrix[3];
  467.  
  468.     result[0] = row1[0] * vector[0] + row2[0] * vector[1] +
  469.                 row3[0] * vector[2] + row4[0] * vector[3];
  470.  
  471.     result[1] = row1[1] * vector[0] + row2[1] * vector[1] +
  472.                 row3[1] * vector[2] + row4[1] * vector[3];
  473.  
  474.     result[2] = row1[2] * vector[0] + row2[2] * vector[1] +
  475.                 row3[2] * vector[2] + row4[2] * vector[3];
  476.  
  477.     result[3] = row1[3] * vector[0] + row2[3] * vector[1] +
  478.                 row3[3] * vector[2] + row4[3] * vector[3];
  479. }
  480.  
  481.  
  482. /*--------------------------------------------------------------------*\
  483. | Procedure    :    mx_invert(*float, *float)
  484. |-----------------------------------------------------------------------
  485. | Description    :    do a GEBS invert of a 4x4 with pivoting
  486. |-----------------------------------------------------------------------
  487. | Return    :    
  488. \*--------------------------------------------------------------------*/
  489. /* Invert the Matrix */
  490. mx_invert(matrix, inverse)
  491. Pmatrix3 matrix, inverse;
  492. {
  493.     float work_space[4][8], a;
  494.     register int j, jr, k, pivot;
  495.     int i, row[4];
  496.  
  497.     /* Initialize */
  498.     for (j=0; j<4; j++)
  499.     {
  500.         for (k=0; k<4; k++)
  501.         {
  502.             work_space[j][k] = matrix[j][k];
  503.             work_space[j][4+k] = 0.0;
  504.         }
  505.         work_space[j][4+j] = 1.0;
  506.         row[j] = j;
  507.     }
  508.  
  509.     /* Eliminate columns */
  510.     for (i=0; i < 4; i++)
  511.     {
  512.  
  513.         /* Find pivot */
  514.         k = i;
  515.         a = fabs(work_space[row[k]][k]);
  516.         for (j=i+1; j < 4; j++)
  517.         {
  518.             jr = row[j];
  519.             if (a < fabs(work_space[jr][i]))
  520.             {
  521.                 k = j;
  522.                 a = fabs(work_space[jr][i]);
  523.             }
  524.         }
  525.  
  526.         /* Swap PIVOT row with row I */
  527.         pivot = row[k];
  528.         row[k] = row[i];
  529.         row[i] = pivot;
  530.  
  531.         /* Normalize pivot row */
  532.         a = work_space[pivot][i];
  533.         if (a == 0.0) return(0); /* Singular */
  534.         work_space[pivot][i] = 1.0;
  535.         for (k=i+1; k < 8; k++) work_space[pivot][k] /= a;
  536.  
  537.         /* Eliminate pivot from all remaining rows */
  538.         for (j = i+1; j < 4; j++)
  539.         {
  540.             jr = row[j];
  541.             a = - work_space[jr][i];
  542.             if (a == 0.0) continue;
  543.             work_space[jr][i] = 0.0;
  544.             for (k = i+1; k < 8; k++)
  545.                 work_space[jr][k] += (a * work_space[pivot][k]);
  546.         }
  547.     }
  548.  
  549.     /* Back solve */
  550.     for (i = 3; i > 0; --i)
  551.     {
  552.         pivot = row[i];
  553.         for (j = i-1; j >= 0; --j)
  554.         {
  555.             jr = row[j];
  556.             a = work_space[jr][i];
  557.             for (k=i; k<8; k++)
  558.                 work_space[jr][k] -= (a * work_space[pivot][k]);
  559.         }
  560.     }
  561.  
  562.     /* Copy inverse back into I */
  563.     for (j=0; j<4; j++)
  564.     {
  565.         jr = row[j];
  566.         for (k=0; k<4; k++)
  567.         {
  568.             inverse[j][k] = work_space[jr][k+4];
  569.         }
  570.     }
  571.  
  572.     return(1);
  573. }
  574.  
  575. /*--------------------------------------------------------------------*\
  576. | Procedure    :    int matcat(mat_from, mat_to, concat)
  577. |---------------------------------------------------------------------
  578. | Description    :    Concatenate the mat_from and mat_to according to
  579. |            concat.  Store the result in mat_to.
  580. |---------------------------------------------------------------------
  581. | Return    :    Error Code ( -1 if error , 0 else)
  582. \*--------------------------------------------------------------------*/
  583. int matcat(mat_from, mat_to, concat)
  584. Pmatrix3 mat_from, mat_to;
  585. int concat;
  586.  
  587. {
  588.     int retCode;
  589.     Matrix4 mx;
  590.  
  591.     /* We don't like NULL pointers no, no, no */
  592.     if ( mat_from == NULL || mat_to == NULL )
  593.         retCode = -1;
  594.     else
  595.     {
  596.         retCode = 0;
  597.         switch( concat )
  598.         {
  599.         case BIF_PRECONCAT    :
  600.             /*--------------------------------------------*\
  601.             |  Preconcat  IS premult  because C stores the 
  602.             |  transpose of the matrix (Relative to PHIGS).
  603.             \*--------------------------------------------*/
  604.             mx_mult( mat_from, mat_to, mx );
  605.             copy44f( mx, mat_to);
  606.             break;
  607.     
  608.         case BIF_POSTCONCAT    :
  609.             /*--------------------------------------------*\
  610.             |  Postoncat IS postmult because C stores the 
  611.             |  transpose of the matrix (Relative to PHIGS).
  612.             \*--------------------------------------------*/
  613.             mx_mult( mat_to, mat_from, mx );
  614.             copy44f( mx, mat_to);
  615.             break;
  616.     
  617.         case BIF_REPLACE    :
  618.             copy44f( mat_from, mat_to);
  619.             break;
  620.  
  621.         default:
  622.             retCode = -1;
  623.         }
  624.     }
  625.  
  626.     /* Return */
  627.     return(retCode);
  628. } /* End matcat() */
  629.  
  630. /*--------------------------------------------------------------------*\
  631. | Procedure    :    int copyvec3f(a,b)
  632. |---------------------------------------------------------------------
  633. | Description    :    copy a into b
  634. |---------------------------------------------------------------------
  635. | Return    :    Error Code 0 --> A.O.K
  636. \*--------------------------------------------------------------------*/
  637. int copyvec3f(a,b)
  638. vector3 a; /* Input */
  639. vector3 b; /* Input */
  640. {
  641.     /*------------------------------------------------------------*\
  642.     |    Copy the Vector
  643.     \*------------------------------------------------------------*/
  644.     b[0] = a[0];
  645.     b[1] = a[1];
  646.     b[2] = a[2];
  647.  
  648.     /*------------------------------------------------------------*\
  649.     |    What could go wrong???  (Could check for NULL, nyah.)
  650.     \*------------------------------------------------------------*/
  651.     return(0);
  652. } /* End copyvec3f() */
  653.  
  654. /*--------------------------------------------------------------------*\
  655. | Procedure    :    double dotvec3f(a,b)
  656. |---------------------------------------------------------------------
  657. | Description    :    Compute and return the dot product of a and b
  658. |---------------------------------------------------------------------
  659. | Return    :    The dot-product (double)
  660. \*--------------------------------------------------------------------*/
  661. double dotvec3f(a,b)
  662. vector3 a, b;
  663.  
  664. {
  665.     /*------------------------------------------------------------*\
  666.     |    Compute the Dot Product
  667.     \*------------------------------------------------------------*/
  668.     return( (double)(    (double)a[0] * (double)b[0] +
  669.                 (double)a[1] * (double)b[1] +
  670.                 (double)a[2] * (double)b[2] ) );
  671. } /* End dotvec3f() */
  672.  
  673. /*--------------------------------------------------------------------*\
  674. | Procedure    :    int crossvec3f(a,b,c)
  675. |---------------------------------------------------------------------
  676. | Description    :    Cross a with b return in c
  677. |---------------------------------------------------------------------
  678. | Return    :    Error Code 0 --> A.O.K
  679. \*--------------------------------------------------------------------*/
  680. int crossvec3f(a,b,c)
  681. vector3 a, b; /* Input */
  682. vector3 c; /* Input */
  683.  
  684. {
  685.     /*------------------------------------------------------------*\
  686.     |    Compute the Cross Product
  687.     \*------------------------------------------------------------*/
  688.     c[0] =  (a[1] * b[2] - a[2] * b[1]);
  689.     c[1] = -(a[0] * b[2] - a[2] * b[0]);
  690.     c[2] =  (a[0] * b[1] - a[1] * b[0]);
  691.  
  692.     /*------------------------------------------------------------*\
  693.     |    What could go wrong???  (Could check for NULL, nyah.)
  694.     \*------------------------------------------------------------*/
  695.     return(0);
  696. } /* End crossvec3f() */
  697.  
  698. /*--------------------------------------------------------------------*\
  699. | Procedure    :    int unitvec(vector3)
  700. |---------------------------------------------------------------------
  701. | Description    :    Normalize the given vector.
  702. |---------------------------------------------------------------------
  703. | Return    :    Error Code (not implemented)
  704. \*--------------------------------------------------------------------*/
  705. int unitvec3f(vector)
  706. vector3 vector;
  707.  
  708. {
  709.     double len, total;
  710.     total = (double)vector[0] * (double)vector[0] +
  711.             (double)vector[1] * (double)vector[1] +
  712.             (double)vector[2] * (double)vector[2] ;
  713.  
  714.     len = sqrt(    total );
  715.  
  716.     if ( len != 0. )
  717.     {
  718.         len = 1/len;
  719.         vector[0] = vector[0] * len;
  720.         vector[1] = vector[1] * len;
  721.         vector[2] = vector[2] * len;
  722.     }
  723. } /* End unitvec3f() */
  724.  
  725. /*----------------------------------------------------------------------*\
  726. | Procedure    :    int copy44f(mata,matb)
  727. |------------------------------------------------------------------------
  728. | Description    :    copy mata into matb (4x4 matrix of type float)
  729. |------------------------------------------------------------------------
  730. | Return    :    Error Code ( -1 if error , 0 else)
  731. \*----------------------------------------------------------------------*/
  732. copy44f(mata,matb)
  733. float mata[][4], matb[][4];
  734. {
  735.     int retCode;
  736.  
  737.     if ( mata == NULL || matb == NULL )
  738.         retCode = -1;
  739.     else
  740.     {
  741.         retCode = 0;
  742.         Cpmatrix44(mata,matb);
  743.     }
  744.     return(retCode);
  745. }
  746.  
  747. /*----------------------------------------------------------------------*\
  748. | Procedure    :    print44f(mat)
  749. |------------------------------------------------------------------------
  750. | Description    :    print a 4x4 matrix of type float
  751. |------------------------------------------------------------------------
  752. | Return    :    void
  753. \*----------------------------------------------------------------------*/
  754. void print44f(mat)
  755. float mat[4][4];
  756. {
  757.     PRINT_MATRIX44f(mat);
  758. }
  759. /*----------------------------------------------------------------------*\
  760. | Procedure    :    mx_comp(mat1,mat2)
  761. |------------------------------------------------------------------------
  762. | Description    :    compares two 4x4 matrix returns TRUE if identical.
  763. |------------------------------------------------------------------------
  764. | Return    :    TRUE | FAULSE
  765. \*----------------------------------------------------------------------*/
  766. int mx_comp(mat1,mat2)
  767. float mat1[4][4];
  768. float mat2[4][4];
  769. {
  770.     int i,j,return_code;
  771.     return_code = TRUE;
  772.     for(i=0;i<4;i++)
  773.     for(j=0;j<4;j++)
  774.     if (mat1[i][j] != mat2[i][j])
  775.     {
  776.         return_code = FALSE;
  777.         break;
  778.     }
  779.     return(return_code);
  780. }
  781.