fixed plenty of bugs, added sponza, added jumping

This commit is contained in:
Anselme 2016-12-19 15:11:50 +01:00
parent b81630c28c
commit 9cfc6d581a
10 changed files with 138 additions and 34 deletions

View File

@ -6,7 +6,7 @@
class DefaultKeysMap : public IKeysMap
{
public:
enum{MAIN_ACTION, SECONDARY_ACTION, TERTIARY_ACTION, MOVE_FORWARD, MOVE_BACKWARD, STRAFE_LEFT, STRAFE_RIGHT,
enum{MAIN_ACTION, SECONDARY_ACTION, TERTIARY_ACTION, MOVE_FORWARD, MOVE_BACKWARD, STRAFE_LEFT, STRAFE_RIGHT, JUMP,
TOGGLE_NOCLIP, TOGGLE_PHYSICS_DEBUG, TOGGLE_CONSOLE,
MOVE_CURSOR_LEFT, MOVE_CURSOR_RIGHT, PLOP_TEST, CLEAR_CONSOLE,
EXIT_GAME,LAST_DEFAULT_ACTION};
@ -19,6 +19,7 @@ public:
keys.push_back( {MOVE_BACKWARD, sf::Keyboard::S, IKeysMap::HOLD} );
keys.push_back( {STRAFE_LEFT, sf::Keyboard::Q, IKeysMap::HOLD} );
keys.push_back( {STRAFE_RIGHT, sf::Keyboard::D, IKeysMap::HOLD} );
keys.push_back( {JUMP, sf::Keyboard::Space, IKeysMap::PRESSED} );
keys.push_back( {TOGGLE_NOCLIP, sf::Keyboard::G, IKeysMap::PRESSED} );
keys.push_back( {TOGGLE_PHYSICS_DEBUG, sf::Keyboard::P, IKeysMap::PRESSED} );
keys.push_back( {TOGGLE_CONSOLE, sf::Keyboard::F3, IKeysMap::PRESSED} );
@ -31,7 +32,7 @@ public:
static std::vector<int> getDefaultContext()
{
return {MAIN_ACTION, SECONDARY_ACTION, TERTIARY_ACTION, MOVE_FORWARD, MOVE_BACKWARD, STRAFE_LEFT, STRAFE_RIGHT, TOGGLE_NOCLIP, TOGGLE_PHYSICS_DEBUG, TOGGLE_CONSOLE, EXIT_GAME};
return {MAIN_ACTION, SECONDARY_ACTION, TERTIARY_ACTION, MOVE_FORWARD, MOVE_BACKWARD, STRAFE_LEFT, STRAFE_RIGHT, JUMP, TOGGLE_NOCLIP, TOGGLE_PHYSICS_DEBUG, TOGGLE_CONSOLE, EXIT_GAME};
}
static std::vector<int> getShellContext()

View File

@ -19,7 +19,9 @@ Engine::Engine() :
m_physicsDebugNode(nullptr),
m_togglePhysicsDebugAction(NO_ACTION),
m_toggleShellAction(NO_ACTION),
m_exitGameAction(NO_ACTION)
m_exitGameAction(NO_ACTION),
m_showMouseAction(NO_ACTION),
m_mouseVisible(true)
{
m_clock = new sf::Clock();
m_clock->restart();
@ -47,7 +49,7 @@ void Engine::createWindow(std::string title,
{
m_window = new sf::Window(sf::VideoMode(w, h),
title,
isWindowed ? sf::Style::Close : sf::Style::Fullscreen,
isWindowed ? sf::Style::Close : sf::Style::None,
sf::ContextSettings(24, 8, 0, 3, 3, sf::ContextSettings::Attribute::Core));
m_window->setFramerateLimit(60);
m_input = new Input(m_window);
@ -158,6 +160,12 @@ void Engine::disablePhysicsDebug()
}
}
void Engine::toggleMouseVisibility()
{
m_mouseVisible = !m_mouseVisible;
m_window->setMouseCursorVisible(m_mouseVisible);
}
void Engine::setTogglePhysicsDebugAction(int action)
{
m_togglePhysicsDebugAction = action;
@ -173,6 +181,11 @@ void Engine::setExitGameAction(int action)
m_exitGameAction = action;
}
void Engine::setShowMouseAction(int action)
{
m_showMouseAction = action;
}
void Engine::outputShell(std::string str) const
{
m_sparrowshell->out(str);
@ -190,13 +203,11 @@ void Engine::checkSpecialInputs()
disablePhysicsDebug();
}
else if(action == m_toggleShellAction)
{
m_sparrowshell->toggleShell();
}
else if(action == m_exitGameAction)
{
m_running = false;
}
else if(action == m_showMouseAction)
toggleMouseVisibility();
}
}

View File

@ -32,10 +32,13 @@ public:
void enablePhysicsDebug();
void disablePhysicsDebug();
void toggleMouseVisibility();
// special inputs
void setTogglePhysicsDebugAction(int action);
void setToggleShellAction(int action);
void setExitGameAction(int action);
void setShowMouseAction(int action);
void start();
void stop();
@ -73,6 +76,8 @@ private:
int m_togglePhysicsDebugAction;
int m_toggleShellAction;
int m_exitGameAction;
int m_showMouseAction;
bool m_mouseVisible;
void checkSpecialInputs();
};

