Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

337 lines
8.6 KiB

4 years ago
  1. /******************************Module*Header*******************************\
  2. * Module Name: genlem.c
  3. *
  4. * The Twist style of the 3D Flying Objects screen saver.
  5. *
  6. * Solid model of a 3D lemniscate.
  7. *
  8. * Copyright (c) 1994 Microsoft Corporation
  9. *
  10. \**************************************************************************/
  11. #include <stdlib.h>
  12. #include <windows.h>
  13. #include <GL\gl.h>
  14. #include <string.h>
  15. #include <math.h>
  16. #include "ss3dfo.h"
  17. #include "mesh.h"
  18. #define ROT_PREC 10
  19. #define NORMS(x, y) lemMesh.norms[((x) * iPrec) + y]
  20. #define GRID(x, y) lemMesh.pts[((x) * iPrec) + y]
  21. static MESH lemMesh;
  22. static POINT3D basis[ROT_PREC];
  23. static double zrot = 0.2;
  24. static int iPrec = 32;
  25. static double *lemX;
  26. static double *lemY;
  27. static double *lemXT;
  28. static double *lemYT;
  29. static void getLem(double index, double max, double *angle, double *r)
  30. {
  31. double a, sina;
  32. a = (index * PI) / (max - 1.0);
  33. if (a >= PI)
  34. a -= PI;
  35. if (a > PI / 2.0) {
  36. *angle = (2.0 * PI) - a;
  37. sina = sin( 2.0 * *angle );
  38. if( sina < 0.0 )
  39. sina = 0.0; // protect against sqrt fpe
  40. *r = 0.5 * sqrt(sina);
  41. } else {
  42. *angle = a;
  43. sina = sin( 2.0 * *angle );
  44. if( sina < 0.0 )
  45. sina = 0.0;
  46. *r = 0.5 * sqrt(sina);
  47. }
  48. }
  49. static void initLemCoords(int iMax)
  50. {
  51. int i;
  52. double max = (double)iMax;
  53. double angle;
  54. double r;
  55. for (i = 0; i < iMax; i++) {
  56. getLem((double)i, (double)iPrec, &angle, &r);
  57. lemX[i] = r * cos(angle);
  58. lemY[i] = r * sin(angle);
  59. getLem((double)i + 0.00001, (double)iPrec, &angle, &r);
  60. lemXT[i] = r * cos(angle);
  61. lemYT[i] = r * sin(angle);
  62. }
  63. }
  64. void genLemniscate(void)
  65. {
  66. int i;
  67. int j;
  68. double posInc = 2.0 / (float)iPrec;
  69. int facecount = 0;
  70. int ptcount = 0;
  71. POINT3D norm;
  72. static float twistFact = 0.0f;
  73. static float twistFactAdd = 0.05f;
  74. POINT3D a[ROT_PREC];
  75. POINT3D b[ROT_PREC];
  76. MATRIX matrix;
  77. MESH *mesh = &lemMesh;
  78. mesh->numPoints = 0;
  79. mesh->numFaces = 0;
  80. for (i = 0; i < (iPrec - 1) * (ROT_PREC - 1); i++)
  81. mesh->norms[i] = ss_ptZero;
  82. for (i = 0; i < (iPrec - 1); i++) {
  83. double x1, y1, x2, y2;
  84. double len;
  85. double sinAngle;
  86. double rotZ;
  87. int id[4];
  88. x1 = lemX[i];
  89. y1 = lemY[i];
  90. x2 = lemXT[i];
  91. y2 = lemYT[i];
  92. x2 -= x1;
  93. y2 -= y1;
  94. len = sqrt(x2 * x2 + y2 * y2);
  95. if (len > 0.0)
  96. sinAngle = y2 / len;
  97. else
  98. sinAngle = 0.0;
  99. if (y2 < 0.0)
  100. sinAngle = -sinAngle;
  101. rotZ = asin(sinAngle);
  102. if (x2 < 0.0)
  103. rotZ = PI - rotZ;
  104. if (y2 < 0.0)
  105. rotZ = -rotZ;
  106. if (rotZ < 0.0)
  107. rotZ = 2.0 * PI + rotZ;
  108. ss_matrixIdent(&matrix);
  109. ss_matrixRotate(&matrix, 0.0, 0.0, -rotZ);
  110. ss_matrixTranslate(&matrix, x1, y1,
  111. twistFact * cos((2.0 * PI * (float)i) / ((float)iPrec - 1)));
  112. for (j = 0; j < ROT_PREC; j++)
  113. ss_xformPoint(&a[j], &basis[j], &matrix);
  114. x1 = lemX[i+1];
  115. y1 = lemY[i+1];
  116. x2 = lemXT[i+1];
  117. y2 = lemYT[i+1];
  118. x2 -= x1;
  119. y2 -= y1;
  120. len = sqrt(x2 * x2 + y2 * y2);
  121. if (len > 0.0)
  122. sinAngle = y2 / len;
  123. else
  124. sinAngle = 0.0;
  125. if (y2 < 0.0)
  126. sinAngle = -sinAngle;
  127. rotZ = asin(sinAngle);
  128. if (x2 < 0.0)
  129. rotZ = PI - rotZ;
  130. if (y2 < 0.0)
  131. rotZ = -rotZ;
  132. if (rotZ < 0.0)
  133. rotZ = 2.0 * PI + rotZ;
  134. ss_matrixIdent(&matrix);
  135. ss_matrixRotate(&matrix, 0.0, 0.0, -rotZ);
  136. ss_matrixTranslate(&matrix, x1, y1,
  137. twistFact * cos((2.0 * PI * ((float)i + 1.0)) / ((float)iPrec - 1)));
  138. for (j = 0; j < ROT_PREC; j++)
  139. ss_xformPoint(&b[j], &basis[j], &matrix);
  140. memcpy(&mesh->pts[ptcount], &a, sizeof(POINT3D) * (ROT_PREC - 1));
  141. ptcount += (ROT_PREC - 1);
  142. mesh->numPoints += (ROT_PREC - 1);
  143. for (j = 0; j < (ROT_PREC - 1); j++) {
  144. int k;
  145. int jj;
  146. if (j == (ROT_PREC - 2))
  147. jj = 0;
  148. else
  149. jj = j + 1;
  150. ss_calcNorm(&norm, &b[j + 1], &b[j], &a[j]);
  151. mesh->faces[facecount].material = 3;
  152. mesh->faces[facecount].norm = norm;
  153. if (i == iPrec - 2) {
  154. id[0] = mesh->faces[facecount].p[0] = j;
  155. id[1] = mesh->faces[facecount].p[1] = jj;
  156. } else {
  157. id[0] = mesh->faces[facecount].p[0] = ptcount + j;
  158. id[1] = mesh->faces[facecount].p[1] = ptcount + jj;
  159. }
  160. id[2] = mesh->faces[facecount].p[2] = ptcount - (ROT_PREC - 1) + j;
  161. id[3] = mesh->faces[facecount].p[3] = ptcount - (ROT_PREC - 1) + jj;
  162. for (k = 0; k < 4; k++) {
  163. POINT3D *pn = &mesh->norms[id[k]];
  164. pn->x += norm.x;
  165. pn->y += norm.y;
  166. pn->z += norm.z;
  167. }
  168. mesh->numFaces++;
  169. facecount++;
  170. }
  171. }
  172. ss_normalizeNorms(lemMesh.norms, lemMesh.numPoints);
  173. if (twistFact >= 1.0f)
  174. twistFactAdd = -0.01f;
  175. else if (twistFact <= -1.0f)
  176. twistFactAdd = 0.01f;
  177. twistFact += twistFactAdd;
  178. }
  179. void initLemScene()
  180. {
  181. int i;
  182. RGBA lightAmbient = {0.0f, 0.0f, 0.0f, 1.0f};
  183. iPrec = (int)(fTesselFact * 32.5);
  184. if (iPrec < 5)
  185. iPrec = 5;
  186. lemX = SaverAlloc(sizeof(double) * iPrec);
  187. lemY = SaverAlloc(sizeof(double) * iPrec);
  188. lemXT = SaverAlloc(sizeof(double) * iPrec);
  189. lemYT = SaverAlloc(sizeof(double) * iPrec);
  190. glMatrixMode(GL_PROJECTION);
  191. glLoadIdentity();
  192. glOrtho(-1.5, 1.5, -1.5, 1.5, 0.0, 3.0);
  193. glTranslatef(0.0f, 0.0f, -1.5f);
  194. newMesh(&lemMesh, (ROT_PREC - 1) * (iPrec - 1) ,
  195. (ROT_PREC - 1) * (iPrec - 1));
  196. for (i = 0; i < ROT_PREC; i++) {
  197. basis[i].x = 0.0f;
  198. basis[i].y = (float) (0.15 * cos((i * 2.0 * PI) / (ROT_PREC - 1.0)));
  199. basis[i].z = (float) (0.15 * sin((i * 2.0 * PI) / (ROT_PREC - 1.0)));
  200. }
  201. initLemCoords(iPrec);
  202. glFrontFace(GL_CW);
  203. glEnable(GL_CULL_FACE);
  204. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (GLfloat *) &lightAmbient);
  205. glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
  206. (GLfloat *) &Material[3].kd);
  207. }
  208. void delLemScene()
  209. {
  210. delMesh(&lemMesh);
  211. SaverFree(lemX);
  212. SaverFree(lemY);
  213. SaverFree(lemXT);
  214. SaverFree(lemYT);
  215. }
  216. void updateLemScene(int flags)
  217. {
  218. static double mxrot = 0.0;
  219. static double myrot = 0.0;
  220. static double mzrot = 0.0;
  221. static double mxrotInc = 0.0;
  222. static double myrotInc = 0.1;
  223. static double zrotInc = 0.1;
  224. static double mzrotInc = 0.0;
  225. static int h = 0;
  226. RGBA color;
  227. MATRIX model;
  228. mxrot += mxrotInc;
  229. myrot += myrotInc;
  230. mzrot += mzrotInc;
  231. if( gbBounce ) {
  232. // floating window bounced off an edge
  233. if (mxrotInc) {
  234. mxrotInc = 0.0;
  235. myrotInc = 0.1;
  236. } else if (myrotInc) {
  237. myrotInc = 0.0;
  238. mzrotInc = 0.1;
  239. } else if (mzrotInc) {
  240. mzrotInc = 0.0;
  241. mxrotInc = 0.1;
  242. }
  243. gbBounce = FALSE;
  244. }
  245. zrot += zrotInc;
  246. if (zrot >= PI / 4.0) {
  247. zrot = PI / 4.0;
  248. zrotInc = -0.03;
  249. } else if (zrot <= -PI / 4.0) {
  250. zrot = -PI / 4.0;
  251. zrotInc = 0.03;
  252. }
  253. genLemniscate();
  254. if (bColorCycle) {
  255. ss_HsvToRgb((float)h, 1.0f, 1.0f, &color );
  256. glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, (GLfloat *) &color);
  257. h++;
  258. h %= 360;
  259. }
  260. glMatrixMode(GL_PROJECTION);
  261. glLoadIdentity();
  262. glOrtho(-1.5, 1.5, -1.5, 1.5, 0.0, 3.0);
  263. glTranslatef(0.0f, 0.0f, -1.5f);
  264. glRotatef((GLfloat) (zrot * (180.0 / PI)), 0.0f, 1.0f, 0.0f);
  265. glRotatef(50.0f, 1.0f, 0.0f, 0.0f);
  266. glRotatef(50.0f, 0.0f, 0.0f, 1.0f);
  267. glMatrixMode(GL_MODELVIEW);
  268. glLoadIdentity();
  269. glTranslatef(0.0f, -0.5f, 0.0f);
  270. glRotatef((GLfloat) (mxrot * (180.0 / PI)), 1.0f, 0.0f, 0.0f);
  271. glRotatef((GLfloat) (myrot * (180.0 / PI)), 0.0f, 1.0f, 0.0f);
  272. glRotatef((GLfloat) (mzrot * (180.0 / PI)), 0.0f, 0.0f, 1.0f);
  273. ss_matrixIdent(&model);
  274. ss_matrixRotate(&model, mxrot, myrot, mzrot);
  275. ss_matrixTranslate(&model, 0.0, -0.5, 0.0);
  276. updateObject(&lemMesh, bSmoothShading);
  277. }