Commit 794a9f4f authored by Håkon Berg Borhaug's avatar Håkon Berg Borhaug
Browse files

Collision detection + change in model matrix logic of obstacle and character

parent 0c1e2acd
......@@ -46,6 +46,7 @@ set( INCLUDE
include/Texture.h
include/Projection.h
include/Skybox.h
include/Obstacle.h
include/GLErrorHandler.h
include/stb_image.h
......@@ -65,6 +66,7 @@ set( SRCS
src/VertexBuffer.cpp
src/Texture.cpp
src/Skybox.cpp
src/Obstacle.cpp
src/GLErrorHandler.cpp
src/stb_image.cpp
......
......@@ -54,8 +54,8 @@ void display()
if(keyPressed[KEY_ID_C]==true) gm->getCam()->moveDown();
if(keyPressed[KEY_ID_H]==true) gm->getCam()->rotateLeft();
if(keyPressed[KEY_ID_J]==true) gm->getCam()->rotateRight();
if(keyPressed[KEY_ID_O]==true) gm->getCharacter()->increaseSpeed();
if(keyPressed[KEY_ID_P]==true) gm->getCharacter()->decreaseSpeed();
if(keyPressed[KEY_ID_O]==true) gm->getCharacter()->increaseSpeed();
if(keyPressed[KEY_ID_P]==true) gm->getCharacter()->decreaseSpeed();
glutSwapBuffers();
glutPostRedisplay();
......
......@@ -5,14 +5,26 @@
#include <GL/glu.h>
#include "SceneObject.hpp"
enum characterStates {
normal = 0,
colliding = 1,
};
class Character : public SceneObject
{
public:
Character();
Character(glm::vec3 trans);
~Character();
void increaseSpeed();
void decreaseSpeed();
glm::vec3 getPosition() { return position_; }
float getSize() { return size_; }
float getState() { return state_; }
void setColor(float r, float g, float b) { color_[0] = r, color_[1] = g, color_[2] = b; }
void setState(int newState) { state_ = newState; }
protected:
void privateInit();
void privateRender();
......@@ -32,7 +44,6 @@ class Character : public SceneObject
void renderNormals();
void renderHealthbar();
private:
std::vector< glm::vec3 > vertexArray_;
std::vector< glm::vec3 > normalArray_;
......@@ -43,13 +54,19 @@ class Character : public SceneObject
std::vector< glm::vec2 > healthbarTextureArray_;
unsigned int texture;
float color_[3] = {1.0f, 0.0f, 0.0f};
glm::vec3 position_;
float size_ = 50.0f;
int state_ = characterStates::normal;
int list_id_;
float speed_;
float speed_ = 0;
float life_;
float armor_;
};
......@@ -10,6 +10,7 @@
#include "Text.hpp"
#include "Minimap.hpp"
#include "Skybox.h"
#include "Obstacle.h"
#include <GL/gl.h>
#include <GL/glu.h>
......@@ -32,25 +33,17 @@ class GameManager : public SceneObject
virtual void privateUpdate();
private:
std::shared_ptr<Plane> ls1_;
std::shared_ptr<Plane> ls2_;
std::shared_ptr<Plane> ls3_;
std::shared_ptr<Plane> ls4_;
std::shared_ptr<Plane> ls5_;
// std::shared_ptr<Plane> sbw_;
// std::shared_ptr<Plane> sbn_;
// std::shared_ptr<Plane> sbe_;
// std::shared_ptr<Plane> sbs_;
// std::shared_ptr<Plane> sbu_;
// std::shared_ptr<Plane> sbd_;
std::vector<std::shared_ptr<Plane>> landscape_;
std::shared_ptr<Skybox> sb_;
std::shared_ptr<Character> character_;
std::vector<std::shared_ptr<Obstacle>> obstacles_;
std::shared_ptr<Camera> cam_;
std::shared_ptr<Snow> snow_;
std::shared_ptr<Text> text_;
std::shared_ptr<Minimap> minimap_;
void checkCollisions();
void handleCollision(std::shared_ptr<Obstacle> obs);
void resetCharacterAfterCollision();
};
#pragma once
#include "../include/VertexArray.h"
#include "../include/VertexBuffer.h"
#include "../include/VertexBufferLayout.h"
#include "../include/IndexBuffer.h"
#include "../include/Shader.h"
#include "../include/Texture.h"
#include <windows.h>
#include <GL/freeglut.h>
#include <GL/glu.h>
#include "SceneObject.hpp"
#include "../../glm-master/glm/glm.hpp"
// 4 points with 3D position and 2D texture position
#define OB_POS_ARRAY_SIZE 6 * 4 * 3
#define OB_IND_ARRAY_SIZE 6 * 4
class Obstacle : public SceneObject
{
public:
Obstacle(glm::vec3 trans, glm::vec3 rotationAxis, float rotationAngle);
~Obstacle();
glm::vec3 getPosition() { return position_; }
float getSize() { return size_; }
protected:
virtual void privateInit();
virtual void privateRender();
virtual void privateUpdate();
private:
const float size_ = 50.0f;
float positions_[OB_POS_ARRAY_SIZE] = {
// Right face
size_, -size_, size_,
size_, -size_, -size_,
size_, size_, -size_,
size_, size_, size_,
// Left face
-size_, -size_, -size_,
-size_, -size_, size_,
-size_, size_, size_,
-size_, size_, -size_,
// Top face
-size_, size_, size_,
size_, size_, size_,
size_, size_, -size_,
-size_, size_, -size_,
// Bottom face
-size_, -size_, -size_,
size_, -size_, -size_,
size_, -size_, size_,
-size_, -size_, size_,
// North face
size_, -size_, -size_,
-size_, -size_, -size_,
-size_, size_, -size_,
size_, size_, -size_,
// South Face
-size_, -size_, size_,
size_, -size_, size_,
size_, size_, size_,
-size_, size_, size_,
};
unsigned int indices_[OB_IND_ARRAY_SIZE] = {
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15,
16, 17, 18, 19,
20, 21, 22, 23
};
VertexArray vao;
VertexBuffer vbo = VertexBuffer(positions_, OB_POS_ARRAY_SIZE * sizeof(float));
VertexBufferLayout layout;
IndexBuffer ibo = IndexBuffer(indices_, OB_IND_ARRAY_SIZE);
Shader shader = Shader("C:/dev/uni/DTE-3609_VR_graphics_animation/start_code/resources/shaders/Obstacle_vertex.shader",
"C:/dev/uni/DTE-3609_VR_graphics_animation/start_code/resources/shaders/Obstacle_fragment.shader");
std::vector<std::string> faceTextures{
"C:/dev/uni/DTE-3609_VR_graphics_animation/start_code/resources/textures/rock.png",
"C:/dev/uni/DTE-3609_VR_graphics_animation/start_code/resources/textures/rock.png",
"C:/dev/uni/DTE-3609_VR_graphics_animation/start_code/resources/textures/rock.png",
"C:/dev/uni/DTE-3609_VR_graphics_animation/start_code/resources/textures/rock.png",
"C:/dev/uni/DTE-3609_VR_graphics_animation/start_code/resources/textures/rock.png",
"C:/dev/uni/DTE-3609_VR_graphics_animation/start_code/resources/textures/rock.png"
};
Texture texture = Texture(faceTextures);
unsigned int textureSlot = 0;
float scaling;
glm::vec3 position_;
};
......@@ -71,6 +71,10 @@ class SceneObject
// Relative to the object's parent. Defaults to the identity matrix.
glm::mat4 matrix_;
glm::mat4 translation_ = glm::mat4(1.0f);
glm::mat4 rotation_ = glm::mat4(1.0f);
glm::mat4 scaling_= glm::mat4(1.0f);
// View matrix
glm::mat4 viewMatrix_;
......
......@@ -15,7 +15,6 @@
#include "SceneObject.hpp"
#include "../../glm-master/glm/glm.hpp"
// 4 points with 3D position and 2D texture position
#define SB_POS_ARRAY_SIZE 6 * 6 * 3
#define SB_IND_ARRAY_SIZE 6 * 6
......
// FRAGMENT SHADER
#shader fragment
#version 330 core
layout(location = 0) out vec4 color;
in vec3 v_TexCoord;
//uniform vec4 u_Color;
uniform samplerCube u_Texture;
void main() {
vec4 texColor = texture(u_Texture, v_TexCoord);
color = texColor;
};
// VERTEX SHADER
#shader vertex
#version 330 core
layout(location = 0) in vec3 position;
out vec3 v_TexCoord;
uniform mat4 u_ProjectionMatrix;
uniform mat4 u_ViewMatrix;
uniform mat4 u_ModelMatrix;
void main() {
gl_Position = u_ProjectionMatrix * u_ViewMatrix * u_ModelMatrix * vec4(position, 1.0);
v_TexCoord = position;
};
......@@ -35,36 +35,36 @@ void Camera::privateUpdate()
void Camera::moveRight()
{
matrix_ = glm::translate(matrix_, glm::vec3(-5.0f, 0.0f, 0.0f));
matrix_ = glm::translate(matrix_, glm::vec3(-6.0f, 0.0f, 0.0f));
}
void Camera::moveLeft()
{
matrix_ = glm::translate(matrix_, glm::vec3(5.0f, 0.0f, 0.0f));
matrix_ = glm::translate(matrix_, glm::vec3(6.0f, 0.0f, 0.0f));
}
void Camera::moveUp()
{
matrix_ = glm::translate(matrix_, glm::vec3(0.0f, -5.0f, 0.0f));
matrix_ = glm::translate(matrix_, glm::vec3(0.0f, -6.0f, 0.0f));
}
void Camera::moveDown()
{
matrix_ = glm::translate(matrix_, glm::vec3(0.0f, 5.0f, 0.0f));
matrix_ = glm::translate(matrix_, glm::vec3(0.0f, 6.0f, 0.0f));
}
void Camera::moveForward()
{
matrix_ = glm::translate(matrix_, glm::vec3(0.0f, 0.0f, 5.0f));
matrix_ = glm::translate(matrix_, glm::vec3(0.0f, 0.0f, 6.0f));
}
void Camera::moveBackward()
{
matrix_ = glm::translate(matrix_, glm::vec3(0.0f, 0.0f, -5.0f));
matrix_ = glm::translate(matrix_, glm::vec3(0.0f, 0.0f, -6.0f));
}
void Camera::rotateLeft()
{
matrix_ = glm::rotate(matrix_, .01f, glm::vec3(0.0f, 1.0f, 0.0f));
matrix_ = glm::rotate(matrix_, .02f, glm::vec3(0.0f, 1.0f, 0.0f));
}
void Camera::rotateRight()
{
matrix_ = glm::rotate(matrix_, -.01f, glm::vec3(0.0f, 1.0f, 0.0f));
matrix_ = glm::rotate(matrix_, -.02f, glm::vec3(0.0f, 1.0f, 0.0f));
}
#include "../include/Character.hpp"
#include "../../glm-master/glm/glm.hpp"
#include "../../glm-master/glm/gtc/matrix_transform.hpp"
......@@ -8,14 +7,15 @@
#include <iostream>
#include <fstream>
Character::Character()
Character::Character(glm::vec3 trans)
:position_(trans)
{
list_id_ = glGenLists(1);
auto translation = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 30.0f, 0.0f));
auto rotation = glm::rotate(glm::mat4(1.0f), glm::radians(30.0f), glm::vec3(0.0f, 0.0f, 1.0f));
translation_ = glm::translate(glm::mat4(1.0f), trans);
rotation_ = glm::rotate(glm::mat4(1.0f), glm::radians(30.0f), glm::vec3(0.0f, 0.0f, 1.0f));
matrix_ = translation * rotation;
matrix_ = translation_ * rotation_ * scaling_;
}
Character::~Character()
......@@ -24,8 +24,6 @@ Character::~Character()
void Character::privateInit()
{
speed_ = 1.0f;
setUpVertices();
createNormalLineList();
......@@ -86,7 +84,7 @@ void Character::privateRender()
void Character::renderCube()
{
glColor3f(1.0f, 0.0f, 0.0f);
glColor3f(color_[0], color_[1], color_[2]);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, normalArray_.data());
glDisableClientState(GL_NORMAL_ARRAY);
......@@ -379,11 +377,21 @@ void Character::privateUpdate()
void Character::increaseSpeed()
{
speed_ = speed_ + 0.2f;
if (position_.z > -150.0f) {
auto const trans = glm::vec3(0.0f, 0.0f, -5.0f);
translation_ = glm::translate(translation_, trans);
matrix_ = translation_ * rotation_ * scaling_;
position_ += trans;
}
}
void Character::decreaseSpeed()
{
speed_ = speed_ - 0.2f;
if (position_.z < 150.0f) {
auto const trans = glm::vec3(0.0f, 0.0f, 5.0f);
translation_ = glm::translate(translation_, trans);
matrix_ = translation_ * rotation_ * scaling_;
position_ += trans;
}
}
......@@ -14,6 +14,8 @@ void GameManager::privateInit()
{
// Set default OpenGL states
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// glEnable(GL_FOG);
// glFogi(GL_FOG_MODE, GL_LINEAR);
......@@ -26,6 +28,7 @@ void GameManager::privateInit()
cam_.reset(new Camera());
// Landscape
const auto landscapeSegments = 5;
const auto landscapeSize = 200.0f;
const auto landscapeScaling = 3.0f;
const auto landscapeRealSize = landscapeSize * landscapeScaling;
......@@ -34,30 +37,35 @@ void GameManager::privateInit()
const auto landscapeX = landscapeRealSize * cos(glm::radians(landscapeRotationDegree));
const auto landscapeY = landscapeRealSize * sin(glm::radians(landscapeRotationDegree));
ls1_.reset(new Plane(glm::vec3(0.0f, -50.0f, 0.0f), landscapeRotationAxis,
landscapeRotationDegree, glm::vec3(landscapeScaling, landscapeScaling, landscapeScaling)));
this->addSubObject(ls1_);
ls2_.reset(new Plane(glm::vec3(landscapeX, -50.0f + landscapeY, 0.0f), landscapeRotationAxis,
landscapeRotationDegree, glm::vec3(landscapeScaling, landscapeScaling, landscapeScaling)));
this->addSubObject(ls2_);
ls3_.reset(new Plane(glm::vec3(2 * landscapeX, -50.0f + 2 * landscapeY, 0.0f), landscapeRotationAxis,
landscapeRotationDegree, glm::vec3(landscapeScaling, landscapeScaling, landscapeScaling)));
this->addSubObject(ls3_);
ls4_.reset(new Plane(glm::vec3(3 * landscapeX, -50.0f + 3 * landscapeY, 0.0f), landscapeRotationAxis,
landscapeRotationDegree, glm::vec3(landscapeScaling, landscapeScaling, landscapeScaling)));
this->addSubObject(ls4_);
ls5_.reset(new Plane(glm::vec3(4 * landscapeX, -50.0f + 4 * landscapeY, 0.0f), landscapeRotationAxis,
landscapeRotationDegree, glm::vec3(landscapeScaling, landscapeScaling, landscapeScaling)));
this->addSubObject(ls5_);
for (unsigned int i = 0; i < landscapeSegments; i++) {
std::shared_ptr<Plane> current_segment;
current_segment.reset(new Plane(glm::vec3(0.0f + landscapeX * i, -50.0f + landscapeY * i, 0.0f), landscapeRotationAxis,
landscapeRotationDegree, glm::vec3(landscapeScaling, landscapeScaling, landscapeScaling)));
this->addSubObject(current_segment);
landscape_.push_back(current_segment);
}
// Skybox
sb_.reset(new Skybox());
this->addSubObject(sb_);
// Character
character_.reset(new Character());
character_.reset(new Character(glm::vec3(0.0f, 30.0f, 0.0f)));
this->addSubObject(character_);
// Obstacles
const auto obstacleNumber = 1;
for (unsigned int i = 0; i < obstacleNumber; i++) {
std::shared_ptr<Obstacle> obstacle;
obstacle.reset(new Obstacle(glm::vec3(400 + landscapeX * i, 260 + landscapeY * i, 0.0f), landscapeRotationAxis,
landscapeRotationDegree));
this->addSubObject(obstacle);
obstacles_.push_back(obstacle);
}
// Snow
snow_.reset(new Snow());
this->addSubObject(snow_);
......@@ -79,11 +87,52 @@ void GameManager::privateRender()
void GameManager::privateUpdate()
{
checkCollisions();
// Instead of adding alle objects in the scene as subobject to the camera they are added as subobjects
// to the game manager. Therefore, we set the game manager matrix equal to the camera matrix.
this->matrix_ = cam_->getMatrix();
}
void GameManager::checkCollisions()
{
for (auto obs : obstacles_) {
const auto obsPos = obs->getPosition();
const auto obsSize = obs->getSize();
const auto charPos = character_->getPosition();
const auto charSize = character_->getSize();
// std::cout << "OBSTACLE: " << obsPos.x << " " << obsPos.y << std::endl;
// std::cout << "CHARACTER: " << charPos.x << " " << charPos.y << std::endl;
const bool collisionX = charPos.x - charSize <= obsPos.x + obsSize && charPos.x + charSize >= obsPos.x - obsSize;
const bool collisionY = charPos.y - charSize <= obsPos.y + obsSize && charPos.y + charSize >= obsPos.y - obsSize;
const bool collisionZ = charPos.z - charSize <= obsPos.z + obsSize && charPos.z + charSize >= obsPos.z - obsSize;
if (collisionX && collisionY && collisionZ) {
if (character_->getState() != characterStates::colliding) {
handleCollision(obs);
}
return;
}
}
if (character_->getState() == characterStates::colliding) {
resetCharacterAfterCollision();
}
}
void GameManager::handleCollision(std::shared_ptr<Obstacle> obs)
{
character_->setColor(1.0f, 1.0f, 1.0f);
character_->setState(characterStates::colliding);
}
void GameManager::resetCharacterAfterCollision()
{
character_->setColor(1.0f, 0.0f, 0.0f);
character_->setState(characterStates::normal);
}
std::shared_ptr<Camera> GameManager::getCam()
{
return cam_;
......
#include "../include/Obstacle.h"
#include "../../glm-master/glm/glm.hpp"
#include "../../glm-master/glm/gtc/type_ptr.hpp"
Obstacle::Obstacle(glm::vec3 trans, glm::vec3 rotationAxis, float rotationAngle)
:position_(trans)
{
translation_ = glm::translate(glm::mat4(1.0f), trans);
rotation_ = glm::rotate(glm::mat4(1.0f), glm::radians(rotationAngle), rotationAxis);
matrix_ = translation_ * rotation_ * scaling_;
}
Obstacle::~Obstacle()
{
}
void Obstacle::privateInit()
{
/* VERTEX BUFFER */
// Is set up in initialization of object attribute
/* LAYOUT */
// 3 floats for world position
layout.Push<float>(3);
// 2 floats for texture position
// layout.Push<float>(2);
/* VERTEX ARRAY */
vao.AddBuffer(vbo, layout);
/* INDEX BUFFER */
// Is set up in initialization of object attribute
/* SHADER */
shader.Bind();
// shader.SetUniform4f("u_Color", 0.0f, 0.0f, 1.0f, 1.0f);
/* TEXTURE */
texture.BindCubemap(textureSlot);
shader.SetUniform1i("u_Texture", textureSlot);
/* UNBINDING */
texture.UnbindCubemap();
vao.Unbind();
vbo.Unbind();
ibo.Unbind();
shader.Unbind();
}
void Obstacle::privateRender()
{
shader.Bind();
vao.Bind();
ibo.Bind();
texture.BindCubemap(textureSlot);
shader.SetUniformMat4f("u_ViewMatrix", viewMatrix_);
shader.SetUniformMat4f("u_ProjectionMatrix", projMatrix_);
shader.SetUniformMat4f("u_ModelMatrix", matrix_);
GLCall(glDrawElements(GL_QUADS, ibo.GetCount(), GL_UNSIGNED_INT, nullptr));
texture.UnbindCubemap();
ibo.Unbind();
vao.Unbind();
shader.Unbind();
}
void Obstacle::privateUpdate()
{
glm::vec3 trans;
float speed = -3.0f;
float resetDistance = 2000.0f;
if (position_.x < - 1.5 * 200 * 3) {
trans = glm::vec3(resetDistance, tan(glm::radians(30.0f)) * resetDistance, 0.0f);
}
else {
trans = glm::vec3(speed, tan(glm::radians(30.0f)) * speed, 0.0f);
}
rotation_ = glm::rotate(rotation_, 0.05f, glm::vec3(0.0f, 0.0f, 1.0f));
translation_ = glm::translate(translation_, trans);
matrix_ = translation_ * rotation_ * scaling_;
position_ += trans;
}
......@@ -66,64 +66,6 @@ void Skybox::privateRender()
ibo.Unbind();
vao.Unbind();
shader.Unbind()