View File

@ -15,6 +15,8 @@ void LightNode::update()
{
DirectionnalLight *l = (DirectionnalLight*)m_light;
l->setDir(glm::mat3(combinedTransform) * l->getDir());
if(l->isShadowCaster())
l->updateShadowMap(m_scene);
}
break;

View File

@ -2,6 +2,7 @@
#include <btBulletCollisionCommon.h>
#include <btBulletDynamicsCommon.h>
#include <BulletDynamics/Character/btKinematicCharacterController.h>
#include <glm/ext.hpp>
@ -51,10 +52,12 @@ void FirstPersonCamera::setUpVector(const glm::vec3 &up)
computeView();
}
const float WALK_SPEED = 12.f;
const float WALK_SPEED = 8.f;
const float PLAYER_RADIUS = 0.30f;
const float PLAYER_HEIGHT = 1.75f;
const float EYES_OFFSET = 0.775f;
const float JUMP_VELOCITY = 5.f;
const float EPSILON = 1.f;
PlayerCharacterNode::PlayerCharacterNode(bool noClip) :
m_noclipMode(noClip),
@ -75,18 +78,19 @@ PlayerCharacterNode::PlayerCharacterNode(bool noClip) :
m_rigidBody->setAngularFactor(0.0);
}
void PlayerCharacterNode::setInputs(int forward, int backward, int strafeLeft, int strafeRight, int toggleNoClip)
void PlayerCharacterNode::setInputs(int forward, int backward, int strafeLeft, int strafeRight, int jump, int toggleNoClip)
{
m_inputActions[FORWARD] = forward;
m_inputActions[BACKWARD] = backward;
m_inputActions[STRAFE_LEFT] = strafeLeft;
m_inputActions[STRAFE_RIGHT] = strafeRight;
m_inputActions[JUMP] = jump;
m_inputActions[TOGGLE_NOCLIP] = toggleNoClip;
}
void PlayerCharacterNode::setPosition(float x, float y, float z)
{
btTransform transform;
btTransform transform = btTransform::getIdentity();
btVector3 pos(x, y, z);
transform.setOrigin(pos);
m_rigidBody->setWorldTransform(transform);
@ -100,6 +104,7 @@ void PlayerCharacterNode::update()
// get events
int walk = 0;
int strafe = 0;
bool jump = false;
for(int action : input->getActions())
{
if(action == m_inputActions[FORWARD])
@ -110,6 +115,8 @@ void PlayerCharacterNode::update()
--strafe;
else if(action == m_inputActions[STRAFE_RIGHT])
++strafe;
else if(action == m_inputActions[JUMP])
jump = true;
else if(action == m_inputActions[TOGGLE_NOCLIP])
toggleNoClip();
}
@ -124,6 +131,8 @@ void PlayerCharacterNode::update()
// update body movement
const glm::vec3 &glmDir = m_fpsCamera.getDirection();
const btVector3 &velocity = m_rigidBody->getLinearVelocity();
btVector3 targetVelocity(0.f, velocity.getY(), 0.f);
if(walk != 0 || strafe != 0)
{
glm::vec3 moveDir = glm::normalize(glmDir*walk + glm::cross(glmDir, glm::vec3(0, 1, 0))*strafe);
@ -134,19 +143,42 @@ void PlayerCharacterNode::update()
}
else
{
//TODO: if on ground + space pressed -> jump
glm::vec2 hPos = glm::normalize(glm::vec2(moveDir.x, moveDir.z))*WALK_SPEED;
const btVector3 &velocity = m_rigidBody->getLinearVelocity();
m_rigidBody->setLinearVelocity((velocity + btVector3(hPos.x, velocity.getY(), hPos.y)) / 2.f); // smooth movements
targetVelocity.setX(hPos.x);
targetVelocity.setZ(hPos.y);
}
}
// apply movements
if(m_noclipMode)
{
btTransform transform;
btTransform transform = btTransform::getIdentity();
transform.setOrigin(m_noclip_pos);
m_rigidBody->setWorldTransform(transform);
m_rigidBody->setLinearVelocity(btVector3(0, 0, 0));
}
else
{
float controlRatio = 0.2f; // 1 = total control, 0 = no control, can be seen as a slipperiness factor
btVector3 newVelocity = velocity*(1.f-controlRatio) + targetVelocity*controlRatio;
if(jump)
{/*
btVector3 start(pos);
start.setY(start.y() - PLAYER_HEIGHT/2.f);
btVector3 end(pos);
end.setY(end.y() - EPSILON);
btCollisionWorld::ClosestRayResultCallback RayCallback(start, end);
getEngine().getPhysics()->rayTest(start, end, RayCallback);
if(RayCallback.hasHit()) // if ground is nearby
{
//btVector3 normal = RayCallback.m_hitNormalWorld;
}*/
// raycasting not working yet
newVelocity.setY(JUMP_VELOCITY);
}
m_rigidBody->setLinearVelocity(newVelocity);
}
}
void PlayerCharacterNode::toggleNoClip()

