Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "SceneCollision.h"
- #include "GL\glew.h"
- #include "Application.h"
- #include <sstream>
- SceneCollision::SceneCollision()
- {
- }
- SceneCollision::~SceneCollision()
- {
- }
- void SceneCollision::Init()
- {
- SceneBase::Init();
- m_worldHeight = 100.f;
- m_worldWidth = m_worldHeight * (float)Application::GetWindowWidth() / Application::GetWindowHeight();
- //Physics code here
- m_speed = 1.f;
- Math::InitRNG();
- //Exercise 1: initialize m_objectCount
- m_ghost = new GameObject(GameObject::GO_BALL);
- m_objectCount = 0;
- m1 = 0; m2 = 0;
- u1 = 0; u2 = 0;
- v1 = 0; v2 = 0;
- initialKE = 0.0f;
- finalKE = 0.0f;
- b_timerStarted = false;
- Vector3 centre(60, 50, 0);
- for (int i = 0; i < 8; i++)
- {
- GameObject *go = FetchGO();
- go->type = GameObject::GO_WALL;
- go->dir.Set(cos(Math::DegreeToRadian(i*45)), sin(Math::DegreeToRadian(i * 45)),0);
- go->pos = centre + go->dir * 40;
- go->scale.Set(4, 40, 1);
- go->color[0].x = 0;
- go->color[0].y = 1;
- go->color[0].z = 0;
- go->color[1].x = 0;
- go->color[1].y = 1;
- go->color[1].z = 0;
- go->color[2].x = 1;
- go->color[2].y = 0;
- go->color[2].z = 0;
- }
- GameObject *go = FetchGO();
- go->type = GameObject::GO_WALL;
- go->dir.Set(0, 1, 0);
- go->pos = centre;
- go->scale.Set(4, 40, 1);
- go->color[0].x = 0;
- go->color[0].y = 1;
- go->color[0].z = 0;
- go->color[1].x = 0;
- go->color[1].y = 1;
- go->color[1].z = 0;
- go->color[2].x = 1;
- go->color[2].y = 0;
- go->color[2].z = 0;
- GameObject *go2 = FetchGO();
- go2->type = GameObject::GO_PILLAR;
- go2->pos = centre +Vector3(20,0,0);
- go2->scale.Set(4, 4, 1);
- GameObject *go3 = FetchGO();
- go3->type = GameObject::GO_PILLAR;
- go3->pos = centre + Vector3(-20, 0, 0);
- go3->scale.Set(4, 4, 1);
- }
- GameObject* SceneCollision::FetchGO()
- {
- //Exercise 2a: implement FetchGO()
- for (std::vector<GameObject *>::iterator it = m_goList.begin(); it != m_goList.end(); ++it)
- {
- GameObject *go = (GameObject *)* it;
- if (!go->active)
- {
- go->active = true;
- ++m_objectCount;
- return go;
- }
- }
- for (int i = 0; i < 10; ++i)
- {
- GameObject * go = new GameObject(GameObject::GO_ASTEROID);
- m_goList.push_back(go);
- }
- ++m_objectCount;
- GameObject *go = m_goList[m_goList.size() - 1];
- go->active = true;
- return go;
- //Exercise 2b: increase object count every time an object is set to active
- // return NULL;
- }
- void SceneCollision::Update(double dt)
- {
- m_worldHeight = 100.f;
- m_worldWidth = m_worldHeight * (float)Application::GetWindowWidth() / Application::GetWindowHeight();
- SceneBase::Update(dt);
- if(Application::IsKeyPressed('9'))
- {
- m_speed = Math::Max(0.f, m_speed - 0.1f);
- }
- if(Application::IsKeyPressed('0'))
- {
- m_speed += 0.1f;
- }
- static bool SPButtonState = false;
- if (!SPButtonState &&Application::IsKeyPressed(VK_SPACE))
- {
- SPButtonState = true;
- GameObject *go = FetchGO();
- go->type = GameObject::GO_BALL;
- go->pos.Set(m_worldWidth*0.9f, 10);
- go->vel.Set(0, 10, 0);
- go->scale.Set(5, 5, 1);
- go->mass = 5*5*1;
- go->color[0].x = 0;
- go->color[0].y = 1;
- go->color[0].z = 0;
- go->color[1].x = 0;
- go->color[1].y = 1;
- go->color[1].z = 0;
- go->color[2].x = 1;
- go->color[2].y = 0;
- go->color[2].z = 0;
- }
- else if (SPButtonState && !Application::IsKeyPressed(VK_SPACE))
- {
- SPButtonState = false;
- }
- //Mouse Section
- static bool bLButtonState = false;
- if(!bLButtonState && Application::IsMousePressed(0))
- {
- bLButtonState = true;
- std::cout << "LBUTTON DOWN" << std::endl;
- double x, y;
- Application::GetCursorPos(&x, &y);
- int w = Application::GetWindowWidth();
- int h = Application::GetWindowHeight();
- if (!m_ghost->active)
- {
- m_ghost->pos.Set((float)(x / w * m_worldWidth), float((h - y) / h * m_worldHeight), 0);
- m_ghost->active = true;
- }
- }
- else if(bLButtonState && !Application::IsMousePressed(0))
- {
- bLButtonState = false;
- std::cout << "LBUTTON UP" << std::endl;
- double x, y;
- Application::GetCursorPos(&x, &y);
- int w = Application::GetWindowWidth();
- int h = Application::GetWindowHeight();
- //Exercise 6: spawn small GO_BALL
- GameObject *go = FetchGO();
- go->type = GameObject::GO_BALL;
- go->pos = m_ghost->pos;
- go->vel = m_ghost->pos - Vector3((float)(x / w * m_worldWidth), float((h - y) / h * m_worldHeight), 0);
- float scale = go->vel.Length()/10;
- scale=Math::Clamp(scale,2.f,10.f);
- go->scale.Set(scale, scale, scale);
- go->mass = 1 ;
- go->color[0].x = ((double)rand() / (RAND_MAX));
- go->color[0].y = ((double)rand() / (RAND_MAX));
- go->color[0].z = ((double)rand() / (RAND_MAX));
- go->color[1].x = ((double)rand() / (RAND_MAX));
- go->color[1].y = ((double)rand() / (RAND_MAX));
- go->color[1].z = ((double)rand() / (RAND_MAX));
- go->color[2].x = ((double)rand() / (RAND_MAX));
- go->color[2].y = ((double)rand() / (RAND_MAX));
- go->color[2].z = ((double)rand() / (RAND_MAX));
- m_ghost->active = false;
- }
- static bool bRButtonState = false;
- if(!bRButtonState && Application::IsMousePressed(1))
- {
- bRButtonState = true;
- double x, y;
- Application::GetCursorPos(&x, &y);
- int w = Application::GetWindowWidth();
- int h = Application::GetWindowHeight();
- if (!m_ghost->active)
- {
- m_ghost->pos.Set((float)(x / w * m_worldWidth), float((h - y) / h * m_worldHeight),0);
- m_ghost->active = true;
- }
- std::cout << "RBUTTON DOWN" << std::endl;
- }
- else if(bRButtonState && !Application::IsMousePressed(1))
- {
- bRButtonState = false;
- std::cout << "RBUTTON UP" << std::endl;
- double x, y;
- Application::GetCursorPos(&x, &y);
- int w = Application::GetWindowWidth();
- int h = Application::GetWindowHeight();
- //Exercise 10: spawn large GO_BALL
- GameObject *go = FetchGO();
- go->type = GameObject::GO_BALL;
- go->pos = m_ghost->pos;
- go->vel = m_ghost->pos - Vector3((float)(x / w * m_worldWidth), float((h - y) / h * m_worldHeight), 0);
- go->scale.Set(1.5, 1.5, 1.5);
- go->mass = 1.5 * 1.5 * 1.5;
- go->color[0].x = ((double)rand() / (RAND_MAX));
- go->color[0].y = ((double)rand() / (RAND_MAX));
- go->color[0].z = ((double)rand() / (RAND_MAX));
- go->color[1].x = ((double)rand() / (RAND_MAX));
- go->color[1].y = ((double)rand() / (RAND_MAX));
- go->color[1].z = ((double)rand() / (RAND_MAX));
- go->color[2].x = ((double)rand() / (RAND_MAX));
- go->color[2].y = ((double)rand() / (RAND_MAX));
- go->color[2].z = ((double)rand() / (RAND_MAX));
- m_ghost->active = false;
- m_timeEstimated1 = 1000;
- m_timeTaken1 = 0;
- b_timerStarted = true;
- }
- for (std::vector<GameObject *>::iterator it = m_goList.begin(); it != m_goList.end(); ++it)
- {
- GameObject *go = (GameObject *)*it;
- if (go->active)
- {
- if (go->type == GameObject::GO_BALL)
- {
- //Rebounding at all 4 edges of the screen
- Vector3 ds = go->vel * (float)dt;
- go->pos += ds;
- if (go->pos.x > m_worldWidth - go->scale.x && go->vel.x > 0)
- {
- go->vel.x = -go->vel.x;
- }
- else if (go->pos.x < go->scale.x && go->vel.x < 0)
- {
- go->vel.x = -go->vel.x;
- }
- if (go->pos.y > m_worldHeight - go->scale.y && go->vel.y > 0)
- {
- go->vel.y = -go->vel.y;
- }
- else if (go->pos.y < go->scale.x && go->vel.y < 0)
- {
- go->vel.y = -go->vel.y;
- }
- if (go->pos.x > m_worldWidth || go->pos.x < 0 || go->pos.y > m_worldHeight || go->pos.y < 0)
- {
- go->active = false;
- m_objectCount -= 1;
- continue;
- }
- }
- for (std::vector<GameObject *>::iterator it2 = it + 1; it2 != m_goList.end(); ++it2)
- {
- GameObject *go2 = (GameObject *)*it2;
- if (!go2->active)
- continue;
- if (go->type == GameObject::GO_WALL&&go2->type == GameObject::GO_WALL)
- continue;
- GameObject *goA, *goB;
- if (go->type == GameObject::GO_BALL)
- {
- goA = go;
- goB = go2;
- }
- else
- {
- goA = go2;
- goB = go;
- }
- if (CheckCollision(goA, goB, dt))
- {
- //Exercise 10: handle collision using momentum swap instead
- u1 = goA->vel;
- u2 = goB->vel;
- m1 = goA->mass;
- m2 = goB->mass;
- initialKE = 0.5 * m1 * u1.Dot(u1) + 0.5f * m2 * u2.Dot(u2);
- CollisionResponse(goA, goB);
- v1 = goA->vel;
- v2 = goB->vel;
- finalKE = 0.5 * m1 * v1.Dot(v1) + 0.5f * m2 * v2.Dot(v2);
- }
- }
- }
- }
- }
- bool SceneCollision::CheckCollision(GameObject *go1, GameObject *go2, float dt)
- {
- switch (go2->type)
- {
- case GameObject::GO_BALL:
- {
- //Exercise 1: move collision code to CheckCollision()
- float distSquared = (go1->pos - go2->pos).LengthSquared();
- float combinedRadius = go1->scale.x + go2->scale.x;
- //Practical 4, Exercise 13: improve collision detection algorithm
- return (distSquared <= combinedRadius * combinedRadius);
- }
- case GameObject::GO_WALL:
- {
- Vector3 w0 = go2->pos;
- Vector3 b1 = go1->pos;
- Vector3 N = go2->dir;
- Vector3 NP = N.Cross(Vector3(0, 0, 1));
- float l = go2->scale.y;
- float r = go1->scale.x;
- float h = go2->scale.x;
- return ((abs((w0 - b1).Dot(N)) < r + h / 2)&& (abs((w0 - b1).Dot(NP)) < r + l / 2));
- }
- }
- }
- float SceneCollision::CheckCollision2(GameObject * go1, GameObject * go2)
- {
- Vector3 rel = go1->vel - go2->vel;
- Vector3 dir = go1->pos - go2->pos;
- float r = go1->scale.x + go2->scale.x;
- if (rel.Dot(dir) > 0)
- return -1.f;
- float a = rel.Dot(rel);
- float b = 2 * rel.Dot(dir);
- float c = dir.Dot(dir) - r*r;
- float d = b*b - 4 * a*c;
- if (d < 0)
- return -1;
- float t = (-b - sqrtf(d)) / 2 * a;
- if (t<0)
- t= (-b + sqrtf(d)) / 2 * a;
- return t;
- }
- void SceneCollision::CollisionResponse(GameObject * go1, GameObject * go2)
- {
- switch (go2->type)
- {
- case GameObject::GO_BALL:
- {
- Vector3 N = (go2->pos - go1->pos).Normalize();
- Vector3 u1N = u1.Dot(N)*N;
- Vector3 u2N = u2.Dot(N)*N;
- go1->vel = u1 + 2 * m2 / (m1 + m2)*(u2N - u1N);
- go2->vel = u2 + 2 * m1 / (m1 + m2)*(u1N - u2N);
- }
- case GameObject::GO_WALL:
- {
- go1->vel = go1->vel - (2 * go1->vel.Dot(go2->dir))*go2->dir;
- }
- }
- }
- void SceneCollision::RenderGO(GameObject *go)
- {
- switch(go->type)
- {
- case GameObject::GO_BALL:
- //Exercise 4: render a sphere using scale and pos
- modelStack.PushMatrix();
- modelStack.Translate(go->pos.x, go->pos.y, go->pos.z);
- modelStack.Scale(go->scale.x, go->scale.y,go->scale.z);
- //Exercise 11: think of a way to give balls different colors
- RenderMesh(meshList[GEO_BALL], true, go->color);
- modelStack.PopMatrix();
- break;
- case GameObject::GO_WALL:
- modelStack.PushMatrix();
- modelStack.Translate(go->pos.x, go->pos.y, go->pos.z);
- modelStack.Rotate(Math::RadianToDegree(atan2(go->dir.y,go->dir.x)),0,0,1);
- modelStack.Scale(go->scale.x, go->scale.y, go->scale.z);
- //Exercise 11: think of a way to give balls different colors
- RenderMesh(meshList[GEO_CUBE], true, go->color);
- modelStack.PopMatrix();
- break;
- case GameObject::GO_PILLAR:
- //Exercise 4: render a sphere using scale and pos
- modelStack.PushMatrix();
- modelStack.Translate(go->pos.x, go->pos.y, go->pos.z);
- modelStack.Scale(go->scale.x, go->scale.y, go->scale.z);
- //Exercise 11: think of a way to give balls different colors
- RenderMesh(meshList[GEO_BALL], true, go->color);
- modelStack.PopMatrix();
- break;
- }
- }
- void SceneCollision::Render()
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- //Calculating aspect ratio
- m_worldHeight = 100.f;
- m_worldWidth = m_worldHeight * (float)Application::GetWindowWidth() / Application::GetWindowHeight();
- // Projection matrix : Orthographic Projection
- Mtx44 projection;
- projection.SetToOrtho(0, m_worldWidth, 0, m_worldHeight, -10, 10);
- projectionStack.LoadMatrix(projection);
- // Camera matrix
- viewStack.LoadIdentity();
- viewStack.LookAt(
- camera.position.x, camera.position.y, camera.position.z,
- camera.target.x, camera.target.y, camera.target.z,
- camera.up.x, camera.up.y, camera.up.z
- );
- // Model matrix : an identity matrix (model will be at the origin)
- modelStack.LoadIdentity();
- RenderMesh(meshList[GEO_AXES], false);
- for(std::vector<GameObject *>::iterator it = m_goList.begin(); it != m_goList.end(); ++it)
- {
- GameObject *go = (GameObject *)*it;
- if(go->active)
- {
- RenderGO(go);
- }
- }
- //On screen text
- //Exercise 5: Render m_objectCount
- //Exercise 8c: Render initial and final momentum
- std::ostringstream ss;
- ss.precision(3);
- ss << "Speed: " << m_speed;
- RenderTextOnScreen(meshList[GEO_TEXT], ss.str(), Color(0, 1, 0), 3, 0, 6);
- ss.str("");
- ss << "Game Objs: " << m_objectCount;
- RenderTextOnScreen(meshList[GEO_TEXT], ss.str(), Color(0, 1, 0), 3, 0, 9);
- ss.str("");
- ss << "Final mom:" << Vector3 (m1 * v1 + m2 * v2);
- RenderTextOnScreen(meshList[GEO_TEXT], ss.str(), Color(0, 1, 0), 3, 0, 12);
- ss.str("");
- ss << "Initial mom:" << Vector3(m1 * u1 + m2 * u2);
- RenderTextOnScreen(meshList[GEO_TEXT], ss.str(), Color(0, 1, 0), 3, 0, 15);
- ss.str("");
- ss.precision(5);
- ss << "Initial KE: " << initialKE;
- RenderTextOnScreen(meshList[GEO_TEXT], ss.str(), Color(0, 1, 0), 3, 0, 21);
- ss.str("");
- ss.precision(5);
- ss << " Final KE: " << finalKE;
- RenderTextOnScreen(meshList[GEO_TEXT], ss.str(), Color(0, 1, 0), 3, 0, 18);
- ss.str("");
- ss.precision(5);
- ss << "FPS: " << fps;
- RenderTextOnScreen(meshList[GEO_TEXT], ss.str(), Color(0, 1, 0), 3, 0, 3);
- RenderTextOnScreen(meshList[GEO_TEXT], "Collision", Color(0, 1, 0), 3, 0, 0);
- }
- void SceneCollision::Exit()
- {
- SceneBase::Exit();
- //Cleanup GameObjects
- while(m_goList.size() > 0)
- {
- GameObject *go = m_goList.back();
- delete go;
- m_goList.pop_back();
- }
- if(m_ghost)
- {
- delete m_ghost;
- m_ghost = NULL;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement