QUAT.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:6k
源码类别:

Windows编程

开发平台:

Visual C++

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