View File

@ -41,12 +41,12 @@ class PlayerCharacterNode : public CameraNode
std::vector<int> m_inputActions;
enum PlayerAction {FORWARD, BACKWARD, STRAFE_LEFT, STRAFE_RIGHT, TOGGLE_NOCLIP};
enum PlayerAction {FORWARD, BACKWARD, STRAFE_LEFT, STRAFE_RIGHT, JUMP, TOGGLE_NOCLIP};
public:
PlayerCharacterNode(bool noClip = true);
void setInputs(int forward, int backward, int strafe_left, int strafe_right, int toggleNoClip = NO_ACTION);
void setInputs(int forward, int backward, int strafe_left, int strafe_right, int jump = NO_ACTION, int toggleNoClip = NO_ACTION);
void setPosition(float x, float y, float z);

View File

@ -81,9 +81,9 @@ void generateTerrain(SceneTree *scene, btDiscreteDynamicsWorld *world)
mat->specular = glm::vec3(0.1f);
mat->emission = glm::vec3(0.5f, 0.1f, 0.1f);
for(int x=-6; x<6; ++x)
for(int y=-3; y<3; ++y)
for(int z=-6; z<6; ++z)
for(int x=-3; x<3; ++x)
for(int y=-2; y<2; ++y)
for(int z=-3; z<3; ++z)
{
Chunk *chunk = new Chunk(&gen); // ! WARNING ! : chunk pointer is lost and never deleted
glm::vec3 pos(x, y, z);
@ -102,29 +102,59 @@ void generateTerrain(SceneTree *scene, btDiscreteDynamicsWorld *world)
}
}
void generateSponza(SceneTree *scene, btDiscreteDynamicsWorld *world)
{
GraphicalContainerNode* sponzaContainer = new GraphicalContainerNode();
scene->getRootObject()->addChild(sponzaContainer);
Loader::setTexDirectory("../data/sponza/");
std::vector<Mesh*> meshes = Loader::loadMesh("sponza.obj");
Loader::setTexDirectory("../data/");
for(Mesh* m : meshes)
{
if(m->getName().find("fabric") != std::string::npos)
delete m; // moyen crade de se débarasser temporairement des rideaux
else
{
m->initGL();
MeshNode *node = new MeshNode(m);
node->setTransform(glm::scale(glm::mat4(), glm::vec3(0.01f)));
sponzaContainer->addChild(node);
world->addRigidBody(node->buildStaticCollider());
}
}
}
int main(int argc, char** argv){
enum Mode { SIMPLEST_TEST, TERRAIN_TEST, FULLSCREEN_DEMO };
enum Mode { SIMPLEST_TEST, TERRAIN_TEST, SPONZA_TEST, FULLSCREEN_DEMO };
Mode mode = SIMPLEST_TEST;
if(argc > 1)
{
std::string modeStr(argv[1]);
if(modeStr == "terrain")
mode = TERRAIN_TEST;
else if(modeStr == "sponza")
mode = SPONZA_TEST;
else if(modeStr == "demo")
mode = FULLSCREEN_DEMO;
else if(modeStr == "simple")
mode = SIMPLEST_TEST;
else
std::cout << "AVAILABLE MODES : simple(default) / terrain / demo" << std::endl;
std::cout << "AVAILABLE MODES : simple(default) / terrain / sponza / demo" << std::endl;
}
Engine engine;
Loader::setObjDirectory("../data/");
Loader::setMtlDirectory("../data/");
Loader::setTexDirectory("../data/");
// this creates the opengl context
// the opengl context must exist before any opengl class is used (texture, pipeline, etc..)
if(mode == FULLSCREEN_DEMO)
engine.createWindow("Sparrow Engine Testing Environment", 1920, 1080, false);
if(mode == FULLSCREEN_DEMO && mode == SPONZA_TEST)
{
engine.createWindow("Sparrow Engine Testing Environment", 1920, 1080, true);
engine.toggleMouseVisibility();
}
else
engine.createWindow("Sparrow Engine Testing Environment");
@ -161,10 +191,9 @@ int main(int argc, char** argv){
*/
// first person player controller
PlayerCharacterNode *player = new PlayerCharacterNode(false);
player->setInputs(DefaultKeysMap::MOVE_FORWARD, DefaultKeysMap::MOVE_BACKWARD, DefaultKeysMap::STRAFE_LEFT, DefaultKeysMap::STRAFE_RIGHT, DefaultKeysMap::TOGGLE_NOCLIP);
player->setInputs(DefaultKeysMap::MOVE_FORWARD, DefaultKeysMap::MOVE_BACKWARD, DefaultKeysMap::STRAFE_LEFT, DefaultKeysMap::STRAFE_RIGHT, DefaultKeysMap::JUMP, DefaultKeysMap::TOGGLE_NOCLIP);
scene->getRootObject()->addChild(player);
scene->setMainCamera(player);
player->setPosition(0.f, 15.f, 0.f);
engine.getPhysics()->addRigidBody(player->getRigidbody());
// throw cubes and spheres with mouse clicks
@ -172,14 +201,34 @@ int main(int argc, char** argv){
scene->getRootObject()->addChild(potator);
// lighting
LightNode *sunLight = new LightNode(new DirectionnalLight(glm::vec3(5, 8, -2), glm::vec3(1.f)));
LightNode *ambientLight = new LightNode(new AmbientLight());
DirectionnalLight* sun = new DirectionnalLight(glm::vec3(5, 8, -2), glm::vec3(0.9f));
LightNode *sunLight = new LightNode(sun);
LightNode *fillLight = new LightNode(new DirectionnalLight(glm::vec3(8, -4, 1), glm::vec3(0.1f)));
scene->getRootObject()->addChild(ambientLight);
scene->getRootObject()->addChild(sunLight);
scene->getRootObject()->addChild(fillLight);
// terrain
if(mode != SIMPLEST_TEST)
generateTerrain(scene, engine.getPhysics());
{
sun->initShadowMap(4096);
if(mode == SPONZA_TEST)
{
generateSponza(scene, engine.getPhysics());
player->setPosition(0.f, 2.f, 0.f);
sun->setShadowView(glm::vec3(30, 30, 50));
}
else
{
generateTerrain(scene, engine.getPhysics());
player->setPosition(0.f, 15.f, 0.f);
sun->setShadowView(glm::vec3(130, 130, 70));
}
}
// shell output tests
engine.outputShell("Hello World!");

View File

@ -66,9 +66,6 @@ Potator::Potator(PlayerCharacterNode * player,
m_cubeMesh->addTriangle(id+7, id+5, id+6);
}
Loader::setObjDirectory("../data/");
Loader::setMtlDirectory("../data/");
Loader::setTexDirectory("../data/");
Image* wood = Loader::loadImage("woodbox.jpg", false);
PhongMaterial *mat = new PhongMaterial();
mat->setTexture(PhongMaterial::DIFFUSE_SLOT, new Texture(wood), "wood_texture");

View File

@ -31,12 +31,14 @@ std::string* Loader::loadTextFile(const std::string &filename)
return str;
}
Image* Loader::loadImage(const std::string &filename, bool hasAlpha)
Image* Loader::loadImage(const std::string &filename, bool hasAlpha, bool reversed)
{
sf::Image sfImg;
bool ok = sfImg.loadFromFile(tex_directory+filename);
if(!ok)
return NULL;
if(reversed)
sfImg.flipVertically();
Image* img = new Image();
img->depth = hasAlpha ? 32 : 24;
img->width = sfImg.getSize().x;
@ -98,7 +100,7 @@ Font* Loader::loadFont(const std::string &description_file, const std::string &t
font->addCharInfo(id,char_info);
}
Image* fucking_image_of_doom = loadImage(texture_file);
Image* fucking_image_of_doom = loadImage(texture_file, true, false);
if(fucking_image_of_doom == NULL)
printf("can't load \"%s\".\n", texture_file.c_str());
Texture* texture = new Texture(fucking_image_of_doom, false); // mipmaps are doing a very bad job at interpolating alpha component
@ -229,6 +231,7 @@ std::vector<Mesh*> Loader::loadMesh(const std::string &filename){
RESOURCE_ADD(currentMat,Material,material_name);
}
currentMesh->setMaterial(currentMat);
currentMesh->setName(material_name);
}
break;
default:
@ -250,6 +253,10 @@ std::vector<Mesh*> Loader::loadMesh(const std::string &filename){
else
{
Mesh* m = meshes[i];
if(m->normals.empty())
m->computeNormals();
if(m->getFlags() & (1 << Mesh::MATERIAL_PHONG_NORMAL_MAP))
m->computeTangents();
m->mergeVertices();
}
}

View File

@ -17,7 +17,7 @@ class Loader
public:
static std::string* loadTextFile(const std::string &filename);
static Image* loadImage(const std::string &filename, bool hasAlpha = true);
static Image* loadImage(const std::string &filename, bool hasAlpha = true, bool reversed = true);
static std::vector<Mesh*> loadMesh(const std::string &filename);
static Font* loadFont(const std::string &texture, const std::string &description);
static bool loadMTL(const std::string &filename);