FLOCK.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:6k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*
  2. **-----------------------------------------------------------------------------
  3. ** File: flock.cpp 
  4. ** Purpose: -- where the boids are
  5. ** Notes:
  6. **
  7. **  Copyright (c) 1995 - 1997 by Microsoft, all rights reserved.
  8. **-----------------------------------------------------------------------------
  9. */
  10. /*
  11. **-----------------------------------------------------------------------------
  12. ** Include Files
  13. **-----------------------------------------------------------------------------
  14. */
  15. #include "Common.h"
  16. #include "Debug.h"
  17. #include "d3dutils.h"
  18. #include "boids.h"
  19. /*
  20. **-----------------------------------------------------------------------------
  21. ** Constants
  22. **-----------------------------------------------------------------------------
  23. */
  24. const float InfluenceRadius = 20.0f;
  25. const float InfluenceRadiusSquared = InfluenceRadius * InfluenceRadius;
  26. const float CollisionFraction = 0.8f;
  27. const float InvCollisionFraction = 1.0f/(1.0f-CollisionFraction);
  28. const float NormalSpeed = 0.1f;
  29. const float AngleTweak = 0.02f;
  30. const float PitchToSpeedRatio = 0.002f;
  31. /*
  32. **-----------------------------------------------------------------------------
  33. ** Functions
  34. **-----------------------------------------------------------------------------
  35. */
  36. /*
  37. **-----------------------------------------------------------------------------
  38. ** Name: UpdateFlock
  39. ** Purpose: Update posiiton of each boid in flock
  40. **-----------------------------------------------------------------------------
  41. */
  42. void
  43. UpdateFlock (Flock flock)
  44. {
  45. int i, j;
  46. float dist;
  47. // first update the dist array 0.0..1.0 with 0.0 being furthest away
  48. for (i=0; i<flock.num_boids; i++) {
  49. for (j=i+1; j<flock.num_boids; j++) {
  50. dist = SquareMagnitude(flock.boids[i].loc - flock.boids[j].loc);
  51. dist = InfluenceRadiusSquared - dist;
  52. if (dist < 0.0f) {
  53. dist = 0.0f;
  54. } else {
  55. dist /= InfluenceRadiusSquared;
  56. }
  57. flock.dist[i][j] = flock.dist[j][i] = dist;
  58. }
  59. flock.dist[i][i] = 0.0f;
  60. flock.boids[i].delta_dir = D3DVECTOR(0.0f);
  61. flock.boids[i].delta_pos = D3DVECTOR(0.0f);
  62. flock.boids[i].delta_cnt = 0;
  63. }
  64. for (i=0; i<flock.num_boids; i++) {
  65. for (j=i+1; j<flock.num_boids; j++) {
  66. // if i is near j have them influence each other
  67. if (flock.dist[i][j] > 0.0) {
  68. D3DVECTOR diff = Normalize(flock.boids[i].loc - flock.boids[j].loc);
  69. D3DVECTOR delta;
  70. float col = 0.0f; // collision weighting
  71. // only do collision testing against the nearest ones
  72. if (flock.dist[i][j] - CollisionFraction > 0.0f) {
  73. col = (flock.dist[i][j] - CollisionFraction) * InvCollisionFraction;
  74. }
  75. // add in a little flock centering
  76. if (flock.dist[i][j] - (1.0-CollisionFraction) > 0.0f) {
  77. col -= flock.dist[i][j] * (1.0f-col);
  78. }
  79. delta = col * diff;
  80. // add in the collision avoidance
  81. flock.boids[i].delta_pos += delta;
  82. flock.boids[j].delta_pos -= delta;
  83. // add in the velocity influences
  84. flock.boids[i].delta_dir += flock.boids[j].dir * flock.dist[i][j];
  85. flock.boids[j].delta_dir += flock.boids[i].dir * flock.dist[i][j];
  86. flock.boids[i].delta_cnt++;
  87. flock.boids[j].delta_cnt++;
  88. }
  89. }
  90. }
  91. // update the boids
  92. for (i=0; i<flock.num_boids; i++) {
  93. if (flock.boids[i].delta_cnt) {
  94. flock.boids[i].delta_dir /= (float)flock.boids[i].delta_cnt;
  95. flock.boids[i].delta_dir -= flock.boids[i].dir;
  96. flock.boids[i].delta_dir *= 1.5f;
  97. }
  98. D3DVECTOR delta = flock.boids[i].delta_dir + flock.boids[i].delta_pos; // + 0.1f * D3DVECTOR(rnd()-rnd(), rnd()-rnd(), rnd()-rnd());
  99. D3DVECTOR offset;
  100. //delta = Normalize(delta);
  101. // add in the influence of the global goal
  102. D3DVECTOR goal = 0.5f * Normalize(flock.goal-flock.boids[i].loc);
  103. delta += goal;
  104. // add in any obstacles
  105. for (j=0; j<flock.num_obs; j++) {
  106. D3DVECTOR ob = flock.boids[i].loc - flock.obs[j].loc;
  107. float radius = flock.obs[j].radius;
  108. float dist = Magnitude(ob);
  109. if (dist > 2*radius)
  110. continue;
  111. ob /= dist; // normalize
  112. dist = 1.0f - dist/(2.0f*radius);
  113. delta += dist * ob * 5.0f;
  114. }
  115. // first deal with pitch changes
  116. if (delta.y > 0.01) { // we're too low
  117. flock.boids[i].pitch += AngleTweak;
  118. if (flock.boids[i].pitch > 0.8f)
  119. flock.boids[i].pitch = 0.8f;
  120. } else if (delta.y < -0.01) { // we're too high
  121. flock.boids[i].pitch -= AngleTweak;
  122. if (flock.boids[i].pitch < -0.8f)
  123. flock.boids[i].pitch = -0.8f;
  124. } else {
  125. // add damping
  126. flock.boids[i].pitch *= 0.98f;
  127. }
  128. // speed up or slow down depending on angle of attack
  129. flock.boids[i].speed -= flock.boids[i].pitch * PitchToSpeedRatio;
  130. // damp back to normal
  131. flock.boids[i].speed = (flock.boids[i].speed-NormalSpeed)*0.99f + NormalSpeed;
  132. if (flock.boids[i].speed < NormalSpeed/2) {
  133. flock.boids[i].speed = NormalSpeed/2;
  134. }
  135. if (flock.boids[i].speed > NormalSpeed*5) {
  136. flock.boids[i].speed = NormalSpeed*5;
  137. }
  138. // now figure out yaw changes
  139. offset = delta;
  140. offset.y = 0.0f;
  141. delta = flock.boids[i].dir;
  142. offset = Normalize(offset);
  143. float dot = DotProduct(offset, delta);
  144. // speed up slightly if not turning much
  145. if (dot > 0.7f) {
  146. dot -= 0.7f;
  147. flock.boids[i].speed += dot * 0.005f;
  148. }
  149. offset = CrossProduct(offset, delta);
  150. dot = (1.0f-dot)/2.0f * 0.07f;
  151. if (offset.y > 0.05f) {
  152. flock.boids[i].dyaw = (flock.boids[i].dyaw*19.0f + dot) * 0.05f;
  153. } else if (offset.y < -0.05f) {
  154. flock.boids[i].dyaw = (flock.boids[i].dyaw*19.0f - dot) * 0.05f;
  155. } else {
  156. flock.boids[i].dyaw *= 0.98f; // damp it
  157. }
  158. flock.boids[i].yaw += flock.boids[i].dyaw;
  159. flock.boids[i].roll = -flock.boids[i].dyaw * 20.0f;
  160. }
  161. } // end of UpdateFlock()
  162. /*
  163. **-----------------------------------------------------------------------------
  164. ** End of File
  165. **-----------------------------------------------------------------------------
  166. */