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.

358 lines
10 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: pipe.cxx
  3. *
  4. * - Pipe base class stuff
  5. *
  6. * Copyright (c) 1995 Microsoft Corporation
  7. *
  8. \**************************************************************************/
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <math.h>
  13. #include <sys/types.h>
  14. #include <sys/timeb.h>
  15. #include <time.h>
  16. #include <windows.h>
  17. #include "sspipes.h"
  18. #include "state.h"
  19. #include "pipe.h"
  20. /******************************Public*Routine******************************\
  21. * PIPE constructor
  22. *
  23. * Nov. 95 [marcfo]
  24. *
  25. \**************************************************************************/
  26. PIPE::PIPE( STATE *state )
  27. {
  28. pState = state;
  29. bTexture = pState->bTexture;
  30. radius = pState->radius;
  31. // default direction choosing is random
  32. chooseDirMethod = CHOOSE_DIR_RANDOM_WEIGHTED;
  33. chooseStartPosMethod = CHOOSE_STARTPOS_RANDOM;
  34. weightStraight = 1;
  35. }
  36. /******************************Public*Routine******************************\
  37. * ChooseMaterial
  38. *
  39. \**************************************************************************/
  40. void
  41. PIPE::ChooseMaterial( )
  42. {
  43. if( bTexture )
  44. ss_RandomTexMaterial( TRUE );
  45. else
  46. ss_RandomTeaMaterial( TRUE );
  47. }
  48. /**************************************************************************\
  49. *
  50. * DrawTeapot
  51. *
  52. \**************************************************************************/
  53. extern void ResetEvaluator( BOOL bTexture );
  54. void
  55. PIPE::DrawTeapot( )
  56. {
  57. glFrontFace( GL_CW );
  58. glEnable( GL_NORMALIZE );
  59. auxSolidTeapot(2.5 * radius);
  60. glDisable( GL_NORMALIZE );
  61. glFrontFace( GL_CCW );
  62. if( type != TYPE_NORMAL ) {
  63. // Re-init flex's evaluator state (teapot uses evaluators as well,
  64. // and messes up the state).
  65. ResetEvaluator( bTexture );
  66. }
  67. }
  68. /******************************Public*Routine******************************\
  69. * SetChooseDirectionMethod
  70. *
  71. * Nov. 95 [marcfo]
  72. *
  73. \**************************************************************************/
  74. void
  75. PIPE::SetChooseDirectionMethod( int method )
  76. {
  77. chooseDirMethod = method;
  78. }
  79. /**************************************************************************\
  80. *
  81. * ChooseNewDirection
  82. *
  83. * Call direction-finding function based on current method
  84. * This is a generic entry point that is used by some pipe types
  85. *
  86. \**************************************************************************/
  87. int
  88. PIPE::ChooseNewDirection()
  89. {
  90. NODE_ARRAY *nodes = pState->nodes;
  91. int bestDirs[NUM_DIRS], nBestDirs;
  92. // figger out which fn to call
  93. switch( chooseDirMethod ) {
  94. case CHOOSE_DIR_CHASE:
  95. if( nBestDirs = GetBestDirsForChase( bestDirs ) )
  96. return nodes->ChoosePreferredDirection( &curPos, lastDir,
  97. bestDirs, nBestDirs );
  98. // else lead pipe must have died, so fall thru:
  99. case CHOOSE_DIR_RANDOM_WEIGHTED :
  100. default:
  101. return nodes->ChooseRandomDirection( &curPos, lastDir, weightStraight );
  102. }
  103. }
  104. /**************************************************************************\
  105. *
  106. * GetBestDirsForChase
  107. *
  108. * Find the best directions to take to close in on the lead pipe in chase mode.
  109. *
  110. \**************************************************************************/
  111. //mf: ? but want to use similar scheme for turning flex pipes !!
  112. // (later)
  113. int
  114. PIPE::GetBestDirsForChase( int *bestDirs )
  115. {
  116. // Figure out best dirs to close in on leadPos
  117. //mf: will have to 'protect' leadPos with GetLeadPos() for multi-threading
  118. IPOINT3D *leadPos = &pState->pLeadPipe->curPos;
  119. IPOINT3D delta;
  120. int numDirs = 0;
  121. delta.x = leadPos->x - curPos.x;
  122. delta.y = leadPos->y - curPos.y;
  123. delta.z = leadPos->z - curPos.z;
  124. if( delta.x ) {
  125. numDirs++;
  126. *bestDirs++ = delta.x > 0 ? PLUS_X : MINUS_X;
  127. }
  128. if( delta.y ) {
  129. numDirs++;
  130. *bestDirs++ = delta.y > 0 ? PLUS_Y : MINUS_Y;
  131. }
  132. if( delta.z ) {
  133. numDirs++;
  134. *bestDirs++ = delta.z > 0 ? PLUS_Z : MINUS_Z;
  135. }
  136. // It should be impossible for numDirs = 0 (all deltas = 0), as this
  137. // means curPos = leadPos
  138. return numDirs;
  139. }
  140. /******************************Public*Routine******************************\
  141. * SetChooseStartPosMethod
  142. *
  143. * Nov. 95 [marcfo]
  144. *
  145. \**************************************************************************/
  146. void
  147. PIPE::SetChooseStartPosMethod( int method )
  148. {
  149. chooseStartPosMethod = method;
  150. }
  151. /******************************Public*Routine******************************\
  152. * PIPE::SetStartPos
  153. *
  154. * - Find an empty node to start the pipe on
  155. *
  156. \**************************************************************************/
  157. BOOL
  158. PIPE::SetStartPos()
  159. {
  160. NODE_ARRAY *nodes = pState->nodes;
  161. switch( chooseStartPosMethod ) {
  162. case CHOOSE_STARTPOS_RANDOM:
  163. default:
  164. if( !nodes->FindRandomEmptyNode( &curPos ) ) {
  165. return FALSE;
  166. }
  167. return TRUE;
  168. case CHOOSE_STARTPOS_FURTHEST:
  169. // find node furthest away from curPos
  170. IPOINT3D refPos, numNodes;
  171. nodes->GetNodeCount( &numNodes );
  172. refPos.x = (curPos.x >= (numNodes.x / 2)) ? 0 : numNodes.x - 1;
  173. refPos.y = (curPos.y >= (numNodes.y / 2)) ? 0 : numNodes.y - 1;
  174. refPos.z = (curPos.z >= (numNodes.z / 2)) ? 0 : numNodes.z - 1;
  175. if( !nodes->TakeClosestEmptyNode( &curPos, &refPos ) ) {
  176. return FALSE;
  177. }
  178. return TRUE;
  179. }
  180. }
  181. /******************************Public*Routine******************************\
  182. * PIPE::IsStuck
  183. *
  184. * Nov. 95 [marcfo]
  185. *
  186. \**************************************************************************/
  187. BOOL
  188. PIPE::IsStuck()
  189. {
  190. return status == PIPE_STUCK;
  191. }
  192. /******************************Public*Routine******************************\
  193. * PIPE::TranslateToCurrentPosition
  194. *
  195. \**************************************************************************/
  196. void
  197. PIPE::TranslateToCurrentPosition()
  198. {
  199. IPOINT3D numNodes;
  200. float divSize = pState->view.divSize;
  201. // this requires knowing the size of the node array
  202. pState->nodes->GetNodeCount( &numNodes );
  203. glTranslatef( (curPos.x - (numNodes.x - 1)/2.0f )*divSize,
  204. (curPos.y - (numNodes.y - 1)/2.0f )*divSize,
  205. (curPos.z - (numNodes.z - 1)/2.0f )*divSize );
  206. }
  207. /**************************************************************************\
  208. *
  209. * UpdateCurrentPosition
  210. *
  211. * Increment current position according to direction taken
  212. \**************************************************************************/
  213. void
  214. PIPE::UpdateCurrentPosition( int newDir )
  215. {
  216. switch( newDir ) {
  217. case PLUS_X:
  218. curPos.x += 1;
  219. break;
  220. case MINUS_X:
  221. curPos.x -= 1;
  222. break;
  223. case PLUS_Y:
  224. curPos.y += 1;
  225. break;
  226. case MINUS_Y:
  227. curPos.y -= 1;
  228. break;
  229. case PLUS_Z:
  230. curPos.z += 1;
  231. break;
  232. case MINUS_Z:
  233. curPos.z -= 1;
  234. break;
  235. }
  236. }
  237. /******************************Public*Routine******************************\
  238. * align_plusz
  239. *
  240. * - Aligns the z axis along specified direction
  241. * - Used for all types of pipes
  242. *
  243. \**************************************************************************/
  244. void align_plusz( int newDir )
  245. {
  246. // align +z along new direction
  247. switch( newDir ) {
  248. case PLUS_X:
  249. glRotatef( 90.0f, 0.0f, 1.0f, 0.0f);
  250. break;
  251. case MINUS_X:
  252. glRotatef( -90.0f, 0.0f, 1.0f, 0.0f);
  253. break;
  254. case PLUS_Y:
  255. glRotatef( -90.0f, 1.0f, 0.0f, 0.0f);
  256. break;
  257. case MINUS_Y:
  258. glRotatef( 90.0f, 1.0f, 0.0f, 0.0f);
  259. break;
  260. case PLUS_Z:
  261. glRotatef( 0.0f, 0.0f, 1.0f, 0.0f);
  262. break;
  263. case MINUS_Z:
  264. glRotatef( 180.0f, 0.0f, 1.0f, 0.0f);
  265. break;
  266. }
  267. }
  268. /**************************************************************************\
  269. * this array tells you which way the notch will be once you make
  270. * a turn
  271. * format: notchTurn[oldDir][newDir][notchVec]
  272. *
  273. \**************************************************************************/
  274. GLint notchTurn[NUM_DIRS][NUM_DIRS][NUM_DIRS] = {
  275. // oldDir = +x
  276. iXX, iXX, iXX, iXX, iXX, iXX,
  277. iXX, iXX, iXX, iXX, iXX, iXX,
  278. iXX, iXX, MINUS_X,PLUS_X, PLUS_Z, MINUS_Z,
  279. iXX, iXX, PLUS_X, MINUS_X,PLUS_Z, MINUS_Z,
  280. iXX, iXX, PLUS_Y, MINUS_Y,MINUS_X,PLUS_X,
  281. iXX, iXX, PLUS_Y, MINUS_Y,PLUS_X, MINUS_X,
  282. // oldDir = -x
  283. iXX, iXX, iXX, iXX, iXX, iXX,
  284. iXX, iXX, iXX, iXX, iXX, iXX,
  285. iXX, iXX, PLUS_X, MINUS_X,PLUS_Z, MINUS_Z,
  286. iXX, iXX, MINUS_X,PLUS_X, PLUS_Z, MINUS_Z,
  287. iXX, iXX, PLUS_Y, MINUS_Y,PLUS_X, MINUS_X,
  288. iXX, iXX, PLUS_Y, MINUS_Y,MINUS_X,PLUS_X,
  289. // oldDir = +y
  290. MINUS_Y,PLUS_Y, iXX, iXX, PLUS_Z, MINUS_Z,
  291. PLUS_Y, MINUS_Y,iXX, iXX, PLUS_Z, MINUS_Z,
  292. iXX, iXX, iXX, iXX, iXX, iXX,
  293. iXX, iXX, iXX, iXX, iXX, iXX,
  294. PLUS_X, MINUS_X,iXX, iXX, MINUS_Y,PLUS_Y,
  295. PLUS_X, MINUS_X,iXX, iXX, PLUS_Y, MINUS_Y,
  296. // oldDir = -y
  297. PLUS_Y, MINUS_Y,iXX, iXX, PLUS_Z, MINUS_Z,
  298. MINUS_Y,PLUS_Y, iXX, iXX, PLUS_Z, MINUS_Z,
  299. iXX, iXX, iXX, iXX, iXX, iXX,
  300. iXX, iXX, iXX, iXX, iXX, iXX,
  301. PLUS_X, MINUS_X,iXX, iXX, PLUS_Y, MINUS_Y,
  302. PLUS_X, MINUS_X,iXX, iXX, MINUS_Y,PLUS_Y,
  303. // oldDir = +z
  304. MINUS_Z,PLUS_Z, PLUS_Y, MINUS_Y,iXX, iXX,
  305. PLUS_Z, MINUS_Z,PLUS_Y, MINUS_Y,iXX, iXX,
  306. PLUS_X, MINUS_X,MINUS_Z,PLUS_Z, iXX, iXX,
  307. PLUS_X, MINUS_X,PLUS_Z, MINUS_Z,iXX, iXX,
  308. iXX, iXX, iXX, iXX, iXX, iXX,
  309. iXX, iXX, iXX, iXX, iXX, iXX,
  310. // oldDir = -z
  311. PLUS_Z, MINUS_Z,PLUS_Y, MINUS_Y,iXX, iXX,
  312. MINUS_Z,PLUS_Z, PLUS_Y, MINUS_Y,iXX, iXX,
  313. PLUS_X, MINUS_X,PLUS_Z, MINUS_Z,iXX, iXX,
  314. PLUS_X, MINUS_X,MINUS_Z,PLUS_Z, iXX, iXX,
  315. iXX, iXX, iXX, iXX, iXX, iXX,
  316. iXX, iXX, iXX, iXX, iXX, iXX
  317. };