smap_rvec2st.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:2k
源码类别:

GIS编程

开发平台:

Visual C++

  1. /* Copyright (c) Mark J. Kilgard, 1998.  */
  2. /* This program is freely distributable without licensing fees
  3.    and is provided without guarantee or warrantee expressed or
  4.    implied. This program is -not- in the public domain. */
  5. #include <math.h>
  6. #include "glsmapint.h"
  7. /* (x,y,z) reflection vector --> (s,t) sphere map coordinates */
  8. int
  9. smapRvecToSt(float rvec[3], float st[2])
  10. {
  11. double m, recipm;
  12. /* In Section 2.10.4 ("Generating texture coordinates")
  13.    of the OpenGL 1.1 specification, you will find the
  14.    GL_SPHERE_MAP equations:
  15.           n' = normal after transformation to eye coordinates
  16.   u  = unit vector from origin to vertex in eye coordinates
  17.   (rx, ry, rz) = u - 2 * n' * transpose(n') * u
  18.   m  = 2 * sqrt(rx^2 + ry^2 + (rz + 1)^2))
  19.   s = rx/m + 0.5
  20.   t = ry/m + 0.5
  21.         The equation for calculating (rx, ry, rz) is the
  22. equation for calculating the reflection vector for
  23. a surface and observer.  The explanation and
  24. derivation for this equation is found in Roger's
  25. "Procedural Elements for Computer Graphics" 2nd ed.
  26. in Section 5-5 ("Determining the Reflection Vector").
  27. Note that Roger's convention has the Z axis in
  28. the opposite direction from the OpenGL convention. */
  29. m = 2 * sqrt(rvec[0]*rvec[0] +
  30.          rvec[1]*rvec[1] +
  31.  (rvec[2]+1)*(rvec[2]+1));
  32. if (m == 0.0) {
  33.     /* Some point on the sphere map perimeter. */
  34.     st[0] = 0.0;
  35.     st[1] = 0.5;
  36. return 0;
  37. }
  38. recipm = 1.0/m;
  39. st[0] = rvec[0]*recipm + 0.5;
  40. st[1] = rvec[1]*recipm + 0.5;
  41. return 1;
  42. }
  43. /* (s,t) sphere map coordinate --> reflection verctor (x,y,z) */
  44. void
  45. smapStToRvec(float *st, float *rvec)
  46. {
  47. double tmp1, tmp2;
  48. /* Using algebra to invert the sphere mapping equations
  49.    shown above in smapRvecToSt, you get:
  50.          rx = 2*sqrt(-4*s^2 + 4*s - 4*t^2 + 4*t - 1)*(2*s-1)
  51.  ry = 2*sqrt(-4*s^2 + 4*s - 4*t^2 + 4*t - 1)*(2*t-1)
  52.  rz = -8*s^2 + 8*s - 8*t^2 + 8*t - 3
  53.        The C code below eliminates common subexpressions. */
  54. tmp1 = st[0]*(1-st[0]) + st[1]*(1-st[1]);
  55. tmp2 = 2 * sqrt(4*tmp1 - 1);
  56. rvec[0] = tmp2 * (2*st[0]-1);
  57. rvec[1] = tmp2 * (2*st[1]-1);
  58. rvec[2] = 8 * tmp1 - 3;
  59. }