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

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 <stdio.h>  /* SunOS multithreaded assert() needs <stdio.h>.  Lame. */
  6. #include <assert.h>
  7. #include <stdlib.h>
  8. #include <math.h>
  9. #include <GL/glsmap.h>
  10. #include "glsmapint.h"
  11. static struct {
  12. int xl;
  13. int yl;
  14. int zl;
  15. int swap;  /* swap final (s,t) */
  16. int flip;  /* flip final s or t, ie. [0..1] --> [1..0] */
  17. float dir;
  18. } faceInfo[5] = {
  19. { 0, 1, 2, 0,  1.0,  1.0 },  /* front */
  20. { 0, 2, 1, 0, -1.0,  1.0 },  /* top */
  21. { 0, 2, 1, 0,  1.0, -1.0 },  /* bottom */
  22. { 1, 2, 0, 1, -1.0,  1.0 },  /* left */
  23. { 1, 2, 0, 1,  1.0, -1.0 },  /* right */
  24. };
  25. static struct {
  26. int xl;
  27. int yl;
  28. float dir;
  29. } edgeInfo[4] = {
  30. { 0, 1, -1.0 },
  31. { 0, 1,  1.0 },
  32. { 1, 0, -1.0 },
  33. { 1, 0,  1.0 }
  34. };
  35. void
  36. __smapValidateSphereMapMesh(SphereMapMesh *mesh)
  37. {
  38. /* setup some local variables for variable array size indexing */
  39. INITFACE(mesh);
  40. INITBACK(mesh);
  41. float st[2];     /* (s,t) coordinate  */
  42.      /* range=[0..1,0..1] */
  43. float v[3];      /* (x,y,z) location on cube map */
  44.                  /* range=[-1..1,-1..1,-1..1] */
  45. float rv[3];     /* reflection vector, ie. cube map location */
  46.                  /* normalized onto unit sphere */
  47. float len;       /* distance from v[3] to origin */
  48.                  /* for converting to rv[3] */
  49. int side;        /* which of 5 faces (all but back face) */
  50. int i, j;
  51. int xl, yl, zl;  /* renamed X, Y, Z index */
  52. int swap;
  53. int flip;
  54. int edge;        /* which edge of back face */
  55. float sc, tc;    /* singularity (s,t) on back face circle */
  56. if (mesh->face) {
  57. assert(mesh->back == &(mesh->face[5*sqsteps]));
  58. return;
  59. }
  60. assert(mesh->back == NULL);
  61. mesh->face = (STXY*)
  62. malloc((5*sqsteps+4*ringedspokes) * sizeof(STXY));
  63. mesh->back = &(mesh->face[5*sqsteps]);
  64. /* for the front and four side faces */
  65. for (side=0; side<5; side++) {
  66. /* use faceInfo to parameterize face construction */
  67. xl  = faceInfo[side].xl;
  68. yl  = faceInfo[side].yl;
  69. zl  = faceInfo[side].zl;
  70. swap = faceInfo[side].swap;
  71. flip = faceInfo[side].flip;
  72. /* cube map "Z" coordinate */
  73. v[zl] = faceInfo[side].dir;
  74. for (i=0; i<mesh->steps; i++) {
  75. /* cube map "Y" coordinate */
  76. v[yl] = 2.0/(mesh->steps-1) * i - 1.0;
  77. for (j=0; j<mesh->steps; j++) {
  78. /* cube map "X" coordinate */
  79. v[xl] = 2.0/(mesh->steps-1) * j - 1.0;
  80. /* normalize cube map location to construct */
  81. /* reflection vector */
  82. len = sqrt(1.0 + v[xl]*v[xl] + v[yl]*v[yl]);
  83. rv[0] = v[0]/len;
  84. rv[1] = v[1]/len;
  85. rv[2] = v[2]/len;
  86. /* map reflection vector to sphere map (s,t) */
  87. /* NOTE: face[side][i][j] (x,y) gets updated */
  88. smapRvecToSt(rv, FACExy(side,i,j));
  89. /* update texture coordinate, */
  90. /* normalize [-1..1,-1..1] to [0..1,0..1] */
  91. if (!swap) {
  92.     FACE(side,i,j).s = (-v[xl] + 1.0)/2.0;
  93. FACE(side,i,j).t = (flip*v[yl] + 1.0)/2.0;
  94. } else {
  95. FACE(side,i,j).s = (flip*-v[yl] + 1.0)/2.0;
  96. FACE(side,i,j).t = (v[xl] + 1.0)/2.0;
  97. }
  98. }
  99. }
  100. }
  101. /* The back face must be specially handled.  The center
  102.    point in the back face of a cube map becomes a
  103.    a singularity around the circular edge of a sphere map. */
  104. /* Carefully work from each edge of the back face to center
  105.    of back face mapped to the outside of the sphere map. */
  106. /* cube map "Z" coordinate, always -1 since backface */
  107. v[2] = -1;
  108. /* for each edge */
  109. /*   [x=-1, y=-1..1, z=-1] */
  110. /*   [x= 1, y=-1..1, z=-1] */
  111. /*   [x=-1..1, y=-1, z=-1] */
  112. /*   [x=-1..1, y= 1, z=-1] */
  113. for (edge=0; edge<4; edge++) {
  114. /* cube map "X" coordinate */
  115. v[edgeInfo[edge].xl] = edgeInfo[edge].dir;
  116. for (j=0; j<mesh->steps; j++) {
  117. /* cube map "Y" coordinate */
  118. v[edgeInfo[edge].yl] = 2.0/(mesh->steps-1) * j - 1.0;
  119. /* normalize cube map location to construct */
  120. /* reflection vector */
  121. len = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
  122. rv[0] = v[0]/len;
  123. rv[1] = v[1]/len;
  124. rv[2] = v[2]/len;
  125. /* Map reflection vector to sphere map (s,t). */
  126. smapRvecToSt(rv, st);
  127. /* Determine distinance from the center of sphere */
  128. /* map (0.5,0.5) to (s,t) */
  129. len = sqrt((st[0]-0.5)*(st[0]-0.5) + (st[1]-0.5)*(st[1]-0.5));
  130. /* Calculate (s,t) location extended to the singularity */
  131. /* at the center of the back face (ie, extend to */
  132. /* circle edge of the sphere map). */
  133. sc = (st[0]-0.5)/len * 0.5 + 0.5;
  134. tc = (st[1]-0.5)/len * 0.5 + 0.5;
  135. /* (s,t) at back face edge. */
  136. BACK(edge,0,j).s = (-v[0] + 1.0)/2.0;
  137. BACK(edge,0,j).t = (-v[1] + 1.0)/2.0;
  138. BACK(edge,0,j).x = st[0];
  139. BACK(edge,0,j).y = st[1];
  140. /* If just two rings, we just generate a back face edge
  141.    vertex and a center vertex (2 rings), but if there
  142.    are more rings, we carefully interpolate between the
  143.    edge and center vertices.  Notice how smapStToRvec is used
  144.    to map the interpolated (s,t) into a reflection vector
  145.    that must then be extended to the back cube face (it is
  146.    not correct to just interpolate the texture
  147.    coordinates!). */
  148. if (mesh->rings > 2) {
  149. float ist[2];  /* interpolated (s,t) */
  150. float ds, dt;  /* delta s and delta t */
  151. /* Start interpolating from the edge. */
  152. ist[0] = st[0];
  153. ist[1] = st[1];
  154. /* Calculate delta s and delta t for interpolation. */
  155. ds = (sc - ist[0]) / (mesh->rings-1);
  156. dt = (tc - ist[1]) / (mesh->rings-1);
  157. for (i=1; i<mesh->rings-1; i++) {
  158. /* Incremental interpolation of (s,t). */
  159. ist[0] = ist[0] + ds;
  160. ist[1] = ist[1] + dt;
  161. /* Calculate reflection vector from interpolated (s,t). */
  162. smapStToRvec(ist, rv);
  163. /* Assert that z must be on the back cube face. */
  164. assert(rv[2] <= -sqrt(1.0/3.0));
  165. /* Extend reflection vector out of back cube face. */
  166. /* Note: z is negative value so negate z to avoid */
  167. /* inverting x and y! */
  168. rv[0] = rv[0] / -rv[2];
  169. rv[1] = rv[1] / -rv[2];
  170. BACK(edge,i,j).s = (-rv[0] + 1.0)/2.0;
  171. BACK(edge,i,j).t = (-rv[1] + 1.0)/2.0;
  172. BACK(edge,i,j).x = ist[0];
  173. BACK(edge,i,j).y = ist[1];
  174. }
  175. }
  176. /* (s,t) at circle edge of the sphere map is ALWAYS */
  177. /* at center of back cube map face */
  178. BACK(edge,mesh->rings-1,j).s = 0.5;
  179. BACK(edge,mesh->rings-1,j).t = 0.5;
  180. /* Location of singularity at the edge of the sphere map. */
  181. BACK(edge,mesh->rings-1,j).x = sc;
  182. BACK(edge,mesh->rings-1,j).y = tc;
  183. if (mesh->edgeExtend) {
  184. /* Add an extra ring to avoid seeing the */
  185. /* tessellation boundary of the sphere map's sphere. */
  186. BACK(edge,mesh->rings,j).s = 0.5;
  187. BACK(edge,mesh->rings,j).t = 0.5;
  188. /* 0.33 below is a fudge factor. */
  189. BACK(edge,mesh->rings,j).x = sc + 0.33*(sc - st[0]);
  190. BACK(edge,mesh->rings,j).y = tc + 0.33*(tc - st[1]);
  191. }
  192. }
  193. }
  194. for (edge=0; edge<4; edge++) {
  195. for (j=0; j<mesh->steps; j++) {
  196. for (i=1; i<mesh->rings-1; i++) {
  197. }
  198. }
  199. }
  200. }
  201. void
  202. smapConfigureSphereMapMesh(SphereMap *smap,
  203. int steps, int rings, int edgeExtend)
  204. {
  205. SphereMapMesh *mesh = smap->mesh;
  206. if (steps == mesh->steps &&
  207. rings == mesh->rings &&
  208. edgeExtend == mesh->edgeExtend) {
  209. return;
  210. }
  211. mesh->steps = steps;
  212. mesh->rings = rings;
  213. mesh->edgeExtend = edgeExtend;
  214. mesh->face = NULL;
  215. mesh->back = NULL;
  216. }