- Moved camera constructor to create method

- Removed yaw and pitch properties from camera create method
- Removed movement code from camera
- Added setYaw and setPitch to camera class
- Created Player class which holds camera class
- Player position and yaw/pitch are synced with camera
- Movement code moved to player class
- Added collision in player class
- Added gravity and friction to player
- Created Ray class
- Used Ray class to get what block player is looking at
- Show currently looked at block in DebugGui
- Changed DebugGUI class to be more concise and show more information
- Added a crosshair to the game, temporarily in GameInstance class
master
aurailus 2018-12-30 19:18:42 -08:00
parent 9922d498e0
commit 4e3f48b867
17 changed files with 410 additions and 109 deletions

View File

@ -70,6 +70,6 @@ add_executable(zeus
zeus/engine/graphics/TextBuilder.h
zeus/engine/graphics/TextBuilder.cpp
zeus/engine/graphics/HudText.cpp
zeus/engine/graphics/HudText.h zeus/game/gui/DebugGui.cpp zeus/gui/DebugGui.h)
zeus/engine/graphics/HudText.h zeus/game/gui/DebugGui.cpp zeus/game/gui/DebugGui.h zeus/game/world/Player.cpp zeus/game/world/Player.h zeus/engine/Ray.cpp zeus/engine/Ray.h)
target_link_libraries(zeus ${OPENGL_gl_LIBRARY} glfw libGLEW.so pthread lua dl)

BIN
tex/gui/crosshair.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 206 B

After

Width:  |  Height:  |  Size: 206 B

View File

