Merge branch 'master' of github.com:Faerbit/swp

Conflicts:
	camera.cc
	graphics.cc
This commit is contained in:
Fabian Klemp 2014-11-17 13:31:01 +01:00
commit 0a0dcd90f8
22 changed files with 10110 additions and 157 deletions

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
binaries binaries
build build
Makefile Makefile
CMakeLists.txt.user
*.cbp

2069
Geometry/Sphere.obj Normal file

File diff suppressed because it is too large Load Diff

BIN
Geometry/stoneTexture.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -4,8 +4,8 @@ uniform mat4 modelMatrix;
uniform mat4 viewMatrix; uniform mat4 viewMatrix;
uniform mat4 projectionMatrix; uniform mat4 projectionMatrix;
in vec3 aNormal;
in vec3 aPosition; in vec3 aPosition;
in vec3 aNormal;
in vec2 aTexCoord; in vec2 aTexCoord;
out vec3 vNormal; out vec3 vNormal;

View File

@ -33,6 +33,30 @@ void Camera::setRotation(glm::vec2 rotation) {
void Camera::updateRotation(glm::vec2 rotation) { void Camera::updateRotation(glm::vec2 rotation) {
this->rotation += rotation; this->rotation += rotation;
if((this->rotation.x + rotation.x) >= 1.57f) {
this->rotation.x = 1.57;
this->rotation.y += rotation.y;
}
else if ((this->rotation.x + rotation.x) <= -1.57f) {
this->rotation.x = -1.57f;
this->rotation.y += rotation.y;
}
else {
this-> rotation += rotation;
}
updatePosition();
}
void Camera:: updateDistance(float distance) {
if (this->distance + distance <= 1.0f) {
this->distance = 1.0f;
}
else if (this->distance + distance >= 30.0f) {
this->distance = 30.f;
}
else {
this->distance += distance;
}
updatePosition(); updatePosition();
} }

View File

@ -10,6 +10,7 @@ class Camera {
~Camera(); ~Camera();
float getDistance(); float getDistance();
void setDistance(float distance); void setDistance(float distance);
void updateDistance(float distance); //adds to current distance
glm::vec2 getRotation(); glm::vec2 getRotation();
void setRotation(glm::vec2 rotation); void setRotation(glm::vec2 rotation);
void updateRotation(glm::vec2 rotation); //adds to current rotation void updateRotation(glm::vec2 rotation); //adds to current rotation

View File

@ -1,6 +1,11 @@
#include "entity.hh" #include "entity.hh"
Entity::Entity(glm::vec3 position, glm::vec3 rotation) { Entity::Entity(glm::vec3 position, glm::vec3 rotation) {
this->position = position;
setRotation(rotation);
}
Entity::Entity(glm::vec3 position, glm::mat4 rotation) {
this->position = position; this->position = position;
this->rotation = rotation; this->rotation = rotation;
} }
@ -15,7 +20,7 @@ glm::vec3 Entity::getPosition() {
return position; return position;
} }
glm::vec3 Entity::getRotation() { glm::mat4 Entity::getRotation() {
return rotation; return rotation;
} }
@ -24,5 +29,11 @@ void Entity::setPosition(glm::vec3 position) {
} }
void Entity::setRotation(glm::vec3 rotation) { void Entity::setRotation(glm::vec3 rotation) {
this->rotation = glm::rotate(rotation.x, glm::vec3(1.0f, 0.0f, 0.0f))
* glm::rotate(rotation.y, glm::vec3(0.0f, 1.0f, 0.0f))
* glm::rotate(rotation.z, glm::vec3(0.0f, 0.0f, 1.0f));
}
void Entity::setRotation(glm::mat4 rotation) {
this->rotation = rotation; this->rotation = rotation;
} }

View File

@ -6,15 +6,17 @@
class Entity { class Entity {
public: public:
Entity(glm::vec3 position, glm::vec3 rotation); Entity(glm::vec3 position, glm::vec3 rotation);
Entity(glm::vec3 position, glm::mat4 rotation);
Entity(); Entity();
~Entity(); ~Entity();
void setPosition(glm::vec3 positon); void setPosition(glm::vec3 positon);
void setRotation(glm::vec3 rotation); void setRotation(glm::vec3 rotation);
void setRotation(glm::mat4 rotation);
glm::vec3 getPosition(); glm::vec3 getPosition();
glm::vec3 getRotation(); glm::mat4 getRotation();
private: private:
glm::vec3 position; glm::vec3 position;
glm::vec3 rotation; glm::mat4 rotation;
}; };
#endif #endif

View File

@ -17,6 +17,8 @@ subject to the following restrictions:
#ifndef BT_OBJECT_ARRAY__ #ifndef BT_OBJECT_ARRAY__
#define BT_OBJECT_ARRAY__ #define BT_OBJECT_ARRAY__
#pragma GCC diagnostic ignored "-Wunused-variable"
#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE #include "btScalar.h" // has definitions like SIMD_FORCE_INLINE
#include "btAlignedAllocator.h" #include "btAlignedAllocator.h"

View File

