Advertisement
Guest User

.cpp

a guest
Jul 23rd, 2017
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.61 KB | None | 0 0
  1. #include "SceneCollision.h"
  2. #include "GL\glew.h"
  3. #include "Application.h"
  4. #include <sstream>
  5.  
  6. SceneCollision::SceneCollision()
  7. {
  8. }
  9.  
  10. SceneCollision::~SceneCollision()
  11. {
  12. }
  13.  
  14. void SceneCollision::Init()
  15. {
  16. SceneBase::Init();
  17. m_worldHeight = 100.f;
  18. m_worldWidth = m_worldHeight * (float)Application::GetWindowWidth() / Application::GetWindowHeight();
  19. //Physics code here
  20. m_speed = 1.f;
  21.  
  22. Math::InitRNG();
  23.  
  24. //Exercise 1: initialize m_objectCount
  25.  
  26. m_ghost = new GameObject(GameObject::GO_BALL);
  27. m_objectCount = 0;
  28. m1 = 0; m2 = 0;
  29. u1 = 0; u2 = 0;
  30. v1 = 0; v2 = 0;
  31. initialKE = 0.0f;
  32. finalKE = 0.0f;
  33. b_timerStarted = false;
  34. Vector3 centre(60, 50, 0);
  35. for (int i = 0; i < 8; i++)
  36. {
  37. GameObject *go = FetchGO();
  38. go->type = GameObject::GO_WALL;
  39. go->dir.Set(cos(Math::DegreeToRadian(i*45)), sin(Math::DegreeToRadian(i * 45)),0);
  40. go->pos = centre + go->dir * 40;
  41. go->scale.Set(4, 40, 1);
  42. go->color[0].x = 0;
  43. go->color[0].y = 1;
  44. go->color[0].z = 0;
  45.  
  46. go->color[1].x = 0;
  47. go->color[1].y = 1;
  48. go->color[1].z = 0;
  49.  
  50. go->color[2].x = 1;
  51. go->color[2].y = 0;
  52. go->color[2].z = 0;
  53. }
  54. GameObject *go = FetchGO();
  55. go->type = GameObject::GO_WALL;
  56. go->dir.Set(0, 1, 0);
  57. go->pos = centre;
  58. go->scale.Set(4, 40, 1);
  59. go->color[0].x = 0;
  60. go->color[0].y = 1;
  61. go->color[0].z = 0;
  62.  
  63. go->color[1].x = 0;
  64. go->color[1].y = 1;
  65. go->color[1].z = 0;
  66.  
  67. go->color[2].x = 1;
  68. go->color[2].y = 0;
  69. go->color[2].z = 0;
  70. GameObject *go2 = FetchGO();
  71. go2->type = GameObject::GO_PILLAR;
  72. go2->pos = centre +Vector3(20,0,0);
  73. go2->scale.Set(4, 4, 1);
  74. GameObject *go3 = FetchGO();
  75. go3->type = GameObject::GO_PILLAR;
  76. go3->pos = centre + Vector3(-20, 0, 0);
  77. go3->scale.Set(4, 4, 1);
  78. }
  79.  
  80. GameObject* SceneCollision::FetchGO()
  81. {
  82. //Exercise 2a: implement FetchGO()
  83. for (std::vector<GameObject *>::iterator it = m_goList.begin(); it != m_goList.end(); ++it)
  84. {
  85. GameObject *go = (GameObject *)* it;
  86. if (!go->active)
  87. {
  88. go->active = true;
  89. ++m_objectCount;
  90. return go;
  91. }
  92. }
  93.  
  94. for (int i = 0; i < 10; ++i)
  95. {
  96. GameObject * go = new GameObject(GameObject::GO_ASTEROID);
  97. m_goList.push_back(go);
  98. }
  99. ++m_objectCount;
  100. GameObject *go = m_goList[m_goList.size() - 1];
  101. go->active = true;
  102. return go;
  103. //Exercise 2b: increase object count every time an object is set to active
  104. // return NULL;
  105. }
  106.  
  107. void SceneCollision::Update(double dt)
  108. {
  109. m_worldHeight = 100.f;
  110. m_worldWidth = m_worldHeight * (float)Application::GetWindowWidth() / Application::GetWindowHeight();
  111. SceneBase::Update(dt);
  112.  
  113. if(Application::IsKeyPressed('9'))
  114. {
  115. m_speed = Math::Max(0.f, m_speed - 0.1f);
  116. }
  117. if(Application::IsKeyPressed('0'))
  118. {
  119. m_speed += 0.1f;
  120. }
  121. static bool SPButtonState = false;
  122. if (!SPButtonState &&Application::IsKeyPressed(VK_SPACE))
  123. {
  124.  
  125. SPButtonState = true;
  126. GameObject *go = FetchGO();
  127. go->type = GameObject::GO_BALL;
  128. go->pos.Set(m_worldWidth*0.9f, 10);
  129. go->vel.Set(0, 10, 0);
  130. go->scale.Set(5, 5, 1);
  131. go->mass = 5*5*1;
  132. go->color[0].x = 0;
  133. go->color[0].y = 1;
  134. go->color[0].z = 0;
  135.  
  136. go->color[1].x = 0;
  137. go->color[1].y = 1;
  138. go->color[1].z = 0;
  139.  
  140. go->color[2].x = 1;
  141. go->color[2].y = 0;
  142. go->color[2].z = 0;
  143. }
  144. else if (SPButtonState && !Application::IsKeyPressed(VK_SPACE))
  145. {
  146. SPButtonState = false;
  147. }
  148. //Mouse Section
  149. static bool bLButtonState = false;
  150. if(!bLButtonState && Application::IsMousePressed(0))
  151. {
  152. bLButtonState = true;
  153. std::cout << "LBUTTON DOWN" << std::endl;
  154. double x, y;
  155. Application::GetCursorPos(&x, &y);
  156. int w = Application::GetWindowWidth();
  157. int h = Application::GetWindowHeight();
  158. if (!m_ghost->active)
  159. {
  160. m_ghost->pos.Set((float)(x / w * m_worldWidth), float((h - y) / h * m_worldHeight), 0);
  161. m_ghost->active = true;
  162. }
  163.  
  164. }
  165. else if(bLButtonState && !Application::IsMousePressed(0))
  166. {
  167. bLButtonState = false;
  168. std::cout << "LBUTTON UP" << std::endl;
  169. double x, y;
  170. Application::GetCursorPos(&x, &y);
  171. int w = Application::GetWindowWidth();
  172. int h = Application::GetWindowHeight();
  173. //Exercise 6: spawn small GO_BALL
  174. GameObject *go = FetchGO();
  175. go->type = GameObject::GO_BALL;
  176. go->pos = m_ghost->pos;
  177. go->vel = m_ghost->pos - Vector3((float)(x / w * m_worldWidth), float((h - y) / h * m_worldHeight), 0);
  178. float scale = go->vel.Length()/10;
  179. scale=Math::Clamp(scale,2.f,10.f);
  180. go->scale.Set(scale, scale, scale);
  181. go->mass = 1 ;
  182.  
  183. go->color[0].x = ((double)rand() / (RAND_MAX));
  184. go->color[0].y = ((double)rand() / (RAND_MAX));
  185. go->color[0].z = ((double)rand() / (RAND_MAX));
  186.  
  187. go->color[1].x = ((double)rand() / (RAND_MAX));
  188. go->color[1].y = ((double)rand() / (RAND_MAX));
  189. go->color[1].z = ((double)rand() / (RAND_MAX));
  190.  
  191. go->color[2].x = ((double)rand() / (RAND_MAX));
  192. go->color[2].y = ((double)rand() / (RAND_MAX));
  193. go->color[2].z = ((double)rand() / (RAND_MAX));
  194.  
  195. m_ghost->active = false;
  196.  
  197. }
  198. static bool bRButtonState = false;
  199. if(!bRButtonState && Application::IsMousePressed(1))
  200. {
  201. bRButtonState = true;
  202. double x, y;
  203. Application::GetCursorPos(&x, &y);
  204. int w = Application::GetWindowWidth();
  205. int h = Application::GetWindowHeight();
  206. if (!m_ghost->active)
  207. {
  208. m_ghost->pos.Set((float)(x / w * m_worldWidth), float((h - y) / h * m_worldHeight),0);
  209. m_ghost->active = true;
  210. }
  211. std::cout << "RBUTTON DOWN" << std::endl;
  212. }
  213. else if(bRButtonState && !Application::IsMousePressed(1))
  214. {
  215. bRButtonState = false;
  216. std::cout << "RBUTTON UP" << std::endl;
  217. double x, y;
  218. Application::GetCursorPos(&x, &y);
  219. int w = Application::GetWindowWidth();
  220. int h = Application::GetWindowHeight();
  221.  
  222. //Exercise 10: spawn large GO_BALL
  223. GameObject *go = FetchGO();
  224. go->type = GameObject::GO_BALL;
  225. go->pos = m_ghost->pos;
  226. go->vel = m_ghost->pos - Vector3((float)(x / w * m_worldWidth), float((h - y) / h * m_worldHeight), 0);
  227. go->scale.Set(1.5, 1.5, 1.5);
  228. go->mass = 1.5 * 1.5 * 1.5;
  229.  
  230. go->color[0].x = ((double)rand() / (RAND_MAX));
  231. go->color[0].y = ((double)rand() / (RAND_MAX));
  232. go->color[0].z = ((double)rand() / (RAND_MAX));
  233.  
  234. go->color[1].x = ((double)rand() / (RAND_MAX));
  235. go->color[1].y = ((double)rand() / (RAND_MAX));
  236. go->color[1].z = ((double)rand() / (RAND_MAX));
  237.  
  238. go->color[2].x = ((double)rand() / (RAND_MAX));
  239. go->color[2].y = ((double)rand() / (RAND_MAX));
  240. go->color[2].z = ((double)rand() / (RAND_MAX));
  241. m_ghost->active = false;
  242. m_timeEstimated1 = 1000;
  243. m_timeTaken1 = 0;
  244. b_timerStarted = true;
  245. }
  246. for (std::vector<GameObject *>::iterator it = m_goList.begin(); it != m_goList.end(); ++it)
  247. {
  248. GameObject *go = (GameObject *)*it;
  249. if (go->active)
  250. {
  251. if (go->type == GameObject::GO_BALL)
  252. {
  253. //Rebounding at all 4 edges of the screen
  254. Vector3 ds = go->vel * (float)dt;
  255. go->pos += ds;
  256.  
  257. if (go->pos.x > m_worldWidth - go->scale.x && go->vel.x > 0)
  258. {
  259. go->vel.x = -go->vel.x;
  260. }
  261. else if (go->pos.x < go->scale.x && go->vel.x < 0)
  262. {
  263. go->vel.x = -go->vel.x;
  264. }
  265. if (go->pos.y > m_worldHeight - go->scale.y && go->vel.y > 0)
  266. {
  267. go->vel.y = -go->vel.y;
  268. }
  269. else if (go->pos.y < go->scale.x && go->vel.y < 0)
  270. {
  271. go->vel.y = -go->vel.y;
  272. }
  273.  
  274. if (go->pos.x > m_worldWidth || go->pos.x < 0 || go->pos.y > m_worldHeight || go->pos.y < 0)
  275. {
  276. go->active = false;
  277. m_objectCount -= 1;
  278. continue;
  279. }
  280.  
  281. }
  282. for (std::vector<GameObject *>::iterator it2 = it + 1; it2 != m_goList.end(); ++it2)
  283. {
  284. GameObject *go2 = (GameObject *)*it2;
  285. if (!go2->active)
  286. continue;
  287. if (go->type == GameObject::GO_WALL&&go2->type == GameObject::GO_WALL)
  288. continue;
  289. GameObject *goA, *goB;
  290. if (go->type == GameObject::GO_BALL)
  291. {
  292. goA = go;
  293. goB = go2;
  294.  
  295. }
  296. else
  297. {
  298. goA = go2;
  299. goB = go;
  300. }
  301. if (CheckCollision(goA, goB, dt))
  302. {
  303. //Exercise 10: handle collision using momentum swap instead
  304. u1 = goA->vel;
  305. u2 = goB->vel;
  306. m1 = goA->mass;
  307. m2 = goB->mass;
  308. initialKE = 0.5 * m1 * u1.Dot(u1) + 0.5f * m2 * u2.Dot(u2);
  309. CollisionResponse(goA, goB);
  310. v1 = goA->vel;
  311. v2 = goB->vel;
  312. finalKE = 0.5 * m1 * v1.Dot(v1) + 0.5f * m2 * v2.Dot(v2);
  313.  
  314.  
  315.  
  316. }
  317. }
  318.  
  319. }
  320. }
  321. }
  322. bool SceneCollision::CheckCollision(GameObject *go1, GameObject *go2, float dt)
  323. {
  324. switch (go2->type)
  325. {
  326. case GameObject::GO_BALL:
  327. {
  328. //Exercise 1: move collision code to CheckCollision()
  329. float distSquared = (go1->pos - go2->pos).LengthSquared();
  330. float combinedRadius = go1->scale.x + go2->scale.x;
  331.  
  332. //Practical 4, Exercise 13: improve collision detection algorithm
  333. return (distSquared <= combinedRadius * combinedRadius);
  334. }
  335. case GameObject::GO_WALL:
  336. {
  337. Vector3 w0 = go2->pos;
  338. Vector3 b1 = go1->pos;
  339. Vector3 N = go2->dir;
  340. Vector3 NP = N.Cross(Vector3(0, 0, 1));
  341. float l = go2->scale.y;
  342. float r = go1->scale.x;
  343. float h = go2->scale.x;
  344.  
  345. return ((abs((w0 - b1).Dot(N)) < r + h / 2)&& (abs((w0 - b1).Dot(NP)) < r + l / 2));
  346. }
  347. }
  348. }
  349.  
  350. float SceneCollision::CheckCollision2(GameObject * go1, GameObject * go2)
  351. {
  352. Vector3 rel = go1->vel - go2->vel;
  353. Vector3 dir = go1->pos - go2->pos;
  354. float r = go1->scale.x + go2->scale.x;
  355. if (rel.Dot(dir) > 0)
  356. return -1.f;
  357. float a = rel.Dot(rel);
  358. float b = 2 * rel.Dot(dir);
  359. float c = dir.Dot(dir) - r*r;
  360. float d = b*b - 4 * a*c;
  361. if (d < 0)
  362. return -1;
  363. float t = (-b - sqrtf(d)) / 2 * a;
  364. if (t<0)
  365. t= (-b + sqrtf(d)) / 2 * a;
  366. return t;
  367. }
  368.  
  369. void SceneCollision::CollisionResponse(GameObject * go1, GameObject * go2)
  370. {
  371. switch (go2->type)
  372. {
  373. case GameObject::GO_BALL:
  374. {
  375. Vector3 N = (go2->pos - go1->pos).Normalize();
  376. Vector3 u1N = u1.Dot(N)*N;
  377. Vector3 u2N = u2.Dot(N)*N;
  378. go1->vel = u1 + 2 * m2 / (m1 + m2)*(u2N - u1N);
  379. go2->vel = u2 + 2 * m1 / (m1 + m2)*(u1N - u2N);
  380. }
  381. case GameObject::GO_WALL:
  382. {
  383. go1->vel = go1->vel - (2 * go1->vel.Dot(go2->dir))*go2->dir;
  384.  
  385. }
  386. }
  387. }
  388.  
  389. void SceneCollision::RenderGO(GameObject *go)
  390. {
  391. switch(go->type)
  392. {
  393. case GameObject::GO_BALL:
  394. //Exercise 4: render a sphere using scale and pos
  395. modelStack.PushMatrix();
  396. modelStack.Translate(go->pos.x, go->pos.y, go->pos.z);
  397. modelStack.Scale(go->scale.x, go->scale.y,go->scale.z);
  398. //Exercise 11: think of a way to give balls different colors
  399. RenderMesh(meshList[GEO_BALL], true, go->color);
  400. modelStack.PopMatrix();
  401. break;
  402.  
  403. case GameObject::GO_WALL:
  404. modelStack.PushMatrix();
  405. modelStack.Translate(go->pos.x, go->pos.y, go->pos.z);
  406. modelStack.Rotate(Math::RadianToDegree(atan2(go->dir.y,go->dir.x)),0,0,1);
  407. modelStack.Scale(go->scale.x, go->scale.y, go->scale.z);
  408. //Exercise 11: think of a way to give balls different colors
  409. RenderMesh(meshList[GEO_CUBE], true, go->color);
  410. modelStack.PopMatrix();
  411. break;
  412. case GameObject::GO_PILLAR:
  413. //Exercise 4: render a sphere using scale and pos
  414. modelStack.PushMatrix();
  415. modelStack.Translate(go->pos.x, go->pos.y, go->pos.z);
  416. modelStack.Scale(go->scale.x, go->scale.y, go->scale.z);
  417. //Exercise 11: think of a way to give balls different colors
  418. RenderMesh(meshList[GEO_BALL], true, go->color);
  419. modelStack.PopMatrix();
  420. break;
  421. }
  422. }
  423.  
  424. void SceneCollision::Render()
  425. {
  426. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  427.  
  428. //Calculating aspect ratio
  429. m_worldHeight = 100.f;
  430. m_worldWidth = m_worldHeight * (float)Application::GetWindowWidth() / Application::GetWindowHeight();
  431.  
  432. // Projection matrix : Orthographic Projection
  433. Mtx44 projection;
  434. projection.SetToOrtho(0, m_worldWidth, 0, m_worldHeight, -10, 10);
  435. projectionStack.LoadMatrix(projection);
  436.  
  437. // Camera matrix
  438. viewStack.LoadIdentity();
  439. viewStack.LookAt(
  440. camera.position.x, camera.position.y, camera.position.z,
  441. camera.target.x, camera.target.y, camera.target.z,
  442. camera.up.x, camera.up.y, camera.up.z
  443. );
  444. // Model matrix : an identity matrix (model will be at the origin)
  445. modelStack.LoadIdentity();
  446.  
  447. RenderMesh(meshList[GEO_AXES], false);
  448.  
  449. for(std::vector<GameObject *>::iterator it = m_goList.begin(); it != m_goList.end(); ++it)
  450. {
  451. GameObject *go = (GameObject *)*it;
  452. if(go->active)
  453. {
  454. RenderGO(go);
  455. }
  456. }
  457.  
  458. //On screen text
  459.  
  460. //Exercise 5: Render m_objectCount
  461.  
  462. //Exercise 8c: Render initial and final momentum
  463.  
  464. std::ostringstream ss;
  465. ss.precision(3);
  466. ss << "Speed: " << m_speed;
  467. RenderTextOnScreen(meshList[GEO_TEXT], ss.str(), Color(0, 1, 0), 3, 0, 6);
  468. ss.str("");
  469. ss << "Game Objs: " << m_objectCount;
  470. RenderTextOnScreen(meshList[GEO_TEXT], ss.str(), Color(0, 1, 0), 3, 0, 9);
  471. ss.str("");
  472. ss << "Final mom:" << Vector3 (m1 * v1 + m2 * v2);
  473. RenderTextOnScreen(meshList[GEO_TEXT], ss.str(), Color(0, 1, 0), 3, 0, 12);
  474. ss.str("");
  475. ss << "Initial mom:" << Vector3(m1 * u1 + m2 * u2);
  476. RenderTextOnScreen(meshList[GEO_TEXT], ss.str(), Color(0, 1, 0), 3, 0, 15);
  477. ss.str("");
  478. ss.precision(5);
  479. ss << "Initial KE: " << initialKE;
  480. RenderTextOnScreen(meshList[GEO_TEXT], ss.str(), Color(0, 1, 0), 3, 0, 21);
  481. ss.str("");
  482. ss.precision(5);
  483. ss << " Final KE: " << finalKE;
  484. RenderTextOnScreen(meshList[GEO_TEXT], ss.str(), Color(0, 1, 0), 3, 0, 18);
  485.  
  486. ss.str("");
  487. ss.precision(5);
  488. ss << "FPS: " << fps;
  489. RenderTextOnScreen(meshList[GEO_TEXT], ss.str(), Color(0, 1, 0), 3, 0, 3);
  490. RenderTextOnScreen(meshList[GEO_TEXT], "Collision", Color(0, 1, 0), 3, 0, 0);
  491. }
  492.  
  493. void SceneCollision::Exit()
  494. {
  495. SceneBase::Exit();
  496. //Cleanup GameObjects
  497. while(m_goList.size() > 0)
  498. {
  499. GameObject *go = m_goList.back();
  500. delete go;
  501. m_goList.pop_back();
  502. }
  503. if(m_ghost)
  504. {
  505. delete m_ghost;
  506. m_ghost = NULL;
  507. }
  508. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement