Source code of Windows XP (NT5)
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.

390 lines
10 KiB

  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 <d3dx8.h>
  18. #include "D3DSaver.h"
  19. #include "FlyingObjects.h"
  20. #include "mesh.h"
  21. #define ROT_PREC 10
  22. #define NORMS(x, y) lemMesh.norms[((x) * iPrec) + y]
  23. #define GRID(x, y) lemMesh.pts[((x) * iPrec) + y]
  24. static MESH lemMesh;
  25. static POINT3D basis[ROT_PREC];
  26. static double zrot = 0.2;
  27. static int iPrec = 32;
  28. static double *lemX;
  29. static double *lemY;
  30. static double *lemXT;
  31. static double *lemYT;
  32. static void getLem(double index, double max, double *angle, double *r)
  33. {
  34. double a, sina;
  35. a = (index * PI) / (max - 1.0);
  36. if (a >= PI)
  37. a -= PI;
  38. if (a > PI / 2.0) {
  39. *angle = (2.0 * PI) - a;
  40. sina = sin( 2.0 * *angle );
  41. if( sina < 0.0 )
  42. sina = 0.0; // protect against sqrt fpe
  43. *r = 0.5 * sqrt(sina);
  44. } else {
  45. *angle = a;
  46. sina = sin( 2.0 * *angle );
  47. if( sina < 0.0 )
  48. sina = 0.0;
  49. *r = 0.5 * sqrt(sina);
  50. }
  51. }
  52. static void initLemCoords(int iMax)
  53. {
  54. int i;
  55. double max = (double)iMax;
  56. double angle;
  57. double r;
  58. for (i = 0; i < iMax; i++) {
  59. getLem((double)i, (double)iPrec, &angle, &r);
  60. lemX[i] = r * cos(angle);
  61. lemY[i] = r * sin(angle);
  62. getLem((double)i + 0.00001, (double)iPrec, &angle, &r);
  63. lemXT[i] = r * cos(angle);
  64. lemYT[i] = r * sin(angle);
  65. }
  66. }
  67. void genLemniscate(void)
  68. {
  69. int i;
  70. int j;
  71. double posInc = 2.0 / (float)iPrec;
  72. int facecount = 0;
  73. int ptcount = 0;
  74. POINT3D norm;
  75. static float twistFact = 0.0f;
  76. static float twistFactAdd = 0.05f;
  77. POINT3D a[ROT_PREC];
  78. POINT3D b[ROT_PREC];
  79. MATRIX matrix;
  80. MESH *mesh = &lemMesh;
  81. mesh->numPoints = 0;
  82. mesh->numFaces = 0;
  83. for (i = 0; i < (iPrec - 1) * (ROT_PREC - 1); i++)
  84. mesh->norms[i] = ss_ptZero;
  85. for (i = 0; i < (iPrec - 1); i++) {
  86. double x1, y1, x2, y2;
  87. double len;
  88. double sinAngle;
  89. double rotZ;
  90. int id[4];
  91. x1 = lemX[i];
  92. y1 = lemY[i];
  93. x2 = lemXT[i];
  94. y2 = lemYT[i];
  95. x2 -= x1;
  96. y2 -= y1;
  97. len = sqrt(x2 * x2 + y2 * y2);
  98. if (len > 0.0)
  99. sinAngle = y2 / len;
  100. else
  101. sinAngle = 0.0;
  102. if (y2 < 0.0)
  103. sinAngle = -sinAngle;
  104. rotZ = asin(sinAngle);
  105. if (x2 < 0.0)
  106. rotZ = PI - rotZ;
  107. if (y2 < 0.0)
  108. rotZ = -rotZ;
  109. if (rotZ < 0.0)
  110. rotZ = 2.0 * PI + rotZ;
  111. ss_matrixIdent(&matrix);
  112. ss_matrixRotate(&matrix, 0.0, 0.0, -rotZ);
  113. ss_matrixTranslate(&matrix, x1, y1,
  114. twistFact * cos((2.0 * PI * (float)i) / ((float)iPrec - 1)));
  115. for (j = 0; j < ROT_PREC; j++)
  116. ss_xformPoint(&a[j], &basis[j], &matrix);
  117. x1 = lemX[i+1];
  118. y1 = lemY[i+1];
  119. x2 = lemXT[i+1];
  120. y2 = lemYT[i+1];
  121. x2 -= x1;
  122. y2 -= y1;
  123. len = sqrt(x2 * x2 + y2 * y2);
  124. if (len > 0.0)
  125. sinAngle = y2 / len;
  126. else
  127. sinAngle = 0.0;
  128. if (y2 < 0.0)
  129. sinAngle = -sinAngle;
  130. rotZ = asin(sinAngle);
  131. if (x2 < 0.0)
  132. rotZ = PI - rotZ;
  133. if (y2 < 0.0)
  134. rotZ = -rotZ;
  135. if (rotZ < 0.0)
  136. rotZ = 2.0 * PI + rotZ;
  137. ss_matrixIdent(&matrix);
  138. ss_matrixRotate(&matrix, 0.0, 0.0, -rotZ);
  139. ss_matrixTranslate(&matrix, x1, y1,
  140. twistFact * cos((2.0 * PI * ((float)i + 1.0)) / ((float)iPrec - 1)));
  141. for (j = 0; j < ROT_PREC; j++)
  142. ss_xformPoint(&b[j], &basis[j], &matrix);
  143. memcpy(&mesh->pts[ptcount], &a, sizeof(POINT3D) * (ROT_PREC - 1));
  144. ptcount += (ROT_PREC - 1);
  145. mesh->numPoints += (ROT_PREC - 1);
  146. for (j = 0; j < (ROT_PREC - 1); j++) {
  147. int k;
  148. int jj;
  149. if (j == (ROT_PREC - 2))
  150. jj = 0;
  151. else
  152. jj = j + 1;
  153. ss_calcNorm(&norm, &b[j + 1], &b[j], &a[j]);
  154. mesh->faces[facecount].material = 3;
  155. mesh->faces[facecount].norm = norm;
  156. if (i == iPrec - 2) {
  157. id[0] = mesh->faces[facecount].p[0] = j;
  158. id[1] = mesh->faces[facecount].p[1] = jj;
  159. } else {
  160. id[0] = mesh->faces[facecount].p[0] = ptcount + j;
  161. id[1] = mesh->faces[facecount].p[1] = ptcount + jj;
  162. }
  163. id[2] = mesh->faces[facecount].p[2] = ptcount - (ROT_PREC - 1) + j;
  164. id[3] = mesh->faces[facecount].p[3] = ptcount - (ROT_PREC - 1) + jj;
  165. for (k = 0; k < 4; k++) {
  166. POINT3D *pn = &mesh->norms[id[k]];
  167. pn->x += norm.x;
  168. pn->y += norm.y;
  169. pn->z += norm.z;
  170. }
  171. mesh->numFaces++;
  172. facecount++;
  173. }
  174. }
  175. ss_normalizeNorms(lemMesh.norms, lemMesh.numPoints);
  176. if (twistFact >= 1.0f)
  177. twistFactAdd = -0.01f;
  178. else if (twistFact <= -1.0f)
  179. twistFactAdd = 0.01f;
  180. twistFact += twistFactAdd;
  181. }
  182. BOOL initLemScene()
  183. {
  184. int i;
  185. RGBA lightAmbient = {0.0f, 0.0f, 0.0f, 1.0f};
  186. iPrec = (int)(fTesselFact * 32.5);
  187. if (iPrec < 5)
  188. iPrec = 5;
  189. lemX = (double*)SaverAlloc(sizeof(double) * iPrec);
  190. if( lemX == NULL )
  191. return FALSE;
  192. lemY = (double*)SaverAlloc(sizeof(double) * iPrec);
  193. if( lemY == NULL )
  194. return FALSE;
  195. lemXT = (double*)SaverAlloc(sizeof(double) * iPrec);
  196. if( lemXT == NULL )
  197. return FALSE;
  198. lemYT = (double*)SaverAlloc(sizeof(double) * iPrec);
  199. if( lemYT == NULL )
  200. return FALSE;
  201. /*
  202. D3DXMATRIX matProj;
  203. D3DXMatrixOrthoLH( &matProj, 3.0, 3.0, 0.0f, 3.0f );
  204. m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  205. */
  206. SetProjectionMatrixInfo( TRUE, 3.0f, 3.0f, 0.0f, 3.0f );
  207. D3DXMATRIX matView;
  208. D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
  209. D3DXVECTOR3 vEyePt(0, 0, 1.5f);
  210. D3DXVECTOR3 vLookatPt(0, 0, 0);
  211. D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
  212. m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
  213. if (!newMesh(&lemMesh, (ROT_PREC - 1) * (iPrec - 1) ,
  214. (ROT_PREC - 1) * (iPrec - 1)) )
  215. {
  216. return FALSE;
  217. }
  218. for (i = 0; i < ROT_PREC; i++) {
  219. basis[i].x = 0.0f;
  220. basis[i].y = (float) (0.15 * cos((i * 2.0 * PI) / (ROT_PREC - 1.0)));
  221. basis[i].z = (float) (0.15 * sin((i * 2.0 * PI) / (ROT_PREC - 1.0)));
  222. }
  223. initLemCoords(iPrec);
  224. /*
  225. glFrontFace(GL_CW);
  226. glEnable(GL_CULL_FACE);
  227. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (FLOAT *) &lightAmbient);
  228. */
  229. m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
  230. myglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
  231. (FLOAT *) &Material[3].Diffuse);
  232. return TRUE;
  233. }
  234. void delLemScene()
  235. {
  236. delMesh(&lemMesh);
  237. SaverFree(lemX);
  238. SaverFree(lemY);
  239. SaverFree(lemXT);
  240. SaverFree(lemYT);
  241. }
  242. void updateLemScene(int flags, FLOAT fElapsedTime)
  243. {
  244. static double mxrot = 0.0;
  245. static double myrot = 0.0;
  246. static double mzrot = 0.0;
  247. static double mxrotInc = 0.0;
  248. static double myrotInc = 0.1;
  249. static double zrotInc = 0.1;
  250. static double mzrotInc = 0.0;
  251. RGBA color;
  252. MATRIX model;
  253. D3DXMATRIX mat1, mat2, mat3, mat4, mat5, matFinal;
  254. static FLOAT fH = 0.0f;
  255. FLOAT fTimeFactor = fElapsedTime * 20.0f;
  256. if( fTimeFactor > 0.25f )
  257. fTimeFactor = 0.25f;
  258. mxrot += mxrotInc * fTimeFactor;
  259. myrot += myrotInc * fTimeFactor;
  260. mzrot += mzrotInc * fTimeFactor;
  261. if( gbBounce ) {
  262. // floating window bounced off an edge
  263. if (mxrotInc) {
  264. mxrotInc = 0.0;
  265. myrotInc = 0.1;
  266. } else if (myrotInc) {
  267. myrotInc = 0.0;
  268. mzrotInc = 0.1;
  269. } else if (mzrotInc) {
  270. mzrotInc = 0.0;
  271. mxrotInc = 0.1;
  272. }
  273. gbBounce = FALSE;
  274. }
  275. zrot += zrotInc * fTimeFactor;
  276. if (zrot >= PI / 4.0) {
  277. zrot = PI / 4.0;
  278. zrotInc = -0.03;
  279. } else if (zrot <= -PI / 4.0) {
  280. zrot = -PI / 4.0;
  281. zrotInc = 0.03;
  282. }
  283. genLemniscate();
  284. if (bColorCycle) {
  285. ss_HsvToRgb(fH, 1.0f, 1.0f, &color );
  286. myglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, (FLOAT *) &color);
  287. fH += fTimeFactor;
  288. if( fH >= 360.0f )
  289. fH -= 360.0f;
  290. }
  291. /*
  292. glMatrixMode(GL_PROJECTION);
  293. glLoadIdentity();
  294. glOrtho(-1.5, 1.5, -1.5, 1.5, 0.0, 3.0);
  295. glTranslatef(0.0f, 0.0f, -1.5f);
  296. */
  297. /*
  298. glRotatef((FLOAT) (zrot * (180.0 / PI)), 0.0f, 1.0f, 0.0f);
  299. glRotatef(50.0f, 1.0f, 0.0f, 0.0f);
  300. glRotatef(50.0f, 0.0f, 0.0f, 1.0f);
  301. */
  302. D3DXMATRIX matView;
  303. D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
  304. D3DXVECTOR3 vEyePt(0, 0, 1.5f);
  305. D3DXVECTOR3 vLookatPt(0, 0, 0);
  306. D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
  307. m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
  308. /*
  309. glMatrixMode(GL_MODELVIEW);
  310. glLoadIdentity();
  311. glTranslatef(0.0f, -0.5f, 0.0f);
  312. glRotatef((FLOAT) (mxrot * (180.0 / PI)), 1.0f, 0.0f, 0.0f);
  313. glRotatef((FLOAT) (myrot * (180.0 / PI)), 0.0f, 1.0f, 0.0f);
  314. glRotatef((FLOAT) (mzrot * (180.0 / PI)), 0.0f, 0.0f, 1.0f);
  315. */
  316. D3DXMatrixTranslation(&mat1, 0.0f, -0.5f, 0.0f);
  317. D3DXMatrixRotationX(&mat2, D3DXToRadian((FLOAT)(mxrot * (180.0 / PI))));
  318. D3DXMatrixRotationY(&mat3, D3DXToRadian((FLOAT)(myrot * (180.0 / PI))));
  319. D3DXMatrixRotationZ(&mat4, D3DXToRadian((FLOAT)(mzrot * (180.0 / PI))));
  320. matFinal = mat4 * mat3 * mat2 * mat1 ;
  321. m_pd3dDevice->SetTransform( D3DTS_WORLD , &matFinal );
  322. ss_matrixIdent(&model);
  323. ss_matrixRotate(&model, mxrot, myrot, mzrot);
  324. ss_matrixTranslate(&model, 0.0, -0.5, 0.0);
  325. // updateObject(&lemMesh, bSmoothShading);
  326. RenderMesh3(&lemMesh, bSmoothShading);
  327. }