home *** CD-ROM | disk | FTP | other *** search
/ NEXT Generation 27 / NEXT27.iso / pc / demos / emperor / dx3.exe / SDK / SAMPLES / DS3DVIEW / RODCONE.CPP < prev    next >
C/C++ Source or Header  |  1996-08-28  |  8KB  |  280 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 "resource.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. /*
  33. ** Error function which is actually defined in rlds3d.cpp
  34. */
  35.  
  36. BOOL D3DRM_SUCCEED(HRESULT result, int force_critical = -1, char* info = NULL);
  37.  
  38. void AddRod(LPDIRECT3DRMMESHBUILDER mesh, D3DVALUE radius, D3DVECTOR a, D3DVECTOR b)
  39. {
  40.         if (!mesh) return;
  41.     D3DVECTOR d, u, r;
  42.     D3DVECTOR v[16];
  43.     D3DVECTOR n[8];
  44.     D3DVALUE f;
  45.     int i;
  46.  
  47.     /*
  48.      * Find the unit vector along the rod.
  49.      */
  50.     d.x = b.x - a.x;
  51.     d.y = b.y - a.y;
  52.     d.z = b.z - a.z;
  53.     D3DRMVectorNormalise(&d);
  54.  
  55.     /*
  56.      * Pick a vector normal to d
  57.      */
  58.     if (d.y != D3DVAL(0.0) || d.z != D3DVAL(0.0))
  59.     {   u.x = D3DVAL(0.0);
  60.         if (d.y == D3DVAL(0.0))
  61.         {   u.y = D3DVAL(1.0);
  62.             u.z = D3DVAL(0.0);
  63.         } else
  64.         {   D3DVALUE n_fix =
  65.                 D3DVAL(1.0)
  66.             +   D3DDivide(D3DMultiply(d.z, d.z), D3DMultiply(d.y, d.y));
  67. #ifdef FIXED_POINT_API
  68.             double un_val = (double)n_fix / (double)(1<<16);
  69.             u.z = D3DVAL(sqrt(1/un_val));
  70. #else
  71.             u.z = D3DVAL(sqrt(D3DDivide(D3DVAL(1.0), D3DVAL(n_fix))));
  72. #endif
  73.             u.y = -D3DMultiply(u.z, D3DDivide(d.z, d.y));
  74.         }
  75.     } else
  76.     {   u.x = D3DVAL(0.0);
  77.         u.y = D3DVAL(0.0);
  78.         u.z = D3DVAL(1.0);
  79.     }
  80.  
  81.     /*
  82.      * Now find a vector normal to them both, to give us a coordinate
  83.      * system in the plane normal to the rod.
  84.      */
  85.     D3DRMVectorCrossProduct(&r, &d, &u);
  86.  
  87.     /*
  88.      * Scale down the coordinates to the radius of the rod.
  89.      */
  90.     u.x = D3DMultiply(u.x, radius);
  91.     u.y = D3DMultiply(u.y, radius);
  92.     u.z = D3DMultiply(u.z, radius);
  93.     r.x = D3DMultiply(r.x, radius);
  94.     r.y = D3DMultiply(r.y, radius);
  95.     r.z = D3DMultiply(r.z, radius);
  96.  
  97.     /*
  98.      * Calculate the corners of an octagon.
  99.      */
  100.     f = D3DVAL((float)sqrt((double)2) / (2 * (1 + (float)sqrt((double)2) / 2)));
  101.     v[0].x = u.x + D3DMultiply(r.x, f);
  102.     v[0].y = u.y + D3DMultiply(r.y, f);
  103.     v[0].z = u.z + D3DMultiply(r.z, f);
  104.  
  105.     v[1].x = D3DMultiply(u.x, f) + r.x;
  106.     v[1].y = D3DMultiply(u.y, f) + r.y;
  107.     v[1].z = D3DMultiply(u.z, f) + r.z;
  108.  
  109.     v[2].x = D3DMultiply(-u.x, f) + r.x;
  110.     v[2].y = D3DMultiply(-u.y, f) + r.y;
  111.     v[2].z = D3DMultiply(-u.z, f) + r.z;
  112.  
  113.     v[3].x = -u.x + D3DMultiply(r.x, f);
  114.     v[3].y = -u.y + D3DMultiply(r.y, f);
  115.     v[3].z = -u.z + D3DMultiply(r.z, f);
  116.  
  117.     v[4].x = -u.x - D3DMultiply(r.x, f);
  118.     v[4].y = -u.y - D3DMultiply(r.y, f);
  119.     v[4].z = -u.z - D3DMultiply(r.z, f);
  120.  
  121.     v[5].x = D3DMultiply(-u.x, f) - r.x;
  122.     v[5].y = D3DMultiply(-u.y, f) - r.y;
  123.     v[5].z = D3DMultiply(-u.z, f) - r.z;
  124.  
  125.     v[6].x = D3DMultiply(u.x, f) - r.x;
  126.     v[6].y = D3DMultiply(u.y, f) - r.y;
  127.     v[6].z = D3DMultiply(u.z, f) - r.z;
  128.  
  129.     v[7].x = u.x - D3DMultiply(r.x, f);
  130.     v[7].y = u.y - D3DMultiply(r.y, f);
  131.     v[7].z = u.z - D3DMultiply(r.z, f);
  132.  
  133.     /*
  134.      * Add the rod endpoints and calculate the vertex normals.
  135.      */
  136.     for (i = 0; i < 8; i++)
  137.     {   n[i] = v[i];
  138.         D3DRMVectorNormalise(&n[i]);
  139.         v[i + 8].x = v[i].x + b.x;
  140.         v[i + 8].y = v[i].y + b.y;
  141.         v[i + 8].z = v[i].z + b.z;
  142.         v[i].x += a.x;
  143.         v[i].y += a.y;
  144.         v[i].z += a.z;
  145.     }
  146.  
  147.     /*
  148.      * Now add the faces.
  149.      */
  150.         D3DRM_SUCCEED(mesh->AddFaces(16, v, 8, n, rod_faces, NULL));
  151. }
  152.  
  153. static unsigned long cone_faces[] =
  154. {   8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, /* end 1 */
  155.     3, 0, 0, 1, 1, 8, 1,        /* side 0 */
  156.     3, 1, 1, 2, 2, 8, 1,        /* side 1 */
  157.     3, 2, 2, 3, 3, 8, 1, /* side 2 */
  158.     3, 3, 3, 4, 4, 8, 1, /* side 3 */
  159.     3, 4, 4, 5, 5, 8, 1, /* side 4 */
  160.     3, 5, 5, 6, 6, 8, 1, /* side 5 */
  161.     3, 6, 6, 7, 7, 8, 1, /* side 6 */
  162.     3, 7, 7, 0, 0, 8, 1,                /* side 7 */
  163.     0,
  164. };
  165.  
  166. void AddCone(LPDIRECT3DRMMESHBUILDER mesh, D3DVALUE radius, D3DVECTOR a, D3DVECTOR b)
  167. {
  168.         if (!mesh) return;
  169.     D3DVECTOR d, u, r;
  170.     D3DVECTOR v[16];
  171.     D3DVECTOR n[8];
  172.     D3DVALUE f;
  173.     int i;
  174.  
  175.     /*
  176.      * Find the unit vector along the rod.
  177.      */
  178.     d.x = b.x - a.x;
  179.     d.y = b.y - a.y;
  180.     d.z = b.z - a.z;
  181.     D3DRMVectorNormalise(&d);
  182.  
  183.     /*
  184.      * Pick a vector normal to d
  185.      */
  186.     if (d.y != D3DVAL(0.0) || d.z != D3DVAL(0.0))
  187.     {   u.x = D3DVAL(0.0);
  188.         if (d.y == D3DVAL(0.0))
  189.         {   u.y = D3DVAL(1.0);
  190.             u.z = D3DVAL(0.0);
  191.         } else
  192.         {   D3DVALUE n_fix =
  193.                 D3DVAL(1.0)
  194.             +   D3DDivide(D3DMultiply(d.z, d.z), D3DMultiply(d.y, d.y));
  195. #ifdef FIXED_POINT_API
  196.             double un_val = (double)n_fix / (double)(1<<16);
  197.             u.z = D3DVAL(sqrt(1 / un_val));
  198. #else
  199.             u.z = D3DVAL(sqrt(D3DVAL(1.0) / D3DVAL(n_fix)));
  200. #endif
  201.             u.y = - D3DDivide(D3DMultiply(u.z, d.z), d.y);
  202.         }
  203.     } else
  204.     {   u.x = D3DVAL(0.0);
  205.         u.y = D3DVAL(0.0);
  206.         u.z = D3DVAL(1.0);
  207.     }
  208.  
  209.     /*
  210.      * Now find a vector normal to them both, to give us a coordinate
  211.      * system in the plane normal to the rod.
  212.      */
  213.     D3DRMVectorCrossProduct(&r, &d, &u);
  214.  
  215.     /*
  216.      * Scale down the coordinates to the radius of the rod.
  217.      */
  218.     u.x = D3DMultiply(u.x, radius);
  219.     u.y = D3DMultiply(u.y, radius);
  220.     u.z = D3DMultiply(u.z, radius);
  221.     r.x = D3DMultiply(r.x, radius);
  222.     r.y = D3DMultiply(r.y, radius);
  223.     r.z = D3DMultiply(r.z, radius);
  224.  
  225.     /*
  226.      * Calculate the corners of an octagon.
  227.      */
  228.     f = D3DVAL((float)sqrt((double)2) / (2 * (1 + (float)sqrt((double)2) / 2)));
  229.     v[0].x = u.x + D3DMultiply(r.x, f);
  230.     v[0].y = u.y + D3DMultiply(r.y, f);
  231.     v[0].z = u.z + D3DMultiply(r.z, f);
  232.  
  233.     v[1].x = D3DMultiply(u.x, f) + r.x;
  234.     v[1].y = D3DMultiply(u.y, f) + r.y;
  235.     v[1].z = D3DMultiply(u.z, f) + r.z;
  236.  
  237.     v[2].x = D3DMultiply(-u.x, f) + r.x;
  238.     v[2].y = D3DMultiply(-u.y, f) + r.y;
  239.     v[2].z = D3DMultiply(-u.z, f) + r.z;
  240.  
  241.     v[3].x = -u.x + D3DMultiply(r.x, f);
  242.     v[3].y = -u.y + D3DMultiply(r.y, f);
  243.     v[3].z = -u.z + D3DMultiply(r.z, f);
  244.  
  245.     v[4].x = -u.x - D3DMultiply(r.x, f);
  246.     v[4].y = -u.y - D3DMultiply(r.y, f);
  247.     v[4].z = -u.z - D3DMultiply(r.z, f);
  248.  
  249.     v[5].x = D3DMultiply(-u.x, f) - r.x;
  250.     v[5].y = D3DMultiply(-u.y, f) - r.y;
  251.     v[5].z = D3DMultiply(-u.z, f) - r.z;
  252.  
  253.     v[6].x = D3DMultiply(u.x, f) - r.x;
  254.     v[6].y = D3DMultiply(u.y, f) - r.y;
  255.     v[6].z = D3DMultiply(u.z, f) - r.z;
  256.  
  257.     v[7].x = u.x - D3DMultiply(r.x, f);
  258.     v[7].y = u.y - D3DMultiply(r.y, f);
  259.     v[7].z = u.z - D3DMultiply(r.z, f);
  260.  
  261.     v[8] = b;
  262.  
  263.     /*
  264.      * Calculate the vertex normals.
  265.      */
  266.     for (i = 0; i < 8; i++)
  267.     {   n[i] = v[i];
  268.         D3DRMVectorNormalise(&n[0]);
  269.         v[i].x += a.x;
  270.         v[i].y += a.y;
  271.         v[i].z += a.z;
  272.     }
  273.  
  274.     /*
  275.      * Now add the faces.
  276.      */
  277.  
  278.     D3DRM_SUCCEED(mesh->AddFaces(9, v, 8, n, cone_faces, NULL));
  279. }
  280.