home *** CD-ROM | disk | FTP | other *** search
/ Learn 3D Graphics Programming on the PC / Learn_3D_Graphics_Programming_on_the_PC_Ferraro.iso / rwwin / pick.cp_ / pick.bin
Encoding:
Text File  |  1995-11-14  |  6.1 KB  |  172 lines

  1. //*********************************************************************
  2. //
  3. // File :     pick.cpp
  4. //
  5. // Abstract : The implementation of some enhanced picking functionality
  6. //            which use ray casting to determine the exact position
  7. //            of the projection of a viewport position onto an
  8. //            arbitrary plane. These functions can be used to drag
  9. //            objects directly under the mouse cursor.
  10. //
  11. //            This application had been written to be compatible with
  12. //            both the fixed and floating-point versions of the
  13. //            RenderWare library, i.e., it uses the macros CREAL,
  14. //            INT2REAL, RAdd, RDiv, RSub etc. If your application is
  15. //            intended for the floating-point version of the library
  16. //            only these macros are not necessary.
  17. //
  18. //            Please note that this application is intended for
  19. //            demonstration purposes only. No support will be
  20. //            provided for this code and it comes with no warranty.
  21. //
  22. //*********************************************************************
  23. //
  24. // This file is a product of Criterion Software Ltd.
  25. //
  26. // This file is provided as is with no warranties of any kind and is
  27. // provided without any obligation on Criterion Software Ltd. or
  28. // Canon Inc. to assist in its use or modification.
  29. //
  30. // Criterion Software Ltd. will not, under any
  31. // circumstances, be liable for any lost revenue or other damages
  32. // arising from the use of this file.
  33. //
  34. // Copyright (c) 1994, 1995 Criterion Software Ltd.
  35. // All Rights Reserved.
  36. //
  37. // RenderWare is a trademark of Canon Inc.
  38. //
  39. //*********************************************************************
  40.  
  41. //*********************************************************************
  42. //
  43. // Header files.
  44. //
  45. //*********************************************************************
  46.  
  47. #include <stdafx.h>
  48.  
  49. #include <rwlib.h>
  50. #include <rwwin.h>
  51.  
  52. #include "pick.h"
  53.  
  54. //*********************************************************************
  55. //
  56. // Functions.
  57. //
  58. //*********************************************************************
  59.  
  60. //*********************************************************************
  61.  
  62. // Return t at the point of interestion of the given ray and plane.
  63. // The plane is defined by a point on the plane (p) and a nornal to the
  64. // plane (n). Returns TRUE if the ray and plane intersect and FALSE if
  65. // the ray and plane are parallel.
  66. RwBool
  67. IntersectRayAndPlane(RwRay *ray, RwV3d *n, RwV3d *p, RwReal *t)
  68. {
  69.     RwReal div;
  70.  
  71.     div = ::RwDotProduct(&ray->v, n);
  72.     if (div == CREAL(0.0))
  73.     {
  74.         // The the ray is parallel to the plane so there is no
  75.         // intersection.
  76.         return FALSE;
  77.     }
  78.     else
  79.     {
  80.         // Math. voodoo to compute the parameter along the ray of the point
  81.         // of intersection.
  82.         *t = -RDiv(RAdd(-::RwDotProduct(n, p), ::RwDotProduct(&ray->p, n)), div);
  83.         return TRUE;
  84.     }
  85. }
  86.  
  87. //*********************************************************************
  88.  
  89. // Given a camera and a viewport position spawn a ray into world space.
  90. // NOTE: This function does not take into account camera offsets.
  91. RwRay *
  92. SpawnRay(RwCamera *camera, RwInt32 x, RwInt32 y, RwRay *ray)
  93. {
  94.     RwInt32 vpw;
  95.     RwInt32 vph;
  96.     RwReal  vww;
  97.     RwReal  vwh;
  98.     RwReal  vwx;
  99.     RwReal  vwy;
  100.  
  101.     // Convert the viewport position to a viewwindow position.
  102.     ::RwGetCameraViewport(camera, NULL, NULL, &vpw, &vph);
  103.     ::RwGetCameraViewwindow(camera, &vww, &vwh);
  104.     vwx = RSub(RDiv(RMul(INT2REAL(x), vww), INT2REAL(vpw)), RDiv(vww, CREAL(2.0)));
  105.     vwy = RSub(RDiv(RMul(INT2REAL((vph - 1) - y), vwh), INT2REAL(vph)), RDiv(vwh, CREAL(2.0)));
  106.  
  107.     // Initalize the ray in camera space.
  108.     ray->p.x = CREAL(0.0);
  109.     ray->p.y = CREAL(0.0);
  110.     ray->p.z = CREAL(0.0);
  111.     ray->v.x = vwx;
  112.     ray->v.y = vwy;
  113.     ray->v.z = CREAL(0.5);
  114.  
  115.     // Transform the ray into world space.
  116.     ::RwPushScratchMatrix();
  117.         ::RwGetCameraLTM(camera, ::RwScratchMatrix());
  118.         // The camera's positive z points into the screen. For the
  119.         // world, positive z points out of the screen. We need to handle
  120.         // this difference in "handedness" by flipping the x axis. A quick
  121.         // way of doing this is to scale the x axis by -1.
  122.         ::RwScaleMatrix(::RwScratchMatrix(),
  123.                         CREAL(-1.0), CREAL(1.0), CREAL(1.0), rwPRECONCAT);
  124.         ::RwTransformVector(&ray->v, ::RwScratchMatrix());
  125.         ::RwTransformPoint(&ray->p, ::RwScratchMatrix());
  126.     ::RwPopScratchMatrix();
  127.  
  128.     return ray;
  129. }
  130.  
  131. //*********************************************************************
  132.  
  133. // Compute the position (in world coordinates) of the given clump under
  134. // the given (x, y) position in the viewport of the given camera. The
  135. // clump will keep a constant orientation and distance with respect to
  136. // the camera, i.e., this function can be used to drag the clump around
  137. // on the plane parallel to the camera on which the clump lies.
  138. RwV3d *
  139. GetClumpPositionUnderPointer(RwClump *clump, RwCamera *camera,
  140.                              RwInt32 x, RwInt32 y, RwV3d *pos)
  141. {
  142.     RwV3d  n;
  143.     RwV3d  p;
  144.     RwRay  ray;
  145.     RwReal t;
  146.     
  147.     // Compute the parameters of the plane on which the clump lies. The
  148.     // plane normal is the negative camera look at vector and the point
  149.     // on the plane is given by the clump's origin.
  150.     ::RwGetCameraLookAt(camera, &n);
  151.     n.x = -n.x;
  152.     n.y = -n.y;
  153.     n.z = -n.z;
  154.     ::RwGetClumpOrigin(clump, &p);
  155.  
  156.     // Spawn a ray from the picked position.
  157.     ::SpawnRay(camera, x, y, &ray);
  158.  
  159.     // Compute the parameter along the ray of the point of intersection.
  160.     // NOTE: This is a special case in that we know the plane is
  161.     // perpindicular to the ray so we know there must be an intersection.
  162.     ::IntersectRayAndPlane(&ray, &n, &p, &t);
  163.  
  164.     // Convert the parameter to an actual world position.
  165.     ::RwScaleVector(&ray.v, t, pos);
  166.     ::RwAddVector(&ray.p, pos, pos);
  167.     
  168.     return pos;
  169. }
  170.  
  171. //*********************************************************************
  172.