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.

348 lines
10 KiB

  1. //-----------------------------------------------------------------------------
  2. // File: pipe.cpp
  3. //
  4. // Desc: Pipe base class stuff
  5. //
  6. // Copyright (c) 1994-2000 Microsoft Corporation
  7. //-----------------------------------------------------------------------------
  8. #include "stdafx.h"
  9. //-----------------------------------------------------------------------------
  10. // Name: PIPE constructor
  11. // Desc:
  12. //-----------------------------------------------------------------------------
  13. PIPE::PIPE( STATE *state )
  14. {
  15. m_pState = state;
  16. m_pWorldMatrixStack = m_pState->m_pWorldMatrixStack;
  17. m_radius = m_pState->m_radius;
  18. // default direction choosing is random
  19. m_chooseDirMethod = CHOOSE_DIR_RANDOM_WEIGHTED;
  20. m_chooseStartPosMethod = CHOOSE_STARTPOS_RANDOM;
  21. m_weightStraight = 1;
  22. }
  23. //-----------------------------------------------------------------------------
  24. // Name:
  25. // Desc:
  26. //-----------------------------------------------------------------------------
  27. PIPE::~PIPE()
  28. {
  29. }
  30. //-----------------------------------------------------------------------------
  31. // Name: ChooseMaterial
  32. // Desc:
  33. //-----------------------------------------------------------------------------
  34. void PIPE::ChooseMaterial( )
  35. {
  36. if( m_pState->m_bUseTexture )
  37. m_pMat = RandomTexMaterial();
  38. else
  39. m_pMat = RandomTeaMaterial();
  40. }
  41. //-----------------------------------------------------------------------------
  42. // Name: SetChooseDirectionMethod
  43. // Desc:
  44. //-----------------------------------------------------------------------------
  45. void PIPE::SetChooseDirectionMethod( int method )
  46. {
  47. m_chooseDirMethod = method;
  48. }
  49. //-----------------------------------------------------------------------------
  50. // Name: ChooseNewDirection
  51. // Desc: Call direction-finding function based on current method
  52. // This is a generic entry point that is used by some pipe types
  53. //-----------------------------------------------------------------------------
  54. int PIPE::ChooseNewDirection()
  55. {
  56. NODE_ARRAY* nodes = m_pState->m_nodes;
  57. int bestDirs[NUM_DIRS], nBestDirs;
  58. // figger out which fn to call
  59. switch( m_chooseDirMethod )
  60. {
  61. case CHOOSE_DIR_CHASE:
  62. if( nBestDirs = GetBestDirsForChase( bestDirs ) )
  63. return nodes->ChoosePreferredDirection( &m_curPos, m_lastDir,
  64. bestDirs, nBestDirs );
  65. // else lead pipe must have died, so fall thru:
  66. case CHOOSE_DIR_RANDOM_WEIGHTED :
  67. default:
  68. return nodes->ChooseRandomDirection( &m_curPos, m_lastDir, m_weightStraight );
  69. }
  70. }
  71. //-----------------------------------------------------------------------------
  72. // Name: GetBestDirsForChase
  73. // Desc: Find the best directions to take to close in on the lead pipe in chase mode.
  74. //
  75. // mf: ? but want to use similar scheme for turning flex pipes !! (later)
  76. //-----------------------------------------------------------------------------
  77. int PIPE::GetBestDirsForChase( int *bestDirs )
  78. {
  79. // Figure out best dirs to close in on leadPos
  80. //mf: will have to 'protect' leadPos with GetLeadPos() for multi-threading
  81. IPOINT3D* leadPos = &m_pState->m_pLeadPipe->m_curPos;
  82. IPOINT3D delta;
  83. int numDirs = 0;
  84. delta.x = leadPos->x - m_curPos.x;
  85. delta.y = leadPos->y - m_curPos.y;
  86. delta.z = leadPos->z - m_curPos.z;
  87. if( delta.x )
  88. {
  89. numDirs++;
  90. *bestDirs++ = delta.x > 0 ? PLUS_X : MINUS_X;
  91. }
  92. if( delta.y )
  93. {
  94. numDirs++;
  95. *bestDirs++ = delta.y > 0 ? PLUS_Y : MINUS_Y;
  96. }
  97. if( delta.z )
  98. {
  99. numDirs++;
  100. *bestDirs++ = delta.z > 0 ? PLUS_Z : MINUS_Z;
  101. }
  102. // It should be impossible for numDirs = 0 (all deltas = 0), as this
  103. // means curPos = leadPos
  104. return numDirs;
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Name: SetChooseStartPosMethod
  108. // Desc:
  109. //-----------------------------------------------------------------------------
  110. void PIPE::SetChooseStartPosMethod( int method )
  111. {
  112. m_chooseStartPosMethod = method;
  113. }
  114. //-----------------------------------------------------------------------------
  115. // Name: PIPE::SetStartPos
  116. // Desc: - Find an empty node to start the pipe on
  117. //-----------------------------------------------------------------------------
  118. BOOL PIPE::SetStartPos()
  119. {
  120. NODE_ARRAY* nodes = m_pState->m_nodes;
  121. switch( m_chooseStartPosMethod )
  122. {
  123. case CHOOSE_STARTPOS_RANDOM:
  124. default:
  125. if( !nodes->FindRandomEmptyNode( &m_curPos ) )
  126. {
  127. return FALSE;
  128. }
  129. return TRUE;
  130. case CHOOSE_STARTPOS_FURTHEST:
  131. // find node furthest away from curPos
  132. IPOINT3D refPos, numNodes;
  133. nodes->GetNodeCount( &numNodes );
  134. refPos.x = (m_curPos.x >= (numNodes.x / 2)) ? 0 : numNodes.x - 1;
  135. refPos.y = (m_curPos.y >= (numNodes.y / 2)) ? 0 : numNodes.y - 1;
  136. refPos.z = (m_curPos.z >= (numNodes.z / 2)) ? 0 : numNodes.z - 1;
  137. if( !nodes->TakeClosestEmptyNode( &m_curPos, &refPos ) )
  138. {
  139. return FALSE;
  140. }
  141. return TRUE;
  142. }
  143. }
  144. //-----------------------------------------------------------------------------
  145. // Name: PIPE::IsStuck
  146. // Desc:
  147. //-----------------------------------------------------------------------------
  148. BOOL PIPE::IsStuck()
  149. {
  150. return m_status == PIPE_STUCK;
  151. }
  152. //-----------------------------------------------------------------------------
  153. // Name: PIPE::TranslateToCurrentPosition
  154. // Desc:
  155. //-----------------------------------------------------------------------------
  156. void PIPE::TranslateToCurrentPosition()
  157. {
  158. IPOINT3D numNodes;
  159. float divSize = m_pState->m_view.m_divSize;
  160. // this requires knowing the size of the node array
  161. m_pState->m_nodes->GetNodeCount( &numNodes );
  162. m_pWorldMatrixStack->TranslateLocal( (m_curPos.x - (numNodes.x - 1)/2.0f )*divSize,
  163. (m_curPos.y - (numNodes.y - 1)/2.0f )*divSize,
  164. (m_curPos.z - (numNodes.z - 1)/2.0f )*divSize );
  165. }
  166. //-----------------------------------------------------------------------------
  167. // Name: UpdateCurrentPosition
  168. // Desc: Increment current position according to direction taken
  169. //-----------------------------------------------------------------------------
  170. void PIPE::UpdateCurrentPosition( int newDir )
  171. {
  172. switch( newDir )
  173. {
  174. case PLUS_X:
  175. m_curPos.x += 1;
  176. break;
  177. case MINUS_X:
  178. m_curPos.x -= 1;
  179. break;
  180. case PLUS_Y:
  181. m_curPos.y += 1;
  182. break;
  183. case MINUS_Y:
  184. m_curPos.y -= 1;
  185. break;
  186. case PLUS_Z:
  187. m_curPos.z += 1;
  188. break;
  189. case MINUS_Z:
  190. m_curPos.z -= 1;
  191. break;
  192. }
  193. }
  194. //-----------------------------------------------------------------------------
  195. // Name: align_plusz
  196. // Desc: - Aligns the z axis along specified direction
  197. // - Used for all types of pipes
  198. //-----------------------------------------------------------------------------
  199. void PIPE::align_plusz( int newDir )
  200. {
  201. static D3DXVECTOR3 xAxis = D3DXVECTOR3(1.0f,0.0f,0.0f);
  202. static D3DXVECTOR3 yAxis = D3DXVECTOR3(0.0f,1.0f,0.0f);
  203. // align +z along new direction
  204. switch( newDir )
  205. {
  206. case PLUS_X:
  207. m_pWorldMatrixStack->RotateAxisLocal( &yAxis, PI/2.0f );
  208. break;
  209. case MINUS_X:
  210. m_pWorldMatrixStack->RotateAxisLocal( &yAxis, -PI/2.0f );
  211. break;
  212. case PLUS_Y:
  213. m_pWorldMatrixStack->RotateAxisLocal( &xAxis, -PI/2.0f );
  214. break;
  215. case MINUS_Y:
  216. m_pWorldMatrixStack->RotateAxisLocal( &xAxis, PI/2.0f );
  217. break;
  218. case PLUS_Z:
  219. m_pWorldMatrixStack->RotateAxisLocal( &yAxis, 0.0f );
  220. break;
  221. case MINUS_Z:
  222. m_pWorldMatrixStack->RotateAxisLocal( &yAxis, PI );
  223. break;
  224. }
  225. }
  226. //-----------------------------------------------------------------------------
  227. // Name:
  228. // Desc: this array tells you which way the notch will be once you make
  229. // a turn
  230. // format: notchTurn[oldDir][newDir][notchVec]
  231. //-----------------------------------------------------------------------------
  232. int notchTurn[NUM_DIRS][NUM_DIRS][NUM_DIRS] =
  233. {
  234. // oldDir = +x
  235. iXX, iXX, iXX, iXX, iXX, iXX,
  236. iXX, iXX, iXX, iXX, iXX, iXX,
  237. iXX, iXX, MINUS_X,PLUS_X, PLUS_Z, MINUS_Z,
  238. iXX, iXX, PLUS_X, MINUS_X,PLUS_Z, MINUS_Z,
  239. iXX, iXX, PLUS_Y, MINUS_Y,MINUS_X,PLUS_X,
  240. iXX, iXX, PLUS_Y, MINUS_Y,PLUS_X, MINUS_X,
  241. // oldDir = -x
  242. iXX, iXX, iXX, iXX, iXX, iXX,
  243. iXX, iXX, iXX, iXX, iXX, iXX,
  244. iXX, iXX, PLUS_X, MINUS_X,PLUS_Z, MINUS_Z,
  245. iXX, iXX, MINUS_X,PLUS_X, PLUS_Z, MINUS_Z,
  246. iXX, iXX, PLUS_Y, MINUS_Y,PLUS_X, MINUS_X,
  247. iXX, iXX, PLUS_Y, MINUS_Y,MINUS_X,PLUS_X,
  248. // oldDir = +y
  249. MINUS_Y,PLUS_Y, iXX, iXX, PLUS_Z, MINUS_Z,
  250. PLUS_Y, MINUS_Y,iXX, iXX, PLUS_Z, MINUS_Z,
  251. iXX, iXX, iXX, iXX, iXX, iXX,
  252. iXX, iXX, iXX, iXX, iXX, iXX,
  253. PLUS_X, MINUS_X,iXX, iXX, MINUS_Y,PLUS_Y,
  254. PLUS_X, MINUS_X,iXX, iXX, PLUS_Y, MINUS_Y,
  255. // oldDir = -y
  256. PLUS_Y, MINUS_Y,iXX, iXX, PLUS_Z, MINUS_Z,
  257. MINUS_Y,PLUS_Y, iXX, iXX, PLUS_Z, MINUS_Z,
  258. iXX, iXX, iXX, iXX, iXX, iXX,
  259. iXX, iXX, iXX, iXX, iXX, iXX,
  260. PLUS_X, MINUS_X,iXX, iXX, PLUS_Y, MINUS_Y,
  261. PLUS_X, MINUS_X,iXX, iXX, MINUS_Y,PLUS_Y,
  262. // oldDir = +z
  263. MINUS_Z,PLUS_Z, PLUS_Y, MINUS_Y,iXX, iXX,
  264. PLUS_Z, MINUS_Z,PLUS_Y, MINUS_Y,iXX, iXX,
  265. PLUS_X, MINUS_X,MINUS_Z,PLUS_Z, iXX, iXX,
  266. PLUS_X, MINUS_X,PLUS_Z, MINUS_Z,iXX, iXX,
  267. iXX, iXX, iXX, iXX, iXX, iXX,
  268. iXX, iXX, iXX, iXX, iXX, iXX,
  269. // oldDir = -z
  270. PLUS_Z, MINUS_Z,PLUS_Y, MINUS_Y,iXX, iXX,
  271. MINUS_Z,PLUS_Z, PLUS_Y, MINUS_Y,iXX, iXX,
  272. PLUS_X, MINUS_X,PLUS_Z, MINUS_Z,iXX, iXX,
  273. PLUS_X, MINUS_X,MINUS_Z,PLUS_Z, iXX, iXX,
  274. iXX, iXX, iXX, iXX, iXX, iXX,
  275. iXX, iXX, iXX, iXX, iXX, iXX
  276. };