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 / quat / quat.c < prev    next >
C/C++ Source or Header  |  1997-07-14  |  6KB  |  194 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File: quat.c
  6.  *
  7.  ***************************************************************************/
  8.  
  9. /*
  10.  * demonstration of representation of orientation using quaternions
  11.  */
  12.  
  13. #include "rmdemo.h"
  14.  
  15. #define PI2 6.28318
  16. #define XPOS 2.0
  17. #define INTERPOLATE_STEP 0.05
  18.  
  19. static D3DRMQUATERNION q;
  20.  
  21. static int view_width, view_height;
  22.  
  23. void ReadMouse(int* buttons, int* x, int* y);
  24.  
  25. void CDECL
  26. UserControl(LPDIRECT3DRMFRAME frame, void* arg, D3DVALUE delta)
  27. {
  28.     int mx, my, mb;
  29.     LPDIRECT3DRMFRAME scene;
  30.     D3DVALUE angle;
  31.     D3DVECTOR vx = {D3DVAL(1), D3DVAL(0), D3DVAL(0)},
  32.      vy = {D3DVAL(0), D3DVAL(1), D3DVAL(0)};
  33.     D3DRMQUATERNION qx, qy;
  34.     D3DRMMATRIX4D mat;
  35.  
  36.     arg = arg;
  37.  
  38.     ReadMouse(&mb, &mx, &my);
  39.     angle = D3DMultiply((-D3DVAL(0.5) + D3DDivide(D3DVAL(my),
  40.                        D3DVAL(view_height))), D3DVAL(PI2));
  41.     D3DRMQuaternionFromRotation(&qx, &vx, angle);
  42.     angle = D3DMultiply((-D3DVAL(0.5) + D3DDivide(D3DVAL(mx),
  43.                        D3DVAL(view_width))), D3DVAL(PI2));
  44.     D3DRMQuaternionFromRotation(&qy, &vy, angle);
  45.     D3DRMQuaternionMultiply(&q, &qx, &qy);
  46.     D3DRMMatrixFromQuaternion(mat, &q);
  47.     frame->lpVtbl->AddTransform(frame, D3DRMCOMBINE_REPLACE, mat);
  48.     frame->lpVtbl->GetScene(frame, &scene);
  49.     frame->lpVtbl->SetPosition(frame, scene, D3DVAL(-XPOS), D3DVAL(0),
  50.                                D3DVAL(0));
  51.  
  52.     RELEASE(scene);
  53. }
  54.  
  55. void CDECL
  56. Follow(LPDIRECT3DRMFRAME frame, void* arg, D3DVALUE delta)
  57. {
  58.     LPDIRECT3DRMFRAME scene;
  59.     int mx, my, mb;
  60.     static D3DRMQUATERNION qstart = {D3DVAL(1), {D3DVAL(0), D3DVAL(0),D3DVAL(0)}},
  61.                                  qend;
  62.     static D3DVALUE alpha = D3DVAL(0);
  63.  
  64.     arg = arg;
  65.  
  66.     ReadMouse(&mb, &mx, &my);
  67.     if (mb && alpha == D3DVAL(0)) {
  68.     qend = q;
  69.     alpha = D3DVAL(INTERPOLATE_STEP);
  70.     }
  71.     if (alpha > D3DVAL(0)) {
  72.     D3DRMQUATERNION interp;
  73.     D3DRMMATRIX4D mat;
  74.  
  75.     D3DRMQuaternionSlerp(&interp, &qstart, &qend, alpha);
  76.     D3DRMMatrixFromQuaternion(mat, &interp);
  77.  
  78.     if (alpha >= D3DVAL(1)) {
  79.         D3DRMMatrixFromQuaternion(mat, &qend);
  80.         alpha = D3DVAL(0);
  81.         qstart = qend;
  82.     } else
  83.         alpha += D3DVAL(INTERPOLATE_STEP);
  84.  
  85.     frame->lpVtbl->AddTransform(frame, D3DRMCOMBINE_REPLACE, mat);
  86.     frame->lpVtbl->GetScene(frame, &scene);
  87.     frame->lpVtbl->SetPosition(frame, scene, D3DVAL(XPOS), D3DVAL(0), D3DVAL(0));
  88.     RELEASE(scene);
  89.     }
  90. }
  91.  
  92. BOOL
  93. BuildScene(LPDIRECT3DRMDEVICE dev, LPDIRECT3DRMVIEWPORT view,
  94.        LPDIRECT3DRMFRAME scene, LPDIRECT3DRMFRAME camera)
  95. {
  96.     D3DRMRENDERQUALITY quality = D3DRMRENDER_FLAT;
  97.     LPDIRECT3DRMFRAME lights = NULL;
  98.     LPDIRECT3DRMFRAME user = NULL;
  99.     LPDIRECT3DRMFRAME follower = NULL;
  100.     LPDIRECT3DRMMESHBUILDER builder = NULL;
  101.     LPDIRECT3DRMMESH mesh = NULL;
  102.     LPDIRECT3DRMLIGHT l1 = NULL;
  103.     LPDIRECT3DRMLIGHT l2 = NULL;
  104.     HRESULT rval;
  105.  
  106.     if (FAILED(dev->lpVtbl->SetQuality(dev, quality)))
  107.     goto generic_error;
  108.  
  109.     view_width = view->lpVtbl->GetWidth(view);
  110.     view_height = view->lpVtbl->GetHeight(view);
  111.  
  112.     /*
  113.      * initialize the lights in the scene
  114.      */
  115.     if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, scene, &lights)))
  116.     goto generic_error;
  117.     if (FAILED(lights->lpVtbl->SetOrientation(lights, scene,
  118.        D3DVAL(-1), D3DVAL(-1), D3DVAL(0), D3DVAL(0), D3DVAL(1), D3DVAL(0))))
  119.        goto generic_error;
  120.     if (FAILED(lpD3DRM->lpVtbl->CreateLightRGB(lpD3DRM, D3DRMLIGHT_DIRECTIONAL, D3DVAL(0.8),
  121.                                   D3DVAL(0.6), D3DVAL(0.7), &l1)))
  122.                   goto generic_error;
  123.     if (FAILED(lights->lpVtbl->AddLight(lights, l1)))
  124.     goto generic_error;
  125.     if (FAILED(lpD3DRM->lpVtbl->CreateLightRGB(lpD3DRM, D3DRMLIGHT_AMBIENT, D3DVAL(0.1),
  126.                                   D3DVAL(0.1), D3DVAL(0.1), &l2)))
  127.                   goto generic_error;
  128.     if (FAILED(scene->lpVtbl->AddLight(scene, l2)))
  129.     goto generic_error;
  130.  
  131.     if (FAILED(lpD3DRM->lpVtbl->CreateMeshBuilder(lpD3DRM, &builder)))
  132.     goto generic_error;
  133.     rval = builder->lpVtbl->Load(builder, "dropship.x", NULL,
  134.                     D3DRMLOAD_FROMFILE, NULL, NULL);
  135.     if (rval != D3DRM_OK) {
  136.         Msg("Failed to load dropship.x.\n%s", D3DRMErrorToString(rval));
  137.     goto ret_with_error;
  138.     }
  139.     if (FAILED(builder->lpVtbl->Scale(builder, D3DVAL(0.1),
  140.                                      D3DVAL(0.08), D3DVAL(0.1))))
  141.                      goto generic_error;
  142.     if (FAILED(builder->lpVtbl->CreateMesh(builder, &mesh)))
  143.     goto generic_error;
  144.     RELEASE(builder);
  145.  
  146.     if (FAILED(camera->lpVtbl->SetPosition(camera, scene, D3DVAL(0), D3DVAL(0), 
  147.                                 D3DVAL(-12))))
  148.                 goto generic_error;
  149.     if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, scene, &user)))
  150.     goto generic_error;
  151.     if (FAILED(user->lpVtbl->AddVisual(user, (LPDIRECT3DRMVISUAL) mesh)))
  152.     goto generic_error;
  153.     if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, scene, &follower)))
  154.     goto generic_error;
  155.     if (FAILED(follower->lpVtbl->AddVisual(follower, (LPDIRECT3DRMVISUAL) mesh)))
  156.     goto generic_error;
  157.  
  158.     if (FAILED(follower->lpVtbl->SetPosition(follower, scene, D3DVAL(XPOS), D3DVAL(0),
  159.                                   D3DVAL(0))))
  160.                   goto generic_error;
  161.  
  162.     if (FAILED(user->lpVtbl->AddMoveCallback(user, UserControl, NULL)))
  163.     goto generic_error;
  164.     if (FAILED(follower->lpVtbl->AddMoveCallback(follower, Follow, NULL)))
  165.     goto generic_error;
  166.  
  167.     RELEASE(lights);
  168.     RELEASE(user);
  169.     RELEASE(follower);
  170.     RELEASE(mesh);
  171.     RELEASE(l1);
  172.     RELEASE(l2);
  173.     return TRUE;
  174. generic_error:
  175.     Msg("A failure occurred while building the scene.\n");
  176. ret_with_error:
  177.     RELEASE(lights);
  178.     RELEASE(user);
  179.     RELEASE(follower);
  180.     RELEASE(builder);
  181.     RELEASE(mesh);
  182.     RELEASE(l1);
  183.     RELEASE(l2);
  184.     return FALSE;
  185. }
  186.  
  187. void
  188. OverrideDefaults(Defaults* defaults)
  189. {
  190.     defaults->bNoTextures = TRUE;
  191.     defaults->bConstRenderQuality = TRUE;
  192.     lstrcpy(defaults->Name, "Quaternion Direct3DRM Example");
  193. }
  194.