home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / viewer / rodcone.cpp < prev    next >
C/C++ Source or Header  |  1997-07-14  |  7KB  |  271 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File: rodcone.cpp
  6.  *
  7.  ***************************************************************************/
  8.  
  9. /*
  10.  * Sample code for building objects out of rods and cones.
  11.  */
  12.  
  13. #include <d3drmwin.h>
  14. #include "viewer.h"
  15. #include "rodcone.h"
  16. #include <math.h>
  17.  
  18. static unsigned long rod_faces[] =
  19. {   8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, /* end 1 */
  20.     4, 0, 0, 1, 1, 9, 1, 8, 0,    /* side 0 */
  21.     4, 1, 1, 2, 2, 10, 2, 9, 1,    /* side 1 */
  22.     4, 2, 2, 3, 3, 11, 3, 10, 2, /* side 2 */
  23.     4, 3, 3, 4, 4, 12, 4, 11, 3, /* side 3 */
  24.     4, 4, 4, 5, 5, 13, 5, 12, 4, /* side 4 */
  25.     4, 5, 5, 6, 6, 14, 6, 13, 5, /* side 5 */
  26.     4, 6, 6, 7, 7, 15, 7, 14, 6, /* side 6 */
  27.     4, 7, 7, 0, 0, 8, 0, 15, 7,        /* side 7 */
  28.     8, 8, 0, 9, 1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6, 15, 7, /* end 2 */
  29.     0,
  30. };
  31.  
  32. void AddRod(LPDIRECT3DRMMESHBUILDER mesh, D3DVALUE radius, D3DVECTOR a, D3DVECTOR b)
  33. {
  34.     D3DVECTOR d, u, r;
  35.     D3DVECTOR v[16];
  36.     D3DVECTOR n[8];
  37.     D3DVALUE f;
  38.     int i;
  39.  
  40.     /*
  41.      * Find the unit vector along the rod.
  42.      */
  43.     d.x = b.x - a.x;
  44.     d.y = b.y - a.y;
  45.     d.z = b.z - a.z;
  46.     D3DRMVectorNormalise(&d);
  47.  
  48.     /*
  49.      * Pick a vector normal to d
  50.      */
  51.     if (d.y != D3DVAL(0.0) || d.z != D3DVAL(0.0))
  52.     {    u.x = D3DVAL(0.0);
  53.     if (d.y == D3DVAL(0.0))
  54.     {   u.y = D3DVAL(1.0);
  55.         u.z = D3DVAL(0.0);
  56.     } else
  57.     {   D3DVALUE n_fix =
  58.         D3DVAL(1.0)
  59.         +    D3DDivide(D3DMultiply(d.z, d.z), D3DMultiply(d.y, d.y));
  60. #ifdef FIXED_POINT_API
  61.         double un_val = (double)n_fix / (double)(1<<16);
  62.         u.z = D3DVAL(sqrt(1/un_val));
  63. #else
  64.         u.z = D3DVAL(sqrt(D3DDivide(D3DVAL(1.0), D3DVAL(n_fix))));
  65. #endif
  66.         u.y = -D3DMultiply(u.z, D3DDivide(d.z, d.y));
  67.     }
  68.     } else
  69.     {    u.x = D3DVAL(0.0);
  70.     u.y = D3DVAL(0.0);
  71.     u.z = D3DVAL(1.0);
  72.     }
  73.  
  74.     /*
  75.      * Now find a vector normal to them both, to give us a coordinate
  76.      * system in the plane normal to the rod.
  77.      */
  78.     D3DRMVectorCrossProduct(&r, &d, &u);
  79.  
  80.     /*
  81.      * Scale down the coordinates to the radius of the rod.
  82.      */
  83.     u.x = D3DMultiply(u.x, radius);
  84.     u.y = D3DMultiply(u.y, radius);
  85.     u.z = D3DMultiply(u.z, radius);
  86.     r.x = D3DMultiply(r.x, radius);
  87.     r.y = D3DMultiply(r.y, radius);
  88.     r.z = D3DMultiply(r.z, radius);
  89.  
  90.     /*
  91.      * Calculate the corners of an octagon.
  92.      */
  93.     f = D3DVAL((float)sqrt(2.0) / (2 * (1 + (float)sqrt(2.0) / 2)));
  94.     v[0].x = u.x + D3DMultiply(r.x, f);
  95.     v[0].y = u.y + D3DMultiply(r.y, f);
  96.     v[0].z = u.z + D3DMultiply(r.z, f);
  97.  
  98.     v[1].x = D3DMultiply(u.x, f) + r.x;
  99.     v[1].y = D3DMultiply(u.y, f) + r.y;
  100.     v[1].z = D3DMultiply(u.z, f) + r.z;
  101.  
  102.     v[2].x = D3DMultiply(-u.x, f) + r.x;
  103.     v[2].y = D3DMultiply(-u.y, f) + r.y;
  104.     v[2].z = D3DMultiply(-u.z, f) + r.z;
  105.  
  106.     v[3].x = -u.x + D3DMultiply(r.x, f);
  107.     v[3].y = -u.y + D3DMultiply(r.y, f);
  108.     v[3].z = -u.z + D3DMultiply(r.z, f);
  109.  
  110.     v[4].x = -u.x - D3DMultiply(r.x, f);
  111.     v[4].y = -u.y - D3DMultiply(r.y, f);
  112.     v[4].z = -u.z - D3DMultiply(r.z, f);
  113.  
  114.     v[5].x = D3DMultiply(-u.x, f) - r.x;
  115.     v[5].y = D3DMultiply(-u.y, f) - r.y;
  116.     v[5].z = D3DMultiply(-u.z, f) - r.z;
  117.  
  118.     v[6].x = D3DMultiply(u.x, f) - r.x;
  119.     v[6].y = D3DMultiply(u.y, f) - r.y;
  120.     v[6].z = D3DMultiply(u.z, f) - r.z;
  121.  
  122.     v[7].x = u.x - D3DMultiply(r.x, f);
  123.     v[7].y = u.y - D3DMultiply(r.y, f);
  124.     v[7].z = u.z - D3DMultiply(r.z, f);
  125.  
  126.     /*
  127.      * Add the rod endpoints and calculate the vertex normals.
  128.      */
  129.     for (i = 0; i < 8; i++)
  130.     {    n[i] = v[i];
  131.     D3DRMVectorNormalise(&n[i]);
  132.     v[i + 8].x = v[i].x + b.x;
  133.     v[i + 8].y = v[i].y + b.y;
  134.     v[i + 8].z = v[i].z + b.z;
  135.     v[i].x += a.x;
  136.     v[i].y += a.y;
  137.     v[i].z += a.z;
  138.     }
  139.  
  140.     /*
  141.      * Now add the faces.
  142.      */
  143.     mesh->AddFaces(16, v, 8, n, rod_faces, NULL);
  144. }
  145.  
  146. static unsigned long cone_faces[] =
  147. {   8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, /* end 1 */
  148.     3, 0, 0, 1, 1, 8, 1,    /* side 0 */
  149.     3, 1, 1, 2, 2, 8, 1,    /* side 1 */
  150.     3, 2, 2, 3, 3, 8, 1, /* side 2 */
  151.     3, 3, 3, 4, 4, 8, 1, /* side 3 */
  152.     3, 4, 4, 5, 5, 8, 1, /* side 4 */
  153.     3, 5, 5, 6, 6, 8, 1, /* side 5 */
  154.     3, 6, 6, 7, 7, 8, 1, /* side 6 */
  155.     3, 7, 7, 0, 0, 8, 1,        /* side 7 */
  156.     0,
  157. };
  158.  
  159. void AddCone(LPDIRECT3DRMMESHBUILDER mesh, D3DVALUE radius, D3DVECTOR a, D3DVECTOR b)
  160. {
  161.     D3DVECTOR d, u, r;
  162.     D3DVECTOR v[16];
  163.     D3DVECTOR n[8];
  164.     D3DVALUE f;
  165.     int i;
  166.  
  167.     /*
  168.      * Find the unit vector along the rod.
  169.      */
  170.     d.x = b.x - a.x;
  171.     d.y = b.y - a.y;
  172.     d.z = b.z - a.z;
  173.     D3DRMVectorNormalise(&d);
  174.  
  175.     /*
  176.      * Pick a vector normal to d
  177.      */
  178.     if (d.y != D3DVAL(0.0) || d.z != D3DVAL(0.0))
  179.     {    u.x = D3DVAL(0.0);
  180.     if (d.y == D3DVAL(0.0))
  181.     {   u.y = D3DVAL(1.0);
  182.         u.z = D3DVAL(0.0);
  183.     } else
  184.     {   D3DVALUE n_fix =
  185.         D3DVAL(1.0)
  186.         +    D3DDivide(D3DMultiply(d.z, d.z), D3DMultiply(d.y, d.y));
  187. #ifdef FIXED_POINT_API
  188.         double un_val = (double)n_fix / (double)(1<<16);
  189.         u.z = D3DVAL(sqrt(1 / un_val));
  190. #else
  191.         u.z = D3DVAL(sqrt(D3DVAL(1.0) / D3DVAL(n_fix)));
  192. #endif
  193.         u.y = - D3DDivide(D3DMultiply(u.z, d.z), d.y);
  194.     }
  195.     } else
  196.     {    u.x = D3DVAL(0.0);
  197.     u.y = D3DVAL(0.0);
  198.     u.z = D3DVAL(1.0);
  199.     }
  200.  
  201.     /*
  202.      * Now find a vector normal to them both, to give us a coordinate
  203.      * system in the plane normal to the rod.
  204.      */
  205.     D3DRMVectorCrossProduct(&r, &d, &u);
  206.  
  207.     /*
  208.      * Scale down the coordinates to the radius of the rod.
  209.      */
  210.     u.x = D3DMultiply(u.x, radius);
  211.     u.y = D3DMultiply(u.y, radius);
  212.     u.z = D3DMultiply(u.z, radius);
  213.     r.x = D3DMultiply(r.x, radius);
  214.     r.y = D3DMultiply(r.y, radius);
  215.     r.z = D3DMultiply(r.z, radius);
  216.  
  217.     /*
  218.      * Calculate the corners of an octagon.
  219.      */
  220.     f = D3DVAL((float)sqrt(2.0) / (2 * (1 + (float)sqrt(2.0) / 2)));
  221.     v[0].x = u.x + D3DMultiply(r.x, f);
  222.     v[0].y = u.y + D3DMultiply(r.y, f);
  223.     v[0].z = u.z + D3DMultiply(r.z, f);
  224.  
  225.     v[1].x = D3DMultiply(u.x, f) + r.x;
  226.     v[1].y = D3DMultiply(u.y, f) + r.y;
  227.     v[1].z = D3DMultiply(u.z, f) + r.z;
  228.  
  229.     v[2].x = D3DMultiply(-u.x, f) + r.x;
  230.     v[2].y = D3DMultiply(-u.y, f) + r.y;
  231.     v[2].z = D3DMultiply(-u.z, f) + r.z;
  232.  
  233.     v[3].x = -u.x + D3DMultiply(r.x, f);
  234.     v[3].y = -u.y + D3DMultiply(r.y, f);
  235.     v[3].z = -u.z + D3DMultiply(r.z, f);
  236.  
  237.     v[4].x = -u.x - D3DMultiply(r.x, f);
  238.     v[4].y = -u.y - D3DMultiply(r.y, f);
  239.     v[4].z = -u.z - D3DMultiply(r.z, f);
  240.  
  241.     v[5].x = D3DMultiply(-u.x, f) - r.x;
  242.     v[5].y = D3DMultiply(-u.y, f) - r.y;
  243.     v[5].z = D3DMultiply(-u.z, f) - r.z;
  244.  
  245.     v[6].x = D3DMultiply(u.x, f) - r.x;
  246.     v[6].y = D3DMultiply(u.y, f) - r.y;
  247.     v[6].z = D3DMultiply(u.z, f) - r.z;
  248.  
  249.     v[7].x = u.x - D3DMultiply(r.x, f);
  250.     v[7].y = u.y - D3DMultiply(r.y, f);
  251.     v[7].z = u.z - D3DMultiply(r.z, f);
  252.  
  253.     v[8] = b;
  254.  
  255.     /*
  256.      * Calculate the vertex normals.
  257.      */
  258.     for (i = 0; i < 8; i++)
  259.     {    n[i] = v[i];
  260.     D3DRMVectorNormalise(&n[0]);
  261.     v[i].x += a.x;
  262.     v[i].y += a.y;
  263.     v[i].z += a.z;
  264.     }
  265.  
  266.     /*
  267.      * Now add the faces.
  268.      */
  269.     mesh->AddFaces(9, v, 8, n, cone_faces, NULL);
  270. }
  271.