@ -6,71 +6,12 @@
Camera::Camera() = default;
Camera::Camera(glm::vec3 position, glm::vec3 up, double yaw, double pitch, float moveSpeed, float turnSpeed) {
this->position = position;
void Camera::create(glm::vec3 up) {
this->position = glm::vec3(0, 0, 0);
this->worldUp = up;
this->yaw = yaw;
this->pitch = pitch;
this->yaw = 0;
this->pitch = 0;
this->front = glm::vec3(0.0f, 0.0f, -1.0f);
this->moveSpeed = moveSpeed;
this->turnSpeed = turnSpeed;
update();
}
void Camera::keyControl(bool *keys, GLfloat delta) {
GLfloat moveMult = moveSpeed * delta;
glm::vec3 frontFlat = glm::vec3(front);
frontFlat.y = 0;
frontFlat = glm::normalize(frontFlat);
glm::vec3 rightFlat = glm::vec3(right);
rightFlat.y = 0;
rightFlat = glm::normalize(rightFlat);
if (keys[GLFW_KEY_W]) {
position += frontFlat * moveMult;
}
if (keys[GLFW_KEY_S]) {
position -= frontFlat * moveMult;
}
if (keys[GLFW_KEY_D]) {
position += rightFlat * moveMult;
}
if (keys[GLFW_KEY_A]) {
position -= rightFlat * moveMult;
}
if (keys[GLFW_KEY_SPACE]) {
position += worldUp * moveMult;
}
if (keys[GLFW_KEY_LEFT_SHIFT]) {
position -= worldUp * moveMult;
}
}
void Camera::mouseControl(double deltaX, double deltaY) {
deltaX *= turnSpeed;
deltaY *= turnSpeed;
//
// if (deltaX != 0 || deltaY != 0) {
// printf("%f, %f\n", deltaX, deltaY);
// }
//
yaw += deltaX;
pitch += deltaY;
if (pitch > 90.0f) {
pitch = 90.0f;
}
if (pitch < -90.0f) {
pitch = -90.0f;
}
update();
}
@ -79,6 +20,18 @@ glm::mat4 Camera::calculateViewMatrix() {
return glm::lookAt(position, position + front, up);
}
void Camera::setYaw(double yaw) {
this->yaw = yaw;
update();
}
void Camera::setPitch(double pitch) {
this->pitch = pitch;
update();
}
void Camera::update() {
front.x = (float)(cos(glm::radians(yaw)) * cos(glm::radians(pitch)));
front.y = (float)(sin(glm::radians(pitch)));

View File

@ -13,31 +13,28 @@
class Camera {
public:
Camera();
Camera(glm::vec3 position, glm::vec3 up, double yaw, double pitch, float moveSpeed, float turnSpeed);
void keyControl(bool* keys, GLfloat delta);
void mouseControl(double deltaX, double deltaY);
void create(glm::vec3 up);
glm::vec3* getPosition();
void setPosition(glm::vec3 pos);
void setYaw(double yaw);
void setPitch(double pitch);
glm::mat4 calculateViewMatrix();
~Camera();
private:
glm::vec3 position;
glm::vec3 front;
glm::vec3 up;
glm::vec3 right;
glm::vec3 worldUp;
private:
glm::vec3 position;
double yaw;
double pitch;
float moveSpeed;
float turnSpeed;
void update();
};

34
zeus/engine/Ray.cpp Normal file
View File

@ -0,0 +1,34 @@
//
// Created by aurailus on 30/12/18.
//
#include "Ray.h"
Ray::Ray(glm::vec3 position, float yaw, float pitch) {
this->start = position;
this->position = position;
this->yaw = glm::radians(yaw + 90);
this->pitch = glm::radians(pitch);
}
Ray::Ray(Player* player) {
this->start = *player->getPos();
this->position = start;
this->yaw = glm::radians(player->getYaw() + 90);
this->pitch = glm::radians(player->getPitch());
}
void Ray::step(float scale) {
position.x += scale * std::sin(yaw) * std::cos(pitch);
position.y += scale * std::sin(pitch);
position.z += scale * -std::cos(yaw) * std::cos(pitch);
}
glm::vec3* Ray::getEnd() {
return &position;
}
float Ray::getLength() {
return glm::distance(start, position);
}

31
zeus/engine/Ray.h Normal file
View File

@ -0,0 +1,31 @@
//
// Created by aurailus on 30/12/18.
//
#ifndef ZEUS_RAY_H
#define ZEUS_RAY_H
#include <vec3.hpp>
#include <cmath>
#include <glm.hpp>
#include "../game/world/Player.h"
class Ray {
public:
Ray() = default;
explicit Ray(Player* player);
Ray(glm::vec3 position, float yaw, float pitch);
void step(float scale);
glm::vec3* getEnd();
float getLength();
private:
glm::vec3 start;
glm::vec3 position;
float yaw;
float pitch;
};
#endif //ZEUS_RAY_H

View File

@ -8,7 +8,9 @@ Renderer::Renderer(GLint winWidth, GLint winHeight) {
window = new Window(winWidth, winHeight);
window->initialize();
camera = new Camera(glm::vec3(0.0f, 16.0f, 0.0f), glm::vec3(0, 1, 0), -90.0f, -45.0f, 10.0f, 0.1f);
camera = new Camera();
camera->create(glm::vec3(0, 1, 0));
worldShader = new Shader();
worldShader->createFromFile("../zeus/shader/world.vs", "../zeus/shader/world.fs");

View File

@ -4,6 +4,7 @@
#include "GameInstance.h"
#include "../lua_api/LRegisterBlock.h"
#include "../engine/Ray.h"
GameInstance::GameInstance() = default;
@ -25,8 +26,6 @@ void GameInstance::initialize(Renderer* renderer) {
//The game requires the blockAtlas for meshing and handling inputs.
world = new World(blockAtlas);
renderer->getCamera()->setPosition(glm::vec3(8, 24, 8));
int SIZE = 8;
for (int i = -SIZE; i < SIZE; i++) {
for (int j = 0; j < 8; j++) {
@ -36,9 +35,41 @@ void GameInstance::initialize(Renderer* renderer) {
}
}
player = new Player();
player->create(world, renderer->getCamera());
player->setPos(glm::vec3(16, 24, 0));
world->genNewChunk(glm::vec3(0, 0, 0));
gui.pushGuiObjects(guiEntities);
auto crosshairTexture = new Texture((char*)"../tex/gui/crosshair.png");
crosshairTexture->load();
auto crosshair = new Entity();
auto crossVerts = new std::vector<float> {
-0.5, -0.5, 0, 0, 0, 0, 0, 0,
-0.5, 0.5, 0, 0, 1, 0, 0, 0,
0.5, 0.5, 0, 1, 1, 0, 0, 0,
0.5, -0.5, 0, 1, 0, 0, 0, 0,
};
auto crossInds = new std::vector<unsigned int> {
0, 1, 2, 2, 3, 0
};
auto m = new Mesh();
m->create(crossVerts, crossInds);
crosshair->create(m, crosshairTexture);
delete crossVerts;
delete crossInds;
crosshair->setPosition(glm::vec3(renderer->getWindow()->getBufferWidth()/2, renderer->getWindow()->getBufferHeight()/2, 0));
crosshair->setScale(22);
guiEntities.push_back(crosshair);
}
void GameInstance::update(GLfloat deltaTime, double fps) {
@ -47,21 +78,32 @@ void GameInstance::update(GLfloat deltaTime, double fps) {
auto camera = renderer->getCamera();
auto window = renderer->getWindow();
camera->keyControl(window->getKeysArray(), deltaTime);
camera->mouseControl(window->getDeltaX(), window->getDeltaY());
player->update(window->getKeysArray(), deltaTime, window->getDeltaX(), window->getDeltaY());
glm::vec3 round = World::roundVec(*camera->getPosition());
round.y -= 2;
// glm::vec3 chunk = World::chunkVec(round);
// glm::vec3 local = World::localVec(round);
int block = world->getBlock(round);
std::string name = "Null";
std::string on = "Null";
if (block >= 0) {
name = blockAtlas->getBlock(block)->getIdentifier();
on = blockAtlas->getBlock(block)->getIdentifier();
}
gui.update(round, name, fps);
block = 0;
for (Ray ray(player); ray.getLength() < 5; ray.step(0.01)) {
auto found = world->getBlock(*ray.getEnd());
if (found > 0) {
block = found;
break;
}
}
std::string look = "Null";
if (block >= 0) {
look = blockAtlas->getBlock(block)->getIdentifier();
}
gui.update(player->getPos(), player->getVel(), player->getYaw(), player->getPitch(), on, look, fps);
world->update();
}
@ -78,6 +120,10 @@ void GameInstance::draw() {
renderer->draw(chunk.second);
}
for (auto &entity : entities) {
renderer->draw(entity);
}
renderer->enableGuiShader();
Texture* prevTexture = nullptr;

View File

@ -14,7 +14,8 @@
#include "../engine/helpers/ArrayTrans3D.h"
#include "../lua_api/LuaParser.h"
#include "../engine/graphics/HudText.h"
#include "../gui/DebugGui.h"
#include "gui/DebugGui.h"
#include "world/Player.h"
class GameInstance {
public:
@ -26,6 +27,8 @@ public:
void draw();
public:
Player* player;
//The renderer contains the camera, window, and draw methods.
Renderer* renderer;
@ -38,6 +41,9 @@ public:
//The block atlas holds block definitions and models.
BlockAtlas* blockAtlas;
//Entities
std::vector<Entity*> entities;
//GUI Related things
std::vector<Entity*> guiEntities;
DebugGui gui;

View File

@ -2,27 +2,31 @@
// Created by aurailus on 27/12/18.
//
#include "../../gui/DebugGui.h"
#include "DebugGui.h"
DebugGui::DebugGui() {
fontTexture = new Texture((char*)"../tex/font.png");
fontTexture = new Texture((char*)"../tex/gui/font.png");
fontTexture->load();
histogramTexture = new Texture((char*)"../tex/histogram.png");
histogramTexture = new Texture((char*)"../tex/gui/histogram.png");
histogramTexture->load();
alphaText = new HudText(fontTexture);
alphaText->set("Zeus Alpha 0.0000000001");
alphaText->set("Zeus Alpha 0.01");
alphaText->setScale(3);
alphaText->setPosition(glm::vec3(8, 4, 0));
fpsText = new HudText(fontTexture);
fpsText->setScale(2);
fpsText->setPosition(glm::vec3(8, 38, 0));
fpsText->setPosition(glm::vec3(16, 740, 0));
playerText = new HudText(fontTexture);
playerText->setScale(2);
playerText->setPosition(glm::vec3(8, 42, 0));
blockText = new HudText(fontTexture);
blockText->setScale(2);
blockText->setPosition(glm::vec3(8, 60, 0));
blockText->setPosition(glm::vec3(8, 116, 0));
fpsHistogram = new Entity();
fpsHistogram->create(new Mesh(), histogramTexture);
@ -33,6 +37,7 @@ void DebugGui::pushGuiObjects(std::vector<Entity*> &list) {
list.push_back(alphaText);
list.push_back(fpsText);
list.push_back(blockText);
list.push_back(playerText);
list.push_back(fpsHistogram);
}
@ -77,28 +82,36 @@ void DebugGui::fpsHistUpdate() {
fpsHistogram->create(m);
}
void DebugGui::update(glm::vec3 pos, std::string block, double fps) {
glm::vec3 chk = World::chunkVec(pos);
glm::vec3 loc = World::localVec(pos);
std::string string_float(float val) {
std::ostringstream out;
out.precision(2);
out << std::fixed << val;
std::string s = out.str();
return s;
}
std::string string_double(double val) {
return string_float((float)val);
}
void DebugGui::update(glm::vec3* pos, glm::vec3* vel, float yaw, float pitch, std::string block, std::string look, double fps) {
glm::vec3 chk = World::chunkVec(*pos);
glm::vec3 loc = World::localVec(*pos);
if (fpsHistory.size() > FPS_HISTOGRAM_SIZE) fpsHistory.erase(fpsHistory.begin());
fpsHistory.push_back(fps);
fpsText->set(string_double(fps) + " FPS");
fpsHistUpdate();
std::ostringstream out;
out.precision(2);
out << std::fixed << fps;
std::string s = out.str();
playerText->set(
"W: " + to_string((int)pos->x) + "," + to_string((int)pos->y) + "," + to_string((int)pos->z) + "\n" +
"C: " + to_string((int)chk.x) + "," + to_string((int)chk.y) + "," + to_string((int)chk.z) + " " +
"(" + to_string((int)loc.x) + "," + to_string((int)loc.y) + "," + to_string((int)loc.z) + ")\n" +
"V: " + string_float(vel->x) + "," + string_float(vel->y) + "," + string_float(vel->z) + "\n" +
"Yaw: " + string_float(yaw) + ", Pitch: " + string_float(pitch));
fpsText->set(s + " FPS");
blockText->set(
"World Pos: (" + to_string((int)pos.x) + ", " + to_string((int)pos.y) + ", " + to_string((int)pos.z) + ")\n" +
"Chunk Pos: (" + to_string((int)chk.x) + ", " + to_string((int)chk.y) + ", " + to_string((int)chk.z) + ")\n" +
"Local Pos: (" + to_string((int)loc.x) + ", " + to_string((int)loc.y) + ", " + to_string((int)loc.z) + ")\n" +
"Block: " + block);
blockText->set("On: " + block + "\nLooking: " + look);
}
DebugGui::~DebugGui() = default;

View File

@ -6,8 +6,8 @@
#define ZEUS_DEBUGGUI_H
#include "../engine/graphics/HudText.h"
#include "../game/world/World.h"
#include "../../engine/graphics/HudText.h"
#include "../world/World.h"
#include <sstream>
class DebugGui {
@ -15,7 +15,7 @@ public:
DebugGui();
void pushGuiObjects(std::vector<Entity*> &list);
void update(glm::vec3 pos, std::string block, double fps);
void update(glm::vec3* pos, glm::vec3* vel, float yaw, float pitch, std::string block, std::string look, double fps);
~DebugGui();
@ -27,6 +27,7 @@ private:
HudText* fpsText;
HudText* alphaText;
HudText* playerText;
HudText* blockText;
Entity* fpsHistogram;

166
zeus/game/world/Player.cpp Normal file
View File

@ -0,0 +1,166 @@
//
// Created by aurailus on 28/12/18.
//
#include <iostream>
#include "Player.h"
#include "../../engine/Timer.h"
Player::Player() {
pos = glm::vec3(0, 0, 0);
vel = glm::vec3(0, 0, 0);
}
void Player::create(World* world, Camera* camera) {
this->camera = camera;
this->world = world;
}
void Player::update(bool *keys, GLfloat delta, double mouseX, double mouseY) {
posUpdate(keys, delta);
viewUpdate(mouseX, mouseY);
moveCollide();
camera->setPosition(pos);
}
void Player::posUpdate(bool *keys, GLfloat delta) {
float moveSpeed = 5.0f;
float jumpVel = 0.14f;
float friction = 0.3f;
GLfloat moveMult = moveSpeed * delta;
if (keys[GLFW_KEY_LEFT_SHIFT]) {
moveMult *= 2;
}
glm::vec3 frontFlat = glm::normalize(glm::vec3(camera->front.x, 0, camera->front.z));
glm::vec3 rightFlat = glm::normalize(glm::vec3(camera->right.x, 0, camera->right.z));
auto mod = glm::vec3(0, 0, 0);
if (keys[GLFW_KEY_W]) mod += frontFlat;
if (keys[GLFW_KEY_S]) mod -= frontFlat;
if (keys[GLFW_KEY_D]) mod += rightFlat;
if (keys[GLFW_KEY_A]) mod -= rightFlat;
if (glm::length(mod) != 0) mod = glm::normalize(mod);
mod = mod * moveMult;
glm::vec3 velFlat = glm::vec3(vel.x, 0, vel.z);
velFlat = velFlat * (1.0f-friction) + mod * friction;
vel.x = velFlat.x;
vel.z = velFlat.z;
if (keys[GLFW_KEY_SPACE] && collides(glm::vec3(pos.x, pos.y - 0.05, pos.z)) && vel.y >= 0) {
vel.y = jumpVel;
}
}
bool Player::collides(glm::vec3 pos) {
float colSize = 0.4;
return (world->solidAt(glm::vec3(pos.x - colSize, pos.y - playerHeight, pos.z - colSize)) ||
world->solidAt(glm::vec3(pos.x + colSize, pos.y - playerHeight, pos.z - colSize)) ||
world->solidAt(glm::vec3(pos.x + colSize, pos.y - playerHeight, pos.z + colSize)) ||
world->solidAt(glm::vec3(pos.x - colSize, pos.y - playerHeight, pos.z + colSize)) );
}
void Player::moveCollide() {
double increment = 0.05;
Timer t("Move calculations");
if (!collides(glm::vec3(pos.x, pos.y - increment, pos.z))) {
vel.y = (float)fmax(vel.y - 0.01, -3);
}
else if (vel.y < 0) {
vel.y = 0;
}
double moved = 0;
for (int i = 0; i < fabs(vel.y) / increment; i++) {
double move = fmax(fmin(increment, fabs(vel.y) - moved), 0);
moved += increment;
glm::vec3 newPos = glm::vec3(pos);
newPos.y += move * (vel.y < 0 ? -1 : 1);
if (!collides(newPos))
pos = newPos;
}
moved = 0;
for (int i = 0; i < fabs(vel.x) / increment; i++) {
double move = fmax(fmin(increment, fabs(vel.x) - moved), 0);
moved += increment;
glm::vec3 newPos = glm::vec3(pos);
newPos.x += move * (vel.x < 0 ? -1 : 1);
if (!collides(newPos))
pos = newPos;
}
moved = 0;
for (int i = 0; i < fabs(vel.z) / increment; i++) {
double move = fmax(fmin(increment, fabs(vel.z) - moved), 0);
moved += increment;
glm::vec3 newPos = glm::vec3(pos);
newPos.z += move * (vel.z < 0 ? -1 : 1);
if (!collides(newPos))
pos = newPos;
}
// t.printElapsedMs();
}
void Player::viewUpdate(double deltaX, double deltaY) {
float turnSpeed = 0.1f;
deltaX *= turnSpeed;
deltaY *= turnSpeed;
yaw += deltaX;
pitch += deltaY;
if (pitch > 90.0f) {
pitch = 90.0f;
}
if (pitch < -90.0f) {
pitch = -90.0f;
}
camera->setYaw(yaw);
camera->setPitch(pitch);
}
Player::~Player() = default;
glm::vec3 *Player::getPos() {
return &pos;
}
void Player::setPos(glm::vec3 pos) {
this->pos = pos;
camera->setPosition(pos);
}
glm::vec3 *Player::getVel() {
return &vel;
}
void Player::setVel(glm::vec3 vel) {
this->vel = vel;
}
float Player::getYaw() {
return yaw;
}
float Player::getPitch() {
return pitch;
}

47
zeus/game/world/Player.h Normal file
View File

@ -0,0 +1,47 @@
//
// Created by aurailus on 28/12/18.
//
#ifndef ZEUS_PLAYER_H
#define ZEUS_PLAYER_H
#include "../../engine/Camera.h"
#include "World.h"
class Player {
public:
Player();
void create(World* world, Camera* camera);
void update(bool* keys, GLfloat delta, double mouseX, double mouseY);
void posUpdate(bool *keys, GLfloat delta);
void viewUpdate(double deltaX, double deltaY);
bool collides(glm::vec3 pos);
void moveCollide();
glm::vec3* getPos();
void setPos(glm::vec3 pos);
float getYaw();
float getPitch();
glm::vec3* getVel();
void setVel(glm::vec3 vel);
~Player();
private:
glm::vec3 pos;
float yaw, pitch;
glm::vec3 vel;
Camera* camera;
World* world;
const float playerHeight = 1.6;
};
#endif //ZEUS_PLAYER_H

View File

@ -57,6 +57,10 @@ int World::getBlock(glm::vec3 pos) {
return -1;
}
bool World::solidAt(glm::vec3 pos) {
return getBlock(pos) != 0;
}
BlockChunk* World::getChunk(glm::vec3 chunkPos) {
if (blockChunks.count(chunkPos) == 1) {
return blockChunks[chunkPos];
@ -104,7 +108,7 @@ void World::handleChunkGenQueue() {
//Takes a threadDef object which contains a vector of tasks to do, and infinitely loops, completing tasks and
//re-inserting them into the vector to be further manipulated by the main thread.
void World::chunkGenThread(World::ChunkThreadDef* threadDef) {
PerlinNoise p(0);
PerlinNoise p(10);
PerlinNoise p2(10);
//Infinite loop

View File

@ -48,6 +48,7 @@ public:
BlockChunk* getChunk(glm::vec3 chunkPos);
int getBlock(glm::vec3 pos);
bool solidAt(glm::vec3 pos);
static glm::vec3 roundVec(glm::vec3 vec) {
return glm::vec3(floor(vec.x), floor(vec.y), floor(vec.z));