@ -68,7 +68,7 @@ bool Graphics::createWindow()
glfwWindowHint( GLFW_OPENGL_DEBUG_CONTEXT, true ); glfwWindowHint( GLFW_OPENGL_DEBUG_CONTEXT, true );
// define whether the window can get resized: // define whether the window can get resized:
glfwWindowHint(GLFW_RESIZABLE, false); glfwWindowHint(GLFW_RESIZABLE, true);
// non-decorated windows can be used as splash screens: // non-decorated windows can be used as splash screens:
//glfwWindowHint( GLFW_DECORATED, false ); //glfwWindowHint( GLFW_DECORATED, false );
@ -142,13 +142,6 @@ void Graphics::setWindowSize(glm::uvec2 windowSize) {
this->windowSize = windowSize; this->windowSize = windowSize;
} }
void resizeCallback(Graphics* graphics, int newWidth, int newHeight)
{
// store the new window size and adjust the viewport:
graphics->setWindowSize(glm::uvec2( newWidth, newHeight));
glViewport( 0, 0, newWidth, newHeight);
}
glm::mat4 Graphics::buildFrustum( float phiInDegree, float _near, float _far, float aspectRatio) { glm::mat4 Graphics::buildFrustum( float phiInDegree, float _near, float _far, float aspectRatio) {
float phiHalfInRadians = 0.5*phiInDegree * (M_PI/180.0); float phiHalfInRadians = 0.5*phiInDegree * (M_PI/180.0);

View File

@ -11,8 +11,6 @@ class Graphics {
Graphics(glm::uvec2 windowSize, float nearPlane, float farPlane); Graphics(glm::uvec2 windowSize, float nearPlane, float farPlane);
Graphics(); Graphics();
void render(Level* level, ACGL::OpenGL::SharedShaderProgram shader); void render(Level* level, ACGL::OpenGL::SharedShaderProgram shader);
// gets called at window resize:
void resizeCallback( GLFWwindow *, int newWidth, int newHeight );
// to build the projection matrix: // to build the projection matrix:
glm::mat4 buildFrustum( float phiInDegree, float near, float far, float aspectRatio); glm::mat4 buildFrustum( float phiInDegree, float near, float far, float aspectRatio);
glm::mat4 buildViewMatrix(Level* level); glm::mat4 buildViewMatrix(Level* level);
@ -28,6 +26,4 @@ class Graphics {
GLFWwindow* window; GLFWwindow* window;
}; };
void resizeCallback(Graphics* graphics, int newWidth, int newHeight);
#endif #endif

View File

@ -1,5 +1,7 @@
#include "level.hh" #include "level.hh"
Level::Level(std::string filePath){ Level::Level(std::string filePath){
this->filePath = filePath; this->filePath = filePath;
this->terrain = Terrain(filePath + "/terrain"); this->terrain = Terrain(filePath + "/terrain");
@ -12,31 +14,40 @@ Level::~Level() {
} }
void Level::load(ACGL::OpenGL::SharedShaderProgram shader) { void Level::load(ACGL::OpenGL::SharedShaderProgram shader) {
this->physics = Physics();
this->physics.init();
// currently hard coded should later read this stuff out of a file // currently hard coded should later read this stuff out of a file
this->camera = Camera(glm::vec2(-0.8f, 0.0f), 3.0f); this->camera = Camera(glm::vec2(-0.8f, 0.0f), 3.0f);
// load the geometry of the stanford bunny and build a VAO: // load the geometry of the stanford bunny and build a VAO:
Model model = Model("Bunny.obj", 0.25f); Model model = Model("Sphere.obj", 0.75f);
// load a texture: // load a texture:
Material material = Material("clownfishBunny.png", 0.1f, 0.5f, 0.5f, 3.0f); Material material = Material("stoneTexture.png", 0.1f, 0.5f, 0.5f, 3.0f);
//Create object //Create object
Object object = Object(model, material, glm::vec3(0.0f, 0.0f, -2.0f), Object object = Object(model, material, glm::vec3(0.0f, 5.0f, 0.0f),
glm::vec3(0.0f, 1.0472f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0472f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 0.0f, 0.0f), shader); glm::vec3(0.0f, 0.0f, 0.0f), shader);
//add player to phy
this->physics.addPlayer(0.75f,0.0f,5.0f,0.0f,1.0f,0);
physics.addStaticGroundPlane();
//set lighting parameters //set lighting parameters
ambientLight = glm::vec3(1.0f, 1.0f, 1.0f); ambientLight = glm::vec3(1.0f, 1.0f, 1.0f);
Light light = Light(glm::vec3(-3.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), 2.0f); Light light = Light(glm::vec3(-3.0f, 6.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), 10.0f);
lights.push_back(light); lights.push_back(light);
Light light2 = Light(glm::vec3(3.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), 2.0f); Light light2 = Light(glm::vec3(3.0f, 6.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), 10.0f);
lights.push_back(light2); lights.push_back(light2);
// load terrain // load terrain
this->terrain.load(); this->terrain.load();
Model terrainModel = this->terrain.getModel(); Model terrainModel = Model(this->terrain.getModel());
// load a texture: // load a texture:
Material terrainMaterial = Material("clownfishBunny.png", 0.1f, 0.7f, 0.3f, 1.0f); Material terrainMaterial = Material("terrainTexture.png", 0.1f, 0.8f, 0.2f, 3.0f);
//Create object //Create object
Object terrainObject = Object(terrainModel, terrainMaterial, Object terrainObject = Object(terrainModel, terrainMaterial,
glm::vec3(-0.5f*(float)this->terrain.getHeightmapHeight(), 0.0f, -0.5f*(float)this->terrain.getHeightmapWidth()), glm::vec3(-0.5f*(float)this->terrain.getHeightmapHeight(), 0.0f, -0.5f*(float)this->terrain.getHeightmapWidth()),
@ -51,13 +62,30 @@ void Level::render() {
for(unsigned int i = 0; i<objects.size(); i++) { for(unsigned int i = 0; i<objects.size(); i++) {
objects[i].render(); objects[i].render();
} }
// this->terrain.render();
} }
void Level::update(float runTime, glm::vec2 mouseDelta) { void Level::update(float runTime, glm::vec2 mouseDelta, bool wPressed, bool aPressed, bool dPressed, bool sPressed) {
// rotate bunny // rotate bunny
//cameraCenter->setRotation(glm::vec3(0.0f, 1.0472f * runTime, 0.0f)); //cameraCenter->setRotation(glm::vec3(0.0f, 1.0472f * runTime, 0.0f));
camera.updateRotation(mouseDelta/50.0f); // Ignore first two mouse updates, because they are incorrect
static int i = 0;
if (i <2) {
i++;
}
else {
camera.updateRotation(mouseDelta/100.0f);
}
if(wPressed)
{
//physics.rollForward(camera.getRotation);
}
physics.takeUpdateStep(runTime);
objects[0].setPosition(physics.getPos(0));
} }
glm::vec3 Level::getAmbientLight() { glm::vec3 Level::getAmbientLight() {

View File

@ -8,6 +8,7 @@
#include "terrain.hh" #include "terrain.hh"
#include "material.hh" #include "material.hh"
#include "camera.hh" #include "camera.hh"
#include "physics.hh"
class Level { class Level {
public: public:
@ -15,7 +16,7 @@ class Level {
Level(); Level();
~Level(); ~Level();
void load(ACGL::OpenGL::SharedShaderProgram shader); // Shader is necessary for correct texture assigning void load(ACGL::OpenGL::SharedShaderProgram shader); // Shader is necessary for correct texture assigning
void update(float runTime, glm::vec2 mouseDelta); void update(float runTime, glm::vec2 mouseDelta,bool wPressed, bool aPressed,bool sPressed, bool dPressed);
void render(); void render();
glm::vec3 getAmbientLight(); glm::vec3 getAmbientLight();
std::vector<Light> getLights(); std::vector<Light> getLights();
@ -27,6 +28,7 @@ class Level {
std::vector<Light> lights; std::vector<Light> lights;
glm::vec3 ambientLight; glm::vec3 ambientLight;
Object* cameraCenter; Object* cameraCenter;
Physics physics;
Camera camera; Camera camera;
Terrain terrain; Terrain terrain;
}; };

6096
lodepng.cpp Normal file

File diff suppressed because it is too large Load Diff

1702
lodepng.h Normal file

File diff suppressed because it is too large Load Diff

67
main.cc
View File

@ -16,13 +16,6 @@
#include <ACGL/OpenGL/glloaders/extensions.hh> #include <ACGL/OpenGL/glloaders/extensions.hh>
#include <ACGL/Base/Settings.hh> #include <ACGL/Base/Settings.hh>
#include "model.hh"
using namespace std;
using namespace ACGL::OpenGL;
using namespace ACGL::Base;
using namespace ACGL::Utils;
Application::Application() { Application::Application() {
graphics = Graphics(glm::uvec2(1024, 786), 0.1f, 100.0f); graphics = Graphics(glm::uvec2(1024, 786), 0.1f, 100.0f);
} }
@ -47,13 +40,17 @@ void Application::init()
ACGL::Base::Settings::the()->setTexturePath("Geometry/"); ACGL::Base::Settings::the()->setTexturePath("Geometry/");
ACGL::Base::Settings::the()->setGeometryPath("Geometry/"); ACGL::Base::Settings::the()->setGeometryPath("Geometry/");
// load Model to give shader correct Attribute locations // construct VAO to give shader correct Attribute locations
// TODO look up if this is really necessary, since this looks really stupid. ACGL::OpenGL::SharedArrayBuffer ab = std::make_shared<ACGL::OpenGL::ArrayBuffer>();
Model model = Model("Bunny.obj"); ab->defineAttribute("aPosition", GL_FLOAT, 3);
ab->defineAttribute("aTexCoord", GL_FLOAT, 2);
ab->defineAttribute("aNormal", GL_FLOAT, 3);
ACGL::OpenGL::SharedVertexArrayObject vao = std::make_shared<ACGL::OpenGL::VertexArrayObject>();
vao->attachAllAttributes(ab);
// look up all shader files starting with 'phong' and build a ShaderProgram from it: // look up all shader files starting with 'phong' and build a ShaderProgram from it:
shader = ACGL::OpenGL::ShaderProgramCreator("phong").attributeLocations( shader = ACGL::OpenGL::ShaderProgramCreator("phong").attributeLocations(
model.getReference()->getAttributeLocations()).create(); vao->getAttributeLocations()).create();
shader->use(); shader->use();
// load Level // load Level
@ -63,10 +60,12 @@ void Application::init()
openGLCriticalError(); openGLCriticalError();
} }
/********************************************************************************************************************** void resizeCallback(GLFWwindow* window, int newWidth, int newHeight)
* Returns true if a window with the desired context could get created. {
* Requested OpenGL version gets set by ACGL defines. // store the new window size and adjust the viewport:
*/ app.getGraphics()->setWindowSize(glm::uvec2( newWidth, newHeight));
glViewport( 0, 0, newWidth, newHeight);
}
static void keyCallback(GLFWwindow* _window, int _key, int, int _action, int) static void keyCallback(GLFWwindow* _window, int _key, int, int _action, int)
{ {
@ -75,10 +74,14 @@ static void keyCallback(GLFWwindow* _window, int _key, int, int _action, int)
} }
} }
static void scrollCallback(GLFWwindow* window, double xoffset, double yoffset) {
app.getLevel()->getCamera()->updateDistance(-(float)yoffset);
}
int main( int argc, char *argv[] ) int main( int argc, char *argv[] )
{ {
Application app = Application(); //Application app = Application();
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
// Create OpenGL capable window: // Create OpenGL capable window:
@ -91,12 +94,15 @@ int main( int argc, char *argv[] )
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
// Set window title to binary name (without the path): // Set window title to binary name (without the path):
// //
std::vector<std::string> tmp = StringHelpers::split( std::string( argv[0] ), '/' ); std::vector<std::string> tmp = ACGL::Utils::StringHelpers::split( std::string( argv[0] ), '/' );
glfwSetWindowTitle(app.getGraphics()->getWindow(), tmp[tmp.size()-1].c_str() ); glfwSetWindowTitle(app.getGraphics()->getWindow(), tmp[tmp.size()-1].c_str() );
// Ensure we can capture the escape key being pressed below // Ensure we can capture the escape key being pressed below
glfwSetInputMode(app.getGraphics()->getWindow(), GLFW_STICKY_KEYS, 1 ); glfwSetInputMode(app.getGraphics()->getWindow(), GLFW_STICKY_KEYS, 1);
//glfwSetWindowSizeCallback(app.getGraphics(), resizeCallback); // Hide mouse cursor
glfwSetInputMode(app.getGraphics()->getWindow(), GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
glfwSetWindowSizeCallback(app.getGraphics()->getWindow(), resizeCallback);
glfwSetKeyCallback(app.getGraphics()->getWindow(), keyCallback ); glfwSetKeyCallback(app.getGraphics()->getWindow(), keyCallback );
glfwSetScrollCallback(app.getGraphics()->getWindow(), scrollCallback );
// Enable vertical sync (on cards that support it) with parameter 1 - 0 means off // Enable vertical sync (on cards that support it) with parameter 1 - 0 means off
glfwSwapInterval( 0 ); glfwSwapInterval( 0 );
@ -113,13 +119,21 @@ int main( int argc, char *argv[] )
const double FPSdelay = 2.0; const double FPSdelay = 2.0;
double startTimeInSeconds = glfwGetTime(); double startTimeInSeconds = glfwGetTime();
double showNextFPS = startTimeInSeconds + FPSdelay; double showNextFPS = startTimeInSeconds + FPSdelay;
double lastUpdate=0.0f;
int stateW = glfwGetKey(app.getGraphics()->getWindow(), GLFW_KEY_W);
int stateA = glfwGetKey(app.getGraphics()->getWindow(), GLFW_KEY_A);
int stateS = glfwGetKey(app.getGraphics()->getWindow(), GLFW_KEY_S);
int stateD = glfwGetKey(app.getGraphics()->getWindow(), GLFW_KEY_D);
do { do {
double now = glfwGetTime();
double now = glfwGetTime()- startTimeInSeconds;
if (showNextFPS <= now) { if (showNextFPS <= now) {
stringstream sstream (stringstream::in | stringstream::out); std::stringstream sstream (std::stringstream::in | std::stringstream::out);
sstream << setprecision(1) << std::fixed sstream << std::setprecision(1) << std::fixed
<< tmp[tmp.size()-1] << " - FPS: " << frameCount / (now-showNextFPS + FPSdelay) << " " << 1000 * (now-showNextFPS + FPSdelay)/frameCount << " msec"; << tmp[tmp.size()-1] << " - FPS: " << frameCount / (now-showNextFPS + FPSdelay) << " " << 1000 * (now-showNextFPS + FPSdelay)/frameCount << " msec";
glfwSetWindowTitle(app.getGraphics()->getWindow(), sstream.str().c_str() ); glfwSetWindowTitle(app.getGraphics()->getWindow(), sstream.str().c_str() );
showNextFPS = now + FPSdelay; showNextFPS = now + FPSdelay;
@ -130,10 +144,13 @@ int main( int argc, char *argv[] )
glfwGetCursorPos(app.getGraphics()->getWindow(), &xpos, &ypos); glfwGetCursorPos(app.getGraphics()->getWindow(), &xpos, &ypos);
glfwSetCursorPos(app.getGraphics()->getWindow(), app.getGraphics()->getWindowSize().x/2, app.getGraphics()->getWindowSize().y/2); glfwSetCursorPos(app.getGraphics()->getWindow(), app.getGraphics()->getWindowSize().x/2, app.getGraphics()->getWindowSize().y/2);
app.getLevel()->update(now - startTimeInSeconds, glm::vec2((float)ypos-app.getGraphics()->getWindowSize().y/2, app.getLevel()->update(now - lastUpdate,
(float)xpos-app.getGraphics()->getWindowSize().x/2)); glm::vec2((float)ypos-app.getGraphics()->getWindowSize().y/2,
(float)xpos-app.getGraphics()->getWindowSize().x/2),
stateW == GLFW_PRESS,stateA == GLFW_PRESS,stateS == GLFW_PRESS,stateD == GLFW_PRESS);
lastUpdate = now;
app.getGraphics()->render(app.getLevel(), app.getShader()); app.getGraphics()->render(app.getLevel(), app.getShader());
openGLCriticalError(); openGLCriticalError();
// MacOS X will not swap correctly is another FBO is bound: // MacOS X will not swap correctly is another FBO is bound:

View File

@ -25,4 +25,5 @@ class Application {
ACGL::OpenGL::SharedShaderProgram shader; ACGL::OpenGL::SharedShaderProgram shader;
}; };
Application app;
#endif #endif

View File

@ -24,9 +24,7 @@ void Object::render() {
shader->setUniform("shininess", material.getShininess()); shader->setUniform("shininess", material.getShininess());
shader->setTexture("uTexture", material.getReference(), 0); shader->setTexture("uTexture", material.getReference(), 0);
// set model matrix // set model matrix
glm::mat4 rotationMatrix = glm::rotate<float>(this->getRotation()[0], glm::vec3(1.0f, 0.0f, 0.0f)) * glm::mat4 modelMatrix = glm::translate(getPosition()) * getRotation() * glm::scale<float>(glm::vec3(model.getScale()));
glm::rotate<float>(this->getRotation()[1], glm::vec3(0.0f, 1.0f, 0.0f)) * glm::rotate<float>(this->getRotation()[2], glm::vec3(0.0f, 0.0f, 1.0f));
glm::mat4 modelMatrix = glm::translate(this->getPosition()) * rotationMatrix * glm::scale<float>(glm::vec3(model.getScale()));
shader->setUniform( "modelMatrix", modelMatrix); shader->setUniform( "modelMatrix", modelMatrix);
// draw // draw
model.getReference()->render(); model.getReference()->render();

View File

@ -1,7 +1,5 @@
#include "physics.hh" #include "physics.hh"
#include <vector>
btDynamicsWorld* world; //contains physical attributes of the world. btDynamicsWorld* world; //contains physical attributes of the world.
btDispatcher* dispatcher; // btDispatcher* dispatcher; //
@ -12,8 +10,16 @@ btConstraintSolver* solver; //solver for forces and impulses.
std::vector<btRigidBody*> bodies; //list of all bodies. bodies are also in world, but save again to ease cleaning up process. std::vector<btRigidBody*> bodies; //list of all bodies. bodies are also in world, but save again to ease cleaning up process.
btRigidBody* playerBall; btRigidBody* playerBall;
btRigidBody* terrainBody; btRigidBody* terrainBody;
btRigidBody* staticGroundBody;
void init()
Physics::Physics() {
}
Physics::~Physics() {
}
void Physics::init()
{ {
colConfig = new btDefaultCollisionConfiguration(); colConfig = new btDefaultCollisionConfiguration();
dispatcher = new btCollisionDispatcher(colConfig); dispatcher = new btCollisionDispatcher(colConfig);
@ -21,17 +27,15 @@ void init()
solver = new btSequentialImpulseConstraintSolver(); solver = new btSequentialImpulseConstraintSolver();
world = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,colConfig); world = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,colConfig);
world->setGravity(btVector3(0,-10,-0)); world->setGravity(btVector3(0,-10,-0));
} }
void takeUpdateStep(float timeDiff) void Physics::takeUpdateStep(float timeDiff)
{ {
world->stepSimulation(timeDiff); world->stepSimulation(timeDiff);
} }
void addTerrain(int width, int length, float** heightData) void Physics::addTerrain(int width, int length, float** heightData)
{ {
float* heightfield = new float[width * length]; float* heightfield = new float[width * length];
int highest = -999999, j = 0, i = 0; int highest = -999999, j = 0, i = 0;
@ -70,7 +74,17 @@ void addTerrain(int width, int length, float** heightData)
} }
void addPlayer(float rad, float x, float y, float z, float mass, unsigned indice) void Physics::addStaticGroundPlane()
{
btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0, 1, 0), 0);
btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 0, 0)));
btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0, groundMotionState, groundShape, btVector3(0, 0, 0));
staticGroundBody = new btRigidBody(groundRigidBodyCI);
world->addRigidBody(staticGroundBody);
}
void Physics::addPlayer(float rad, float x, float y, float z, float mass, unsigned indice)
{ {
if(bodies.size() != indice) if(bodies.size() != indice)
throw std::invalid_argument( "Bodies out of Sync" ); throw std::invalid_argument( "Bodies out of Sync" );
@ -98,7 +112,7 @@ void addPlayer(float rad, float x, float y, float z, float mass, unsigned indice
} }
void addSphere(float rad, float x, float y, float z, float mass, unsigned indice) void Physics::addSphere(float rad, float x, float y, float z, float mass, unsigned indice)
{ {
if(bodies.size() != indice) if(bodies.size() != indice)
throw std::invalid_argument( "Bodies out of Sync" ); throw std::invalid_argument( "Bodies out of Sync" );
@ -126,30 +140,34 @@ void addSphere(float rad, float x, float y, float z, float mass, unsigned indice
} }
glm::vec3 getPos(int i) glm::vec3 Physics::getPos(int i)
{ {
btVector3 origin = bodies[i]->getCenterOfMassPosition(); btVector3 origin = bodies[i]->getCenterOfMassPosition();
glm::vec3 save(origin.getX(),origin.getY(),origin.getZ()); glm::vec3 save(origin.getX(),origin.getY(),origin.getZ());
return save; return save;
} }
glm::mat4 getRotation(int i) glm::mat4 Physics::getRotation(int i)
{ {
btQuaternion quat = bodies[i]->getOrientation(); btQuaternion quat = bodies[i]->getOrientation();
glm::mat4 matrix = glm::rotate( glm::mat4 matrix = glm::rotate(
matrix,
quat.getAngle(), quat.getAngle(),
glm::vec3(quat.getAxis().getX(), quat.getAxis().getY(), quat.getAxis().getZ()) glm::vec3(quat.getAxis().getX(), quat.getAxis().getY(), quat.getAxis().getZ())
); );
return matrix; return matrix;
} }
void rollForward(glm::mat3 rotCamera) void Physics::rollForward(glm::vec3 camPos)
{ {
glm::vec3 saveVector= glm::vec3(1,0,0) * rotCamera; btVector3 pos(camPos.x,camPos.y,camPos.z);
pos -= playerBody->getCenterOfMassPosition();
pos.cross(btVector3(0,1,0));
playerBall->applyTorque(pos);
/* glm::vec3 saveVector= glm::vec3(1,0,0) * rotCamera;
saveVector = glm::cross(glm::vec3(0,1,0),saveVector); saveVector = glm::cross(glm::vec3(0,1,0),saveVector);
playerBall->applyTorque(btVector3(saveVector[0],saveVector[1],saveVector[2])); playerBall->applyTorque(btVector3(saveVector[0],saveVector[1],saveVector[2]));*/
} }
/* /*

View File

@ -11,6 +11,7 @@
#include "extern/bullet/src/BulletCollision/CollisionShapes/btSphereShape.h" #include "extern/bullet/src/BulletCollision/CollisionShapes/btSphereShape.h"
#include "extern/bullet/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h" #include "extern/bullet/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h"
#include "extern/bullet/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h"
#include "extern/bullet/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h" #include "extern/bullet/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h"
#include "extern/bullet/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"//YAY! #include "extern/bullet/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"//YAY!
@ -31,14 +32,15 @@
class Physics { class Physics {
public: public:
Physics(); Physics();
~Physics(); ~Physics();
void init(); void init();
void takeUpdateStep(float timeDiff); void takeUpdateStep(float timeDiff);
void rollForward(glm::vec3 camPos, float strength); void rollForward(glm::vec3 camPos, float strength);
glm::vec3 getPos(int i); glm::vec3 getPos(int i);
glm::mat4 getRotation(int i); glm::mat4 getRotation(int i);
void rollForward(glm::mat3 rotCamera); void rollForward(glm::vec3 camPos);
void addStaticGroundPlane();
void addTerrain(int width, int length, float** heightData); void addTerrain(int width, int length, float** heightData);
void addPlayer(float rad, float x, float y, float z, float mass, unsigned indice); void addPlayer(float rad, float x, float y, float z, float mass, unsigned indice);
void addSphere(float rad, float x, float y, float z, float mass, unsigned indice); void addSphere(float rad, float x, float y, float z, float mass, unsigned indice);
@ -47,6 +49,7 @@ class Physics {
btRigidBody* playerBody; btRigidBody* playerBody;
btRigidBody* terrainBody; btRigidBody* terrainBody;
std::vector<btRigidBody*> bodies; //list of all bodies. bodies are also in world, but save again to ease cleaning up process. std::vector<btRigidBody*> bodies; //list of all bodies. bodies are also in world, but save again to ease cleaning up process.
btRigidBody* staticGroundBody;
btDynamicsWorld* world; //contains physical attributes of the world. btDynamicsWorld* world; //contains physical attributes of the world.

View File

@ -1,4 +1,5 @@
#include "terrain.hh" #include "terrain.hh"
#include "lodepng.h"
Terrain::Terrain(std::string filePath){ Terrain::Terrain(std::string filePath){
this->filePath = filePath; this->filePath = filePath;
@ -12,28 +13,21 @@ Terrain::~Terrain() {
void Terrain::load() { void Terrain::load() {
this->filePath = "../Levels/LevelTest/terrain"; //TODO remove this, its only for testing filePath = "../Levels/LevelTest/terrain/"; //TODO remove this, its only for testing
std::ifstream terrain_png(this->filePath + "/heightmap.png"); std::vector<unsigned char> image; //the raw pixels
unsigned int rowNum, columnNum, heightmapValue; unsigned error = lodepng::decode(image, heightmapWidth, heightmapHeight, filePath + "heightmap.png");
if (error) {
terrain_png.seekg(16); //skip part of the header std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl;
}
char temp[4]; this->heightmap = new float*[this->heightmapHeight]; //initialize the heightmap
terrain_png.read(temp, 4); //read width for(unsigned int rowNum = 0; rowNum < this->heightmapHeight; rowNum++){ //read in the heightmap
this->heightmapWidth = (temp[3]<<0) | (temp[2]<<8) | (temp[1]<<16) | (temp[0]<<24); //convert from network to host byte order this->heightmap[rowNum] = new float[this->heightmapWidth];
terrain_png.read(temp, 4); //read height for(unsigned int columnNum = 0; columnNum < this->heightmapWidth; columnNum++){
this->heightmapHeight = (temp[3]<<0) | (temp[2]<<8) | (temp[1]<<16) | (temp[0]<<24); //convert from network to host byte order this->heightmap[rowNum][columnNum] = (float)(image[(rowNum*heightmapWidth+columnNum)*4]) / 32;
heightmap = new float*[this->heightmapHeight]; //initialize the heightmap
for(rowNum = 0; rowNum < this->heightmapHeight; rowNum++){ //read in the heightmap
heightmap[rowNum] = new float[this->heightmapWidth];
for(columnNum = 0; columnNum < this->heightmapWidth; columnNum++){
terrain_png.read((char *)&heightmapValue, 1);
heightmap[rowNum][columnNum] = (float)heightmapValue / 256;
} }
} }
this->makeTriangleMesh(); this->makeTriangleMesh();
heightmapChanged = false; //no need to make a TriangleMesh again before rendering heightmapChanged = false; //no need to make a TriangleMesh again before rendering
@ -42,48 +36,53 @@ void Terrain::load() {
void Terrain::makeTriangleMesh(){ void Terrain::makeTriangleMesh(){
ACGL::OpenGL::SharedArrayBuffer ab = std::make_shared<ACGL::OpenGL::ArrayBuffer>(); ACGL::OpenGL::SharedArrayBuffer ab = std::make_shared<ACGL::OpenGL::ArrayBuffer>();
ab->defineAttribute("aPosition", GL_FLOAT, 3); //TODO: ArrayBuffer for the texture coordinates // Do NOT change the order of this!
ab->defineAttribute("aNormal", GL_FLOAT, 3); ab->defineAttribute("aPosition", GL_FLOAT, 3);
ab->defineAttribute("aTexCoord", GL_FLOAT, 2); ab->defineAttribute("aTexCoord", GL_FLOAT, 2);
ab->defineAttribute("aNormal", GL_FLOAT, 3);
unsigned int rowNum=0, columnNum=0, dataCount=0, abNumFloats=8; //initializing: unsigned int rowNum=0, columnNum=0, dataCount=0, abNumFloats=8; //initializing:
bool movingRight = true, isUp = true; bool movingRight = true, isUp = true;
int numVertices = (this->heightmapHeight - 1) * (this->heightmapWidth * 2 + 1) + 1; int numVertices = (this->heightmapHeight - 1) * (this->heightmapWidth * 2 + 1) + 1;
float* abData = new float[numVertices * abNumFloats]; float* abData = new float[numVertices * floatsPerVertex];
while(rowNum < this->heightmapHeight){ //traversing the Triangle Strip! while(rowNum < this->heightmapHeight){ //traversing the Triangle Strip!
set_abData(abData, dataCount, rowNum, columnNum); set_abData(abData, dataCount, rowNum, columnNum);
dataCount += abNumFloats; dataCount += floatsPerVertex;
if (isUp){ if (isUp){
rowNum = rowNum + 1; rowNum = rowNum + 1;
isUp = false; isUp = false;
}else if (movingRight){
if (columnNum == this->heightmapWidth - 1){
set_abData(abData, dataCount, rowNum, columnNum);
dataCount += abNumFloats;
set_abData(abData, dataCount, rowNum, columnNum);
dataCount += abNumFloats;
movingRight = false;
rowNum = rowNum + 1;
} else{
rowNum = rowNum - 1;
columnNum = columnNum + 1;
isUp = true;
}
}else{
if (columnNum == 0){
set_abData(abData, dataCount, rowNum, columnNum);
dataCount += abNumFloats;
set_abData(abData, dataCount, rowNum, columnNum);
dataCount += abNumFloats;
movingRight = true;
rowNum = rowNum + 1;
}else{
rowNum = rowNum - 1;
columnNum = columnNum - 1;
isUp = true;
}
} }
else if (movingRight) {
if (columnNum == this->heightmapWidth - 1) {
set_abData(abData, dataCount, rowNum, columnNum);
dataCount += abNumFloats;
set_abData(abData, dataCount, rowNum, columnNum);
dataCount += abNumFloats;
movingRight = false;
rowNum = rowNum + 1;
}
else {
rowNum = rowNum - 1;
columnNum = columnNum + 1;
isUp = true;
}
}
else {
if (columnNum == 0){
set_abData(abData, dataCount, rowNum, columnNum);
dataCount += abNumFloats;
set_abData(abData, dataCount, rowNum, columnNum);
dataCount += abNumFloats;
movingRight = true;
rowNum = rowNum + 1;
}
else {
rowNum = rowNum - 1;
columnNum = columnNum - 1;
isUp = true;
}
}
} }
ab->setDataElements(numVertices, abData); ab->setDataElements(numVertices, abData);
@ -101,33 +100,34 @@ void Terrain::set_abData(float* abData, unsigned int dataCount, unsigned int row
abData[dataCount+1] = heightmap[rowNum][columnNum]; abData[dataCount+1] = heightmap[rowNum][columnNum];
abData[dataCount+2] = (float)columnNum; abData[dataCount+2] = (float)columnNum;
//set Texture Coordinate
abData[dataCount+3] = (float)(rowNum % 2);
abData[dataCount+4] = (float)(columnNum % 2);
//setNormal //setNormal
if (rowNum==0 || rowNum==(this->heightmapHeight-1) || columnNum==0 || columnNum==(this->heightmapWidth-1)){ if (rowNum==0 || rowNum==(this->heightmapHeight-1) || columnNum==0 || columnNum==(this->heightmapWidth-1)){
abData[dataCount+3] = 0.0;
abData[dataCount+4] = 1.0;
abData[dataCount+5] = 0.0; abData[dataCount+5] = 0.0;
}else{ abData[dataCount+6] = 1.0;
glm::vec3 sumNormals; abData[dataCount+7] = 0.0;
for (int i=-1; i<2; i+=1){ }
for (int j=-1; j<2; j+=1){ else {
glm::vec3 vecA, vecB, normal; glm::vec3 sumNormals = glm::vec3(0.0f, 0.0f, 0.0f);
vecA = glm::vec3((float)i, (heightmap[rowNum+i][columnNum] - heightmap[rowNum][columnNum]), 0.0f); for (int i=-1; i<2; i+=2) {
vecB = glm::vec3(0.0f, (heightmap[rowNum][columnNum+j] - heightmap[rowNum][columnNum]), (float)j); for (int j=-1; j<2; j+=2) {
normal = glm::normalize(glm::cross(vecA, vecB)); glm::vec3 vecA, vecB, normal;
if(i+j==0) vecA = glm::vec3((float)i, (heightmap[rowNum+i][columnNum] - heightmap[rowNum][columnNum]), 0.0f);
normal = normal*(-1.0f); vecB = glm::vec3(0.0f, (heightmap[rowNum][columnNum+j] - heightmap[rowNum][columnNum]), (float)j);
sumNormals += normal; normal = glm::normalize(glm::cross(vecA, vecB));
} if(i+j!=0)
} normal = normal*(-1.0f);
sumNormals = sumNormals*0.111f; sumNormals += normal;
abData[dataCount+3] = sumNormals[0]; }
abData[dataCount+4] = sumNormals[1]; }
abData[dataCount+5] = sumNormals[2]; sumNormals = glm::normalize(sumNormals);
abData[dataCount+5] = sumNormals[0];
abData[dataCount+6] = sumNormals[1];
abData[dataCount+7] = sumNormals[2];
} }
//set Texture Coordinate
abData[dataCount+6] = (float)(rowNum % 2);
abData[dataCount+7] = (float)(columnNum % 2);
} }
Model Terrain::getModel(){ Model Terrain::getModel(){
@ -145,14 +145,3 @@ unsigned int Terrain::getHeightmapHeight(){
unsigned int Terrain::getHeightmapWidth(){ unsigned int Terrain::getHeightmapWidth(){
return this->heightmapWidth; return this->heightmapWidth;
} }

View File

@ -3,7 +3,6 @@
#include <string> #include <string>
#include "material.hh" #include "material.hh"
#include <fstream>
#include <ACGL/OpenGL/Objects/VertexArrayObject.hh> #include <ACGL/OpenGL/Objects/VertexArrayObject.hh>
#include "model.hh" #include "model.hh"
class Terrain { class Terrain {