home *** CD-ROM | disk | FTP | other *** search
/ NEXT Generation 27 / NEXT27.iso / pc / demos / emperor / dx3.exe / SDK / SAMPLES / MISC / D3DMATH.C < prev    next >
C/C++ Source or Header  |  1996-08-28  |  4KB  |  180 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File: d3dmath.c
  6.  *
  7.  ***************************************************************************/
  8.  
  9. #include <d3d.h>
  10. #include <math.h>
  11.  
  12. /*
  13.  * Normalises the vector v
  14.  */
  15. LPD3DVECTOR 
  16. D3DVECTORNormalise(LPD3DVECTOR v)
  17. {
  18.     float vx, vy, vz, inv_mod;
  19.     vx = v->x;
  20.     vy = v->y;
  21.     vz = v->z;
  22.     if ((vx == 0) && (vy == 0) && (vz == 0))
  23.         return v;
  24.     inv_mod = (float)(1.0 / sqrt(vx * vx + vy * vy + vz * vz));
  25.     v->x = vx * inv_mod;
  26.     v->y = vy * inv_mod;
  27.     v->z = vz * inv_mod;
  28.     return v;
  29. }
  30.  
  31.  
  32. /*
  33.  * Calculates cross product of a and b.
  34.  */
  35. LPD3DVECTOR 
  36. D3DVECTORCrossProduct(LPD3DVECTOR lpd, LPD3DVECTOR lpa, LPD3DVECTOR lpb)
  37. {
  38.  
  39.     lpd->x = lpa->y * lpb->z - lpa->z * lpb->y;
  40.     lpd->y = lpa->z * lpb->x - lpa->x * lpb->z;
  41.     lpd->z = lpa->x * lpb->y - lpa->y * lpb->x;
  42.     return lpd;
  43. }
  44.  
  45.  
  46. /*
  47.  * lpDst = lpSrc1 * lpSrc2
  48.  * lpDst can be equal to lpSrc1 or lpSrc2
  49.  */
  50. LPD3DMATRIX MultiplyD3DMATRIX(LPD3DMATRIX lpDst, LPD3DMATRIX lpSrc1, 
  51.                               LPD3DMATRIX lpSrc2)
  52. {
  53.     D3DVALUE M1[4][4], M2[4][4], D[4][4];
  54.     int i, r, c;
  55.  
  56.     memcpy(&M1[0][0], lpSrc1, sizeof(D3DMATRIX));
  57.     memcpy(&M2[0][0], lpSrc2, sizeof(D3DMATRIX));
  58.     for (r = 0; r < 4; r++) {
  59.         for (c = 0; c < 4; c++) {
  60.             D[r][c] = (float)0.0;
  61.             for (i = 0; i < 4; i++)
  62.                 D[r][c] += M1[r][i] * M2[i][c];
  63.         }
  64.     }
  65.     memcpy(lpDst, &D[0][0], sizeof(D3DMATRIX));
  66.     return lpDst;
  67. }
  68.  
  69.  
  70.  
  71. /*
  72.  * -1 d = a
  73.  */
  74. LPD3DMATRIX 
  75. D3DMATRIXInvert(LPD3DMATRIX d, LPD3DMATRIX a)
  76. {
  77.     d->_11 = a->_11;
  78.     d->_12 = a->_21;
  79.     d->_13 = a->_31;
  80.     d->_14 = a->_14;
  81.  
  82.     d->_21 = a->_12;
  83.     d->_22 = a->_22;
  84.     d->_23 = a->_32;
  85.     d->_24 = a->_24;
  86.  
  87.     d->_31 = a->_13;
  88.     d->_32 = a->_23;
  89.     d->_33 = a->_33;
  90.     d->_34 = a->_34;
  91.  
  92.     d->_41 = a->_14;
  93.     d->_42 = a->_24;
  94.     d->_43 = a->_34;
  95.     d->_44 = a->_44;
  96.  
  97.     return d;
  98. }
  99.  
  100.  
  101. /*
  102.  * Set the rotation part of a matrix such that the vector lpD is the new
  103.  * z-axis and lpU is the new y-axis.
  104.  */
  105. LPD3DMATRIX 
  106. D3DMATRIXSetRotation(LPD3DMATRIX lpM, LPD3DVECTOR lpD, LPD3DVECTOR lpU)
  107. {
  108.     float t;
  109.     D3DVECTOR d, u, r;
  110.  
  111.     /*
  112.      * Normalise the direction vector.
  113.      */
  114.     d.x = lpD->x;
  115.     d.y = lpD->y;
  116.     d.z = lpD->z;
  117.     D3DVECTORNormalise(&d);
  118.  
  119.     u.x = lpU->x;
  120.     u.y = lpU->y;
  121.     u.z = lpU->z;
  122.     /*
  123.      * Project u into the plane defined by d and normalise.
  124.      */
  125.     t = u.x * d.x + u.y * d.y + u.z * d.z;
  126.     u.x -= d.x * t;
  127.     u.y -= d.y * t;
  128.     u.z -= d.z * t;
  129.     D3DVECTORNormalise(&u);
  130.  
  131.     /*
  132.      * Calculate the vector pointing along the matrix x axis (in a right
  133.      * handed coordinate system) using cross product.
  134.      */
  135.     D3DVECTORCrossProduct(&r, &u, &d);
  136.  
  137.     lpM->_11 = r.x;
  138.     lpM->_12 = r.y, lpM->_13 = r.z;
  139.     lpM->_21 = u.x;
  140.     lpM->_22 = u.y, lpM->_23 = u.z;
  141.     lpM->_31 = d.x;
  142.     lpM->_32 = d.y;
  143.     lpM->_33 = d.z;
  144.  
  145.     return lpM;
  146. }
  147.  
  148. /*
  149.  * Calculates a point along a B-Spline curve defined by four points. p
  150.  * n output, contain the point. t                                Position
  151.  * along the curve between p2 and p3.  This position is a float between 0
  152.  * and 1. p1, p2, p3, p4    Points defining spline curve. p, at parameter
  153.  * t along the spline curve
  154.  */
  155. void 
  156. spline(LPD3DVECTOR p, float t, LPD3DVECTOR p1, LPD3DVECTOR p2,
  157.        LPD3DVECTOR p3, LPD3DVECTOR p4)
  158. {
  159.     double t2, t3;
  160.     float m1, m2, m3, m4;
  161.  
  162.     t2 = (double)(t * t);
  163.     t3 = t2 * (double)t;
  164.  
  165.     m1 = (float)((-1.0 * t3) + (2.0 * t2) + (-1.0 * (double)t));
  166.     m2 = (float)((3.0 * t3) + (-5.0 * t2) + (0.0 * (double)t) + 2.0);
  167.     m3 = (float)((-3.0 * t3) + (4.0 * t2) + (1.0 * (double)t));
  168.     m4 = (float)((1.0 * t3) + (-1.0 * t2) + (0.0 * (double)t));
  169.  
  170.     m1 /= (float)2.0;
  171.     m2 /= (float)2.0;
  172.     m3 /= (float)2.0;
  173.     m4 /= (float)2.0;
  174.  
  175.     p->x = p1->x * m1 + p2->x * m2 + p3->x * m3 + p4->x * m4;
  176.     p->y = p1->y * m1 + p2->y * m2 + p3->y * m3 + p4->y * m4;
  177.     p->z = p1->z * m1 + p2->z * m2 + p3->z * m3 + p4->z * m4;
  178. }
  179.  
  180.