DynamicTreeTest.h
上传用户:gb3593
上传日期:2022-01-07
资源大小:3028k
文件大小:7k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /*
  2. * Copyright (c) 2009 Erin Catto http://www.gphysics.com
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty.  In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. * Permission is granted to anyone to use this software for any purpose,
  8. * including commercial applications, and to alter it and redistribute it
  9. * freely, subject to the following restrictions:
  10. * 1. The origin of this software must not be misrepresented; you must not
  11. * claim that you wrote the original software. If you use this software
  12. * in a product, an acknowledgment in the product documentation would be
  13. * appreciated but is not required.
  14. * 2. Altered source versions must be plainly marked as such, and must not be
  15. * misrepresented as being the original software.
  16. * 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #ifndef DYNAMIC_TREE_TEST_H
  19. #define DYNAMIC_TREE_TEST_H
  20. class DynamicTreeTest : public Test
  21. {
  22. public:
  23. enum
  24. {
  25. e_actorCount = 128,
  26. };
  27. DynamicTreeTest()
  28. {
  29. m_worldExtent = 15.0f;
  30. m_proxyExtent = 0.5f;
  31. srand(888);
  32. for (int32 i = 0; i < e_actorCount; ++i)
  33. {
  34. Actor* actor = m_actors + i;
  35. GetRandomAABB(&actor->aabb);
  36. actor->proxyId = m_tree.CreateProxy(actor->aabb, actor);
  37. }
  38. m_stepCount = 0;
  39. float32 h = m_worldExtent;
  40. m_queryAABB.lowerBound.Set(-3.0f, -4.0f + h);
  41. m_queryAABB.upperBound.Set(5.0f, 6.0f + h);
  42. m_rayCastInput.p1.Set(-5.0, 5.0f + h);
  43. m_rayCastInput.p2.Set(7.0f, -4.0f + h);
  44. //m_rayCastInput.p1.Set(0.0f, 2.0f + h);
  45. //m_rayCastInput.p2.Set(0.0f, -2.0f + h);
  46. m_rayCastInput.maxFraction = 1.0f;
  47. m_automated = false;
  48. }
  49. static Test* Create()
  50. {
  51. return new DynamicTreeTest;
  52. }
  53. void Step(Settings* settings)
  54. {
  55. B2_NOT_USED(settings);
  56. m_rayActor = NULL;
  57. for (int32 i = 0; i < e_actorCount; ++i)
  58. {
  59. m_actors[i].fraction = 1.0f;
  60. m_actors[i].overlap = false;
  61. }
  62. if (m_automated == true)
  63. {
  64. int32 actionCount = b2Max(1, e_actorCount >> 2);
  65. for (int32 i = 0; i < actionCount; ++i)
  66. {
  67. Action();
  68. }
  69. }
  70. Query();
  71. RayCast();
  72. for (int32 i = 0; i < e_actorCount; ++i)
  73. {
  74. Actor* actor = m_actors + i;
  75. if (actor->proxyId == b2_nullNode)
  76. continue;
  77. b2Color c(0.9f, 0.9f, 0.9f);
  78. if (actor == m_rayActor && actor->overlap)
  79. {
  80. c.Set(0.9f, 0.6f, 0.6f);
  81. }
  82. else if (actor == m_rayActor)
  83. {
  84. c.Set(0.6f, 0.9f, 0.6f);
  85. }
  86. else if (actor->overlap)
  87. {
  88. c.Set(0.6f, 0.6f, 0.9f);
  89. }
  90. m_debugDraw.DrawAABB(&actor->aabb, c);
  91. }
  92. b2Color c(0.7f, 0.7f, 0.7f);
  93. m_debugDraw.DrawAABB(&m_queryAABB, c);
  94. m_debugDraw.DrawSegment(m_rayCastInput.p1, m_rayCastInput.p2, c);
  95. b2Color c1(0.2f, 0.9f, 0.2f);
  96. b2Color c2(0.9f, 0.2f, 0.2f);
  97. m_debugDraw.DrawPoint(m_rayCastInput.p1, 6.0f, c1);
  98. m_debugDraw.DrawPoint(m_rayCastInput.p2, 6.0f, c2);
  99. if (m_rayActor)
  100. {
  101. b2Color cr(0.2f, 0.2f, 0.9f);
  102. b2Vec2 p = m_rayCastInput.p1 + m_rayActor->fraction * (m_rayCastInput.p2 - m_rayCastInput.p1);
  103. m_debugDraw.DrawPoint(p, 6.0f, cr);
  104. }
  105. ++m_stepCount;
  106. }
  107. void Keyboard(unsigned char key)
  108. {
  109. switch (key)
  110. {
  111. case 'a':
  112. m_automated = !m_automated;
  113. break;
  114. case 'c':
  115. CreateProxy();
  116. break;
  117. case 'd':
  118. DestroyProxy();
  119. break;
  120. case 'm':
  121. MoveProxy();
  122. break;
  123. }
  124. }
  125. bool QueryCallback(int32 proxyId)
  126. {
  127. Actor* actor = (Actor*)m_tree.GetUserData(proxyId);
  128. actor->overlap = b2TestOverlap(m_queryAABB, actor->aabb);
  129. return true;
  130. }
  131. float32 RayCastCallback(const b2RayCastInput& input, int32 proxyId)
  132. {
  133. Actor* actor = (Actor*)m_tree.GetUserData(proxyId);
  134. b2RayCastOutput output;
  135. bool hit = actor->aabb.RayCast(&output, input);
  136. if (hit)
  137. {
  138. m_rayCastOutput = output;
  139. m_rayActor = actor;
  140. m_rayActor->fraction = output.fraction;
  141. return output.fraction;
  142. }
  143. return input.maxFraction;
  144. }
  145. private:
  146. struct Actor
  147. {
  148. b2AABB aabb;
  149. float32 fraction;
  150. bool overlap;
  151. int32 proxyId;
  152. };
  153. void GetRandomAABB(b2AABB* aabb)
  154. {
  155. b2Vec2 w; w.Set(2.0f * m_proxyExtent, 2.0f * m_proxyExtent);
  156. //aabb->lowerBound.x = -m_proxyExtent;
  157. //aabb->lowerBound.y = -m_proxyExtent + m_worldExtent;
  158. aabb->lowerBound.x = RandomFloat(-m_worldExtent, m_worldExtent);
  159. aabb->lowerBound.y = RandomFloat(0.0f, 2.0f * m_worldExtent);
  160. aabb->upperBound = aabb->lowerBound + w;
  161. }
  162. void MoveAABB(b2AABB* aabb)
  163. {
  164. b2Vec2 d;
  165. d.x = RandomFloat(-0.5f, 0.5f);
  166. d.y = RandomFloat(-0.5f, 0.5f);
  167. //d.x = 2.0f;
  168. //d.y = 0.0f;
  169. aabb->lowerBound += d;
  170. aabb->upperBound += d;
  171. b2Vec2 c0 = 0.5f * (aabb->lowerBound + aabb->upperBound);
  172. b2Vec2 min; min.Set(-m_worldExtent, 0.0f);
  173. b2Vec2 max; max.Set(m_worldExtent, 2.0f * m_worldExtent);
  174. b2Vec2 c = b2Clamp(c0, min, max);
  175. aabb->lowerBound += c - c0;
  176. aabb->upperBound += c - c0;
  177. }
  178. void CreateProxy()
  179. {
  180. for (int32 i = 0; i < e_actorCount; ++i)
  181. {
  182. int32 j = rand() % e_actorCount;
  183. Actor* actor = m_actors + j;
  184. if (actor->proxyId == b2_nullNode)
  185. {
  186. GetRandomAABB(&actor->aabb);
  187. actor->proxyId = m_tree.CreateProxy(actor->aabb, actor);
  188. return;
  189. }
  190. }
  191. }
  192. void DestroyProxy()
  193. {
  194. for (int32 i = 0; i < e_actorCount; ++i)
  195. {
  196. int32 j = rand() % e_actorCount;
  197. Actor* actor = m_actors + j;
  198. if (actor->proxyId != b2_nullNode)
  199. {
  200. m_tree.DestroyProxy(actor->proxyId);
  201. actor->proxyId = b2_nullNode;
  202. return;
  203. }
  204. }
  205. }
  206. void MoveProxy()
  207. {
  208. for (int32 i = 0; i < e_actorCount; ++i)
  209. {
  210. int32 j = rand() % e_actorCount;
  211. Actor* actor = m_actors + j;
  212. if (actor->proxyId == b2_nullNode)
  213. {
  214. continue;
  215. }
  216. b2AABB aabb0 = actor->aabb;
  217. MoveAABB(&actor->aabb);
  218. b2Vec2 displacement = actor->aabb.GetCenter() - aabb0.GetCenter();
  219. m_tree.MoveProxy(actor->proxyId, actor->aabb, displacement);
  220. return;
  221. }
  222. }
  223. void Action()
  224. {
  225. int32 choice = rand() % 20;
  226. switch (choice)
  227. {
  228. case 0:
  229. CreateProxy();
  230. break;
  231. case 1:
  232. DestroyProxy();
  233. break;
  234. default:
  235. MoveProxy();
  236. }
  237. }
  238. void Query()
  239. {
  240. m_tree.Query(this, m_queryAABB);
  241. for (int32 i = 0; i < e_actorCount; ++i)
  242. {
  243. if (m_actors[i].proxyId == b2_nullNode)
  244. {
  245. continue;
  246. }
  247. bool overlap = b2TestOverlap(m_queryAABB, m_actors[i].aabb);
  248. B2_NOT_USED(overlap);
  249. b2Assert(overlap == m_actors[i].overlap);
  250. }
  251. }
  252. void RayCast()
  253. {
  254. m_rayActor = NULL;
  255. b2RayCastInput input = m_rayCastInput;
  256. // Ray cast against the dynamic tree.
  257. m_tree.RayCast(this, input);
  258. // Brute force ray cast.
  259. Actor* bruteActor = NULL;
  260. b2RayCastOutput bruteOutput;
  261. for (int32 i = 0; i < e_actorCount; ++i)
  262. {
  263. if (m_actors[i].proxyId == b2_nullNode)
  264. {
  265. continue;
  266. }
  267. b2RayCastOutput output;
  268. bool hit = m_actors[i].aabb.RayCast(&output, input);
  269. if (hit)
  270. {
  271. bruteActor = m_actors + i;
  272. bruteOutput = output;
  273. input.maxFraction = output.fraction;
  274. }
  275. }
  276. if (bruteActor != NULL)
  277. {
  278. b2Assert(bruteOutput.fraction == m_rayCastOutput.fraction);
  279. }
  280. }
  281. float32 m_worldExtent;
  282. float32 m_proxyExtent;
  283. b2DynamicTree m_tree;
  284. b2AABB m_queryAABB;
  285. b2RayCastInput m_rayCastInput;
  286. b2RayCastOutput m_rayCastOutput;
  287. Actor* m_rayActor;
  288. Actor m_actors[e_actorCount];
  289. int32 m_stepCount;
  290. bool m_automated;
  291. };
  292. #endif