fixed plenty of bugs, added sponza, added jumping
This commit is contained in:
parent
b81630c28c
commit
9cfc6d581a
@ -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()
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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!");
|
||||
|
@ -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");
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user