diff --git a/application.cc b/application.cc index 6e263e8..b16e9c0 100644 --- a/application.cc +++ b/application.cc @@ -27,14 +27,14 @@ void Application::init() ACGL::Base::Settings::the()->setShaderPath(shaderPath); ACGL::Base::Settings::the()->setTexturePath(texturePath); ACGL::Base::Settings::the()->setGeometryPath(geometryPath); - + // load Level level.load(); Loader loader = Loader(); std::string levelXmlFilePath = levelXmlPath + "Level1.xml"; loader.load(levelXmlFilePath, &level, compositionsPath, scriptPath); graphics.init(&level); - + // just in case: check for errors openGLCriticalError(); } diff --git a/converter/converter.hh b/converter/converter.hh index 318f944..33cb71a 100644 --- a/converter/converter.hh +++ b/converter/converter.hh @@ -13,9 +13,8 @@ class Converter { ~Converter(); void updateComposition(int idG, int idB, float posX, float posZ); //updates the position of a composition std::vector newComposition(int type, float posX, float posZ);//creates a new composition and returns its ID - void deleteComposition(int idG, int idB); - void save(); //writes the xml to file - + void deleteComposition(int idG, int idB); + void save(); //writes the xml to file private: void errorCheck(XMLError error); std::vector nextID; diff --git a/entity.hh b/entity.hh index c712644..252a978 100644 --- a/entity.hh +++ b/entity.hh @@ -7,7 +7,7 @@ class Entity { public: Entity(glm::vec3 position, glm::vec3 rotation); Entity(glm::vec3 position, glm::mat4 rotation); - Entity(); + Entity(); ~Entity(); void setPosition(glm::vec3 positon); void setRotation(glm::vec3 rotation); diff --git a/graphics.cc b/graphics.cc index 6f61565..d51ecb6 100644 --- a/graphics.cc +++ b/graphics.cc @@ -22,10 +22,10 @@ Graphics::Graphics() { void Graphics::init(Level* level) { // save Level this->level = level; - + // update lights on creation lastUpdate = -lightUpdateDelay; - + // construct VAO to give shader correct Attribute locations SharedArrayBuffer ab = SharedArrayBuffer(new ArrayBuffer()); ab->defineAttribute("aPosition", GL_FLOAT, 3); @@ -33,25 +33,25 @@ void Graphics::init(Level* level) { ab->defineAttribute("aNormal", GL_FLOAT, 3); SharedVertexArrayObject vao = SharedVertexArrayObject(new VertexArrayObject()); vao->attachAllAttributes(ab); - + // look up all shader files starting with 'phong' and build a ShaderProgram from it: lightingShader = ShaderProgramCreator("phong").attributeLocations( vao->getAttributeLocations()).create(); - + depthShader = ShaderProgramCreator("depth") .attributeLocations(vao->getAttributeLocations()).create(); - + depthTexture = SharedTexture2D( new Texture2D(windowSize, GL_DEPTH_COMPONENT16)); depthTexture->setMinFilter(GL_NEAREST); depthTexture->setMagFilter(GL_NEAREST); depthTexture->setWrapS(GL_CLAMP_TO_EDGE); depthTexture->setWrapT(GL_CLAMP_TO_EDGE); depthTexture->setCompareMode(GL_COMPARE_REF_TO_TEXTURE); - + framebuffer = SharedFrameBufferObject(new FrameBufferObject()); framebuffer->setDepthTexture(depthTexture); framebuffer->validate(); - + /*depth_cubeMaps = std::vector(level->getLights()->size()); for (unsigned int i = 0; i(std::min(int(level->getLights()->size()), 1)); @@ -63,9 +63,9 @@ void Graphics::init(Level* level) { depth_cubeMaps.at(i)->setWrapT(GL_CLAMP_TO_EDGE); depth_cubeMaps.at(i)->setCompareMode(GL_COMPARE_REF_TO_TEXTURE); } - + framebuffer_cube = SharedFrameBufferObject(new FrameBufferObject()); - + depthTexture_cube = SharedTexture2D( new Texture2D(windowSize, GL_DEPTH_COMPONENT16)); depthTexture_cube->setMinFilter(GL_NEAREST); depthTexture_cube->setMagFilter(GL_NEAREST); @@ -87,7 +87,7 @@ void Graphics::render(double time) glm::mat4 depthProjectionMatrix_pointlights = glm::perspective(1.571f, (float)cube_size/(float)cube_size, 0.1f, farPlane); glm::vec3 looking_directions[6] = {glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 0.0f, -1.0f)}; - + framebuffer_cube->bind(); //for (unsigned int i_pointlight = 0; i_pointlightgetLights()->size(); i_pointlight++) { for (unsigned int i_pointlight = 0; i_pointlight<1 && i_pointlightgetLights()->size(); i_pointlight++) { @@ -116,19 +116,19 @@ void Graphics::render(double time) if (!framebuffer->isFrameBufferObjectComplete()) { printf("Framebuffer incomplete, unknown error occured during shadow generation!\n"); } - + // final render pass glBindFramebuffer(GL_FRAMEBUFFER, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - + lightingShader->use(); - + if (level->getLights()->size() > 0) { lightingShader->setTexture("shadowMap_cube", depth_cubeMaps.at(0), 4); } - + //set lighting parameters - + // TODO look into doing this less often, offload to another thread? // TODO figure out how to deal with bigger numbers of lights. load the nearest on demand? double nextUpdate = lastUpdate + lightUpdateDelay; @@ -137,7 +137,7 @@ void Graphics::render(double time) updateLights(); lastUpdate = time; } - + // convert texture to homogenouse coordinates glm::mat4 biasMatrix( 0.5, 0.0, 0.0, 0.0, @@ -146,25 +146,25 @@ void Graphics::render(double time) 0.5, 0.5, 0.5, 1.0 ); glm::mat4 depthBiasVP = biasMatrix*depthViewProjectionMatrix; - + lightingShader->setTexture("shadowMap", depthTexture, 1); - + lightingShader->setUniform("farPlane", farPlane); - + // set fog Parameters lightingShader->setUniform("fogColor", level->getFogColour()); lightingShader->setUniform("cameraCenter", level->getCameraCenter()->getPosition()); - + // set Material Parameters lightingShader->setUniform("ambientColor", level->getAmbientLight()); lightingShader->setUniform("camera", level->getCameraPosition()); - + //set view and projection matrix glm::mat4 lightingViewProjectionMatrix = glm::perspective(1.571f, (float)windowSize.x/(float)windowSize.y, 0.1f, farPlane) * buildViewMatrix(level); - + std::vector shadowVPs = std::vector(); shadowVPs.push_back(depthBiasVP); - + // render the level level->render(lightingShader, true, &lightingViewProjectionMatrix, &shadowVPs); } @@ -172,7 +172,7 @@ void Graphics::render(double time) void Graphics::updateLights() { if (level->getLights()->size() > 0) { lightingShader->setUniform("lightCount", (int) level->getLights()->size()); - + // Build light position array glm::vec3 lightSources[level->getLights()->size()]; for(unsigned int i = 0; igetLights()->size(); i++) { @@ -217,7 +217,6 @@ glm::mat4 Graphics::buildViewMatrix(Level* level) { return glm::lookAt((level->getCameraCenter()->getPosition() + level->getCamera()->getVector()), level->getCameraCenter()->getPosition(), glm::vec3(0.0f, 1.0f, 0.0f)); - } float Graphics::getFarPlane() { diff --git a/level.cc b/level.cc index e2c81b1..bafb957 100644 --- a/level.cc +++ b/level.cc @@ -40,7 +40,7 @@ void Level::load() { //Push the level to Lua as a global variable luabridge::push(luaState, this); lua_setglobal(luaState, "level"); - + this->camera = Camera(glm::vec2(-0.8f, 0.0f), 3.0f); } @@ -68,7 +68,7 @@ void Level::update(float runTime, glm::vec2 mouseDelta, bool wPressed, bool aPre camera.setPosition(physics.getCameraPosition()); camera.setDirection(physics.getCameraToPlayer()); - } + } if(wPressed){ physics.rollForward(camera.getVector(),strength); } @@ -149,7 +149,7 @@ void Level::moveObject(int objectIndex, float strength, float xPos, float yPos, glm::vec3 position = glm::vec3(xPos, yPos, zPos); physics.removePositionConstraint(objectIndex); physics.addPositionConstraint(objectIndex, strength, position); -} +} //should not be used since objects does not get synchronized and deletion is not implemented in pyhsics void Level::deleteObject(int objectIndex){ diff --git a/loader.cc b/loader.cc index b33c130..2c49802 100644 --- a/loader.cc +++ b/loader.cc @@ -20,35 +20,35 @@ void Loader::loadConfig(Application* application) { errorCheck(resolution->FirstChildElement("height")->QueryIntText(&windowHeight)); errorCheck(config->FirstChildElement("shadowCubeSize")->QueryIntText(&shadowCubeSize)); errorCheck(config->FirstChildElement("farPlane")->QueryFloatText(&farPlane)); - + const char* charCompositionsPath = config->FirstChildElement("compositionsPath")->GetText(); if(charCompositionsPath == NULL){ printf("XMLError: No compositionsPath found.\n"); exit(-1); } compositionsPath = charCompositionsPath; - + const char* charShaderPath = config->FirstChildElement("shaderPath")->GetText(); if(charShaderPath == NULL){ printf("XMLError: No shaderPath found.\n"); exit(-1); } shaderPath = charShaderPath; - + const char* charGeometryPath = config->FirstChildElement("geometryPath")->GetText(); if(charGeometryPath == NULL){ printf("XMLError: No geometryPath found.\n"); exit(-1); } geometryPath = charGeometryPath; - + const char* charTexturePath = config->FirstChildElement("texturePath")->GetText(); if(charTexturePath == NULL){ printf("XMLError: No texturePath found.\n"); exit(-1); } texturePath = charTexturePath; - + const char* charScriptPath = config->FirstChildElement("scriptPath")->GetText(); if(charScriptPath == NULL){ printf("XMLError: No scriptPath found.\n"); @@ -62,7 +62,7 @@ void Loader::loadConfig(Application* application) { exit(-1); } heightmapPath = charHeightmapPath; - + const char* charLevelXmlPath = config->FirstChildElement("levelXmlPath")->GetText(); if(charLevelXmlPath == NULL){ printf("XMLError: No levelXmlPath found.\n"); @@ -116,11 +116,11 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa errorCheck(terrainElement->FirstChildElement("shininess")->QueryFloatText(&terrainShininess)); Material terrainMaterial = Material(terrainTexture, terrainAmbientFactor, terrainDiffuseFactor, terrainSpecularFactor, terrainShininess); Object* terrainObject = new Object(terrainModel, terrainMaterial, - glm::vec3(-0.5*(float)level->getTerrain()->getHeightmapHeight(), 0.0f, -0.5f*(float)level->getTerrain()->getHeightmapWidth()), + glm::vec3(-0.5*(float)level->getTerrain()->getHeightmapHeight(), 0.0f, -0.5f*(float)level->getTerrain()->getHeightmapWidth()), glm::vec3(0.0f, 0.0f, 0.0f), true); level->addObject(terrainObject); - level->getPhysics()->addTerrain(level->getTerrain()->getHeightmapWidth(), level->getTerrain()->getHeightmapHeight(), level->getTerrain()->getHeightmap()); - + level->getPhysics()->addTerrain(level->getTerrain()->getHeightmapWidth(), level->getTerrain()->getHeightmapHeight(), level->getTerrain()->getHeightmap()); + //load the skydome XMLElement* skydomeElement = doc->FirstChildElement("skydome"); const char* charSkydomeTexture = skydomeElement->FirstChildElement("texture")->GetText(); @@ -135,7 +135,7 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa glm::vec3(0.0f, 0.0f, 0.0f), true); level->addObject(skydomeObject); level->setSkydomeObject(skydomeObject); - + //load lighting parameters float rColour, gColour, bColour, alpha, xOffset, yOffset, zOffset, intensity; XMLElement* ambientElement = doc->FirstChildElement("ambientLight"); @@ -143,14 +143,14 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa errorCheck(ambientElement->FirstChildElement("gColour")->QueryFloatText(&gColour)); errorCheck(ambientElement->FirstChildElement("bColour")->QueryFloatText(&bColour)); level->setAmbientLight(glm::vec3(rColour,gColour,bColour)); - + XMLElement* fogElement = doc->FirstChildElement("fogColour"); errorCheck(fogElement->FirstChildElement("rColour")->QueryFloatText(&rColour)); errorCheck(fogElement->FirstChildElement("gColour")->QueryFloatText(&gColour)); errorCheck(fogElement->FirstChildElement("bColour")->QueryFloatText(&bColour)); errorCheck(fogElement->FirstChildElement("alpha")->QueryFloatText(&alpha)); level->setFogColour(glm::vec4(rColour,gColour,bColour, alpha)); - + XMLElement* directionalElement = doc->FirstChildElement("directionalLight"); errorCheck(directionalElement->FirstChildElement("xOffset")->QueryFloatText(&xOffset)); errorCheck(directionalElement->FirstChildElement("yOffset")->QueryFloatText(&yOffset)); @@ -160,7 +160,7 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa errorCheck(directionalElement->FirstChildElement("bColour")->QueryFloatText(&bColour)); errorCheck(directionalElement->FirstChildElement("intensity")->QueryFloatText(&intensity)); level->setDirectionalLight(Light(glm::vec3(xOffset,yOffset,zOffset), glm::vec3(rColour,gColour,bColour), intensity)); - + //load Objects std::vector> objectIdentifiers = std::vector>(); //The first entry is the index in objects, the second one the index in physicObjects, the others are idGreen, idBlue and objectNum. XMLDocument* compositions = new XMLDocument(); @@ -259,7 +259,7 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa objectRot *= 0.0174532925; //transform degrees to radians Object* object = new Object(model, material, objectPosition, compRot+objectRot, renderable); level->addObject(object); - + //add object to physics const char* charPhysicType = objectData->FirstChildElement("physicType")->GetText(); if(charPhysicType == NULL){ @@ -315,7 +315,7 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa printf("XMLError: Not a valid physicType.\n"); exit(-1); } - + //create an identifier for this object std::vector objectIdentifier = std::vector(5); objectIdentifier[0] = level->getObjectsVectorSize()-1; @@ -340,7 +340,7 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa objectNum = objectNum + 1; }//iterating over all objects of the composition - + //iterate over all lights of the composition XMLElement* xmlLight = composition->FirstChildElement("light"); for(; xmlLight; xmlLight=xmlLight->NextSiblingElement("light")){ diff --git a/main.cc b/main.cc index c639348..2cfb0a5 100644 --- a/main.cc +++ b/main.cc @@ -76,19 +76,19 @@ bool createWindow() ACGL::Utils::error() << "Failed to initialize GLFW" << std::endl; exit( -1 ); } - + // Configure OpenGL context setGLFWHintsForOpenGLVersion( ACGL_OPENGL_VERSION ); - + // activate multisampling (second parameter is the number of samples): //glfwWindowHint( GLFW_SAMPLES, 8 ); - + // request an OpenGL debug context: glfwWindowHint( GLFW_OPENGL_DEBUG_CONTEXT, true ); - + // define whether the window can get resized: glfwWindowHint(GLFW_RESIZABLE, true); - + // try to create an OpenGL context in a window and check the supported OpenGL version: // R,G,B,A, Depth,Stencil window = glfwCreateWindow(app.getGraphics()->getWindowSize().x, app.getGraphics()->getWindowSize().y, "SWP MarbleGame Group C", NULL, NULL); @@ -104,13 +104,13 @@ bool createWindow() int main( int argc, char *argv[] ) { // app gets created as global variable, to work properly with GLFW - + // Create OpenGL capable window: if ( !createWindow() ) { glfwTerminate(); exit( -1 ); } - + // Set window title to binary name (without the path): std::vector tmp = ACGL::Utils::StringHelpers::split( std::string( argv[0] ), '/' ); glfwSetWindowTitle(window, tmp[tmp.size()-1].c_str() ); @@ -122,10 +122,10 @@ int main( int argc, char *argv[] ) glfwSetScrollCallback(window, scrollCallback ); glfwSetWindowFocusCallback(window, focusCallback); glfwSetMouseButtonCallback(window, mouseCallback); - + // Enable vertical sync (on cards that support it) with parameter 1 - 0 means off glfwSwapInterval( 0 ); - + // OpenGL state: glClearColor( 0.0, 0.0, 0.0, 1.0 ); glEnable( GL_DEPTH_TEST ); @@ -133,20 +133,19 @@ int main( int argc, char *argv[] ) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); app.init(); - + int frameCount = 0; - + const double FPSdelay = 2.0; double startTimeInSeconds = glfwGetTime(); double showNextFPS = startTimeInSeconds + FPSdelay; double lastUpdate=0.0f; - - - do { - - double now = glfwGetTime()- startTimeInSeconds; + do { + + double now = glfwGetTime()- startTimeInSeconds; + if (showNextFPS <= now) { std::stringstream sstream (std::stringstream::in | std::stringstream::out); sstream << std::setprecision(1) << std::fixed @@ -155,8 +154,8 @@ int main( int argc, char *argv[] ) showNextFPS = now + FPSdelay; frameCount = 0; } - - + + if (app.isLocked() && app.getIgnoredMouseUpdates() == 0) { int stateW = glfwGetKey(window, GLFW_KEY_W); int stateA = glfwGetKey(window, GLFW_KEY_A); @@ -176,12 +175,12 @@ int main( int argc, char *argv[] ) app.ignoredOneMouseUpdate(); } } - + app.getGraphics()->render(now); lastUpdate = now; openGLCriticalError(); - + // MacOS X will not swap correctly is another FBO is bound: glBindFramebuffer( GL_FRAMEBUFFER, 0 ); glfwSwapBuffers(window); @@ -190,7 +189,7 @@ int main( int argc, char *argv[] ) } // Check if the window was closed while( !glfwWindowShouldClose(window) ); - + glfwTerminate(); exit(0); } diff --git a/material.hh b/material.hh index 5c80b73..c151568 100644 --- a/material.hh +++ b/material.hh @@ -10,7 +10,7 @@ class Material{ public: Material(std::string filePath, float ambientFactor, float diffuseFactor, float specularFactor, float shininess); - Material(); + Material(); ACGL::OpenGL::SharedTexture2D getReference(); ~Material(); float getAmbientFactor(); diff --git a/model.hh b/model.hh index e73c4e9..3f38d09 100644 --- a/model.hh +++ b/model.hh @@ -7,8 +7,8 @@ class Model { public: Model(std::string filePath, float scale=1.0f); - Model(ACGL::OpenGL::SharedVertexArrayObject vao, float scale=1.0f); - Model(); + Model(ACGL::OpenGL::SharedVertexArrayObject vao, float scale=1.0f); + Model(); ~Model(); ACGL::OpenGL::SharedVertexArrayObject getReference(); void setScale(float scale); diff --git a/physics.cc b/physics.cc index 05d1e5b..dc665f9 100644 --- a/physics.cc +++ b/physics.cc @@ -10,11 +10,11 @@ Physics::~Physics() { void Physics::init(std::string geometryPath) //prepares bullet by creating all initial classes { - colConfig = new btDefaultCollisionConfiguration(); - dispatcher = new btCollisionDispatcher(colConfig); - broadphase = new btDbvtBroadphase(); - solver = new btSequentialImpulseConstraintSolver(); - world = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,colConfig); + colConfig = new btDefaultCollisionConfiguration(); + dispatcher = new btCollisionDispatcher(colConfig); + broadphase = new btDbvtBroadphase(); + solver = new btSequentialImpulseConstraintSolver(); + world = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,colConfig); world->setGravity(btVector3(0,-10,-0)); if (world == NULL) { printf("No World after init\n"); @@ -23,24 +23,23 @@ void Physics::init(std::string geometryPath) //prepares bullet by creating all i } void Physics::takeUpdateStep(float timeDiff) -{ - - counter++; - if(counter<1) - { - world->stepSimulation(timeDiff);//allows the world to be simmulated correctly indipendant of the timedifferences between frames - return; - } - - for(unsigned i = 0; i < allPositionConstraints.size();i++) //this handles the spring constraints - { - if(allPositionConstraints[i].position != allPositionConstraints[i].body->getCenterOfMassPosition()) //if constraint != position of the body because otherwise dir = 0 - { - btVector3 dir = allPositionConstraints[i].position - allPositionConstraints[i].body->getCenterOfMassPosition(); - dir = dir*allPositionConstraints[i].strength - allPositionConstraints[i].body->getLinearVelocity(); - allPositionConstraints[i].body->applyCentralForce(dir*allPositionConstraints[i].strength); //apply a foce upon the object pushing it towards the constraint position - } - } +{ + counter++; + if(counter<1) + { + world->stepSimulation(timeDiff); //allows the world to be simmulated correctly indipendant of the timedifferences between frames + return; + } + + for(unsigned i = 0; i < allPositionConstraints.size();i++) //this handles the spring constraints + { + if(allPositionConstraints[i].position != allPositionConstraints[i].body->getCenterOfMassPosition()) //if constraint != position of the body because otherwise dir = 0 + { + btVector3 dir = allPositionConstraints[i].position - allPositionConstraints[i].body->getCenterOfMassPosition(); + dir = dir*allPositionConstraints[i].strength - allPositionConstraints[i].body->getLinearVelocity(); + allPositionConstraints[i].body->applyCentralForce(dir*allPositionConstraints[i].strength); //apply a foce upon the object pushing it towards the constraint position + } + } btVector3 position = cameraBody->getCenterOfMassPosition() - playerBall->getCenterOfMassPosition(); //gets a vector from the player to the camera @@ -50,32 +49,32 @@ void Physics::takeUpdateStep(float timeDiff) //prevent the camera from being dragged along on the ground if (position.getY() < playerBall->getCenterOfMassPosition().getY() + 1) - position.setY(playerBall->getCenterOfMassPosition().getY() + 1); + position.setY(playerBall->getCenterOfMassPosition().getY() + 1); - btVector3 dir = cameraBody->getCenterOfMassPosition() - position; - float str = 50 * dir.length() / cameraBody->getInvMass(); - cameraBody->applyCentralForce(-dir*str);//scale the force by camera mass - counter=0; - float speed = cameraBody->getLinearVelocity().length(); - if(speed>20.0f) - { - printf("%f , %f \n", speed, position.length()); - position = cameraBody->getLinearVelocity(); - position.normalize(); - cameraBody->setLinearVelocity(position*20); - } - world->stepSimulation(timeDiff); + btVector3 dir = cameraBody->getCenterOfMassPosition() - position; + float str = 50 * dir.length() / cameraBody->getInvMass(); //getInvMass() returns the inverted mass + cameraBody->applyCentralForce(-dir*str); //scale the force by camera mass + counter=0; + float speed = cameraBody->getLinearVelocity().length(); + if(speed>20.0f) + { + printf("%f , %f \n", speed, position.length()); + position = cameraBody->getLinearVelocity(); + position.normalize(); + cameraBody->setLinearVelocity(position*20); + } + world->stepSimulation(timeDiff); } -// + void Physics::removePositionConstraint(int bodyIndice) //remover function for deleting all pos constraints on one body { - for(unsigned i = 0; i < allPositionConstraints.size(); i++) - { - if(allPositionConstraints[i].body == bodies[bodyIndice]) - { - allPositionConstraints.erase(allPositionConstraints.begin()+i); - } - } + for(unsigned i = 0; i < allPositionConstraints.size(); i++) + { + if(allPositionConstraints[i].body == bodies[bodyIndice]) + { + allPositionConstraints.erase(allPositionConstraints.begin()+i); + } + } } void Physics::addPositionConstraint(int bodyIndice, float strength, glm::vec3 position) //function for adding position constraints @@ -85,83 +84,83 @@ void Physics::addPositionConstraint(int bodyIndice, float strength, glm::vec3 po cons.strength = strength; cons.position = btVector3(position.x,position.y,position.z); allPositionConstraints.push_back(cons); -} +} //players and objects void Physics::addPlayer(float friction, float rad, Entity entity, float mass, float dampningL, float dampningA, unsigned indice) { - if(bodies.size() == indice) - throw std::invalid_argument( "Bodies out of Sync" ); //these error are to ensure that level can always communicate with physics without having to worry about synching errors - - btSphereShape* sphere = new btSphereShape(rad); //the first thing we need for a rigid body is the shape - btVector3 inertia(0,0,0); - if(mass != 0.0) - { - sphere->calculateLocalInertia((btScalar)mass,inertia); //from this shape we can then calculate the innertia, as long as the mass != 0 (otherwise inertia = 0) - } - - glm::quat glmQuat = glm::quat_cast(entity.getRotation()); - - btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(glmQuat.x,glmQuat.y,glmQuat.z,glmQuat.w),btVector3(entity.getPosition().x,entity.getPosition().y,entity.getPosition().z))); //next we define the motionstate, wich describes the innital position and rotation - - btRigidBody::btRigidBodyConstructionInfo info(mass,motion,sphere,inertia); //next we process all data for the rigid body into info - + if(bodies.size() == indice) + throw std::invalid_argument( "Bodies out of Sync" ); //these error are to ensure that level can always communicate with physics without having to worry about synching errors + + btSphereShape* sphere = new btSphereShape(rad); //the first thing we need for a rigid body is the shape + btVector3 inertia(0,0,0); + if(mass != 0.0) + { + sphere->calculateLocalInertia((btScalar)mass,inertia); //from this shape we can then calculate the innertia, as long as the mass != 0 (otherwise inertia = 0) + } + + glm::quat glmQuat = glm::quat_cast(entity.getRotation()); + + btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(glmQuat.x,glmQuat.y,glmQuat.z,glmQuat.w),btVector3(entity.getPosition().x,entity.getPosition().y,entity.getPosition().z))); //next we define the motionstate, wich describes the innital position and rotation + + btRigidBody::btRigidBodyConstructionInfo info(mass,motion,sphere,inertia); //next we process all data for the rigid body into info + info.m_friction = friction*2; //here we modify the friction and restitution (bounciness) of the object info.m_restitution = 0.1f; - - playerBall = new btRigidBody(info); //finally we create the rigid body using the info + + playerBall = new btRigidBody(info); //finally we create the rigid body using the info playerBall->setDamping(dampningL, dampningA); //here we can set the dampning (how much of the motion is lost) - world->addRigidBody(playerBall,COL_OBJECTS,COL_OBJECTS|COL_OBJECTS_NO_TERRAIN|COL_TERRAIN); //then we add the rigid body to the wiorld, allowing it to be simulated + world->addRigidBody(playerBall,COL_OBJECTS,COL_OBJECTS|COL_OBJECTS_NO_TERRAIN|COL_TERRAIN); //then we add the rigid body to the wiorld, allowing it to be simulated - bodies.push_back(playerBall); //next we add the rigid body to our own list (for cleanup and for synchronitaation with level) + bodies.push_back(playerBall); //next we add the rigid body to our own list (for cleanup and for synchronitaation with level) //note, while we can always access playerBall through its global name, we add it to this array for synchronization purposes playerBall->setSleepingThresholds(0,0); //in a final step we make sure that the body never is removed from the active rigid bodies - if(bodies.size() != indice) - throw std::invalid_argument( "Bodies out of Sync" ); //one last check to make sure level and physics are in synch + if(bodies.size() != indice) + throw std::invalid_argument( "Bodies out of Sync" ); //one last check to make sure level and physics are in synch addCamera(); //now that the player exists add a camera for the player } void Physics::addTerrain(int width, int length, float** heightData) //The terrain adding function { - float* heightfield = new float[width * length];//bullet only accepts data in a one dimensional array, so parse data into appropriate format + float* heightfield = new float[width * length]; //bullet only accepts data in a one dimensional array, so parse data into appropriate format int highest = -999999, j = 0, i = 0; for (i = 0; i < width; i++) { for (j = 0; j < length; j++) { heightfield[i*length+j] = heightData[j][i]; //reverse order because they are loaded backwards - + if (heightData[j][i] > highest) - highest = heightData[j][i]; //bullet needs to know the highest point of the heightmap + highest = heightData[j][i]; //bullet needs to know the highest point of the heightmap } } highest++; - - btHeightfieldTerrainShape* terrainShape = new btHeightfieldTerrainShape(length,width,heightfield,highest,1,true,false); - btRigidBody::btRigidBodyConstructionInfo info(0,new btDefaultMotionState(),terrainShape,btVector3(0,0,0)); //next we process all data for the rigid body into info - info.m_friction = 1; + + btHeightfieldTerrainShape* terrainShape = new btHeightfieldTerrainShape(length,width,heightfield,highest,1,true,false); + btRigidBody::btRigidBodyConstructionInfo info(0,new btDefaultMotionState(),terrainShape,btVector3(0,0,0)); //next we process all data for the rigid body into info + info.m_friction = 1; info.m_restitution = 0; - btRigidBody* tBody = new btRigidBody(info); - - tBody->getWorldTransform().setOrigin(btVector3(0,((float)highest)/2,0)); //we have to move the origin of our rigid body down, because bullet sets the origin (0,0,0) at (width/2, height/2, length/2) in the map the x and z are correct in our level, but y needs to be addapted - - terrainBody = tBody; + btRigidBody* tBody = new btRigidBody(info); + + tBody->getWorldTransform().setOrigin(btVector3(0,((float)highest)/2,0)); //we have to move the origin of our rigid body down, because bullet sets the origin (0,0,0) at (width/2, height/2, length/2) in the map the x and z are correct in our level, but y needs to be addapted + + terrainBody = tBody; if (world == NULL) { printf("No World while adding terrain.\n"); } - world->addRigidBody(terrainBody, COL_TERRAIN, COL_TERRAIN | COL_OBJECTS); //COL_XXXX are collision masks, allowing us to ignore collisions between certain object groups (required for buttons) + world->addRigidBody(terrainBody, COL_TERRAIN, COL_TERRAIN | COL_OBJECTS); //COL_XXXX are collision masks, allowing us to ignore collisions between certain object groups (required for buttons) } void Physics::addTriangleMeshBody(Entity entity, std::string path, float mass, float dampningL, float dampningA,unsigned indice,float scaling, bool rotate) { - if(bodies.size() == indice) - throw std::invalid_argument( "Bodies out of Sync" ); - + if(bodies.size() == indice) + throw std::invalid_argument( "Bodies out of Sync" ); + std::vector< unsigned int > vertexIndices; //temp lists for data sets std::vector< btVector3 > temp_vertices; path = "../" + geometryPath + path; @@ -171,10 +170,10 @@ void Physics::addTriangleMeshBody(Entity entity, std::string path, float mass, f } while( 1 ){ char lineHeader[128]; - // read the first word of the line + //read the first word of the line int res = fscanf(file, "%s", lineHeader); if (res == EOF) - break; // while not at end do loop + break; //while not at end do loop if ( strcmp( lineHeader, "v" ) == 0 ){ //if a vertex glm::vec3 vertex; fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z ); @@ -183,202 +182,198 @@ void Physics::addTriangleMeshBody(Entity entity, std::string path, float mass, f else if ( strcmp( lineHeader, "f" ) == 0 ){ //if face (index for 3 vertexes for a triangle) std::string vertex1, vertex2, vertex3; unsigned int vertexIndex[3], uvIndex[3], normalIndex[3]; - int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2] ); + int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2]); vertexIndices.push_back(vertexIndex[0]); vertexIndices.push_back(vertexIndex[1]); vertexIndices.push_back(vertexIndex[2]); //save 3 indexes in array } } - //finally start making body + //finally start making body btTriangleMesh* triMesh = new btTriangleMesh(); for(unsigned i = 2; i < vertexIndices.size();i+=3) { - triMesh->addTriangle(temp_vertices[vertexIndices[i]],temp_vertices[vertexIndices[i-1]],temp_vertices[vertexIndices[i-2]]); // for every face (3 elements in vertexIndices) create triangle use the indices to find correct vertexes to make the triangle + triMesh->addTriangle(temp_vertices[vertexIndices[i]],temp_vertices[vertexIndices[i-1]],temp_vertices[vertexIndices[i-2]]); //for every face (3 elements in vertexIndices) create triangle use the indices to find correct vertexes to make the triangle } btBvhTriangleMeshShape* shape = new btBvhTriangleMeshShape(triMesh,true); shape->setLocalScaling(btVector3(scaling,scaling,scaling)); //we need to add a scaling here because the objects seem to have diffrent sizes when loaded (no clue why, see composition.xml for exact scaling factors) - glm::quat glmQuat = glm::quat_cast(entity.getRotation()); + glm::quat glmQuat = glm::quat_cast(entity.getRotation()); - btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(glmQuat.x,glmQuat.y,glmQuat.z,glmQuat.w),btVector3(entity.getPosition().x,entity.getPosition().y,entity.getPosition().z))); + btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(glmQuat.x,glmQuat.y,glmQuat.z,glmQuat.w),btVector3(entity.getPosition().x,entity.getPosition().y,entity.getPosition().z))); - btVector3 inertia(0,0,0); - if(mass != 0.0 && rotate) //&& rotate lets certain objects get inertia (0,0,0) (not rotateable) - { - shape->calculateLocalInertia((btScalar)mass,inertia); - } + btVector3 inertia(0,0,0); + if(mass != 0.0 && rotate) //&& rotate lets certain objects get inertia (0,0,0) (not rotateable) + { + shape->calculateLocalInertia((btScalar)mass,inertia); + } - btRigidBody::btRigidBodyConstructionInfo info(mass,motion,shape,inertia); - - btRigidBody* body = new btRigidBody(info); - - body->setDamping(dampningL,dampningA); - - bodies.push_back(body); - - world->addRigidBody(body,COL_OBJECTS, objectsPhysicsCollision); + btRigidBody::btRigidBodyConstructionInfo info(mass,motion,shape,inertia); + + btRigidBody* body = new btRigidBody(info); + + body->setDamping(dampningL,dampningA); + + bodies.push_back(body); + + world->addRigidBody(body,COL_OBJECTS, objectsPhysicsCollision); - if(bodies.size() != indice) - throw std::invalid_argument( "Bodies out of Sync" ); + if(bodies.size() != indice) + throw std::invalid_argument( "Bodies out of Sync" ); } void Physics::addButton(float width, float height, float length, Entity entity, float mass, float dampningL, float dampningA, unsigned indice,bool rotate) { - if(bodies.size() == indice) - throw std::invalid_argument( "Bodies out of Sync" ); - - btBoxShape* box = new btBoxShape(btVector3(width/2,height/2,length/2)); - - glm::quat glmQuat = glm::quat_cast(entity.getRotation()); - - btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(glmQuat.x,glmQuat.y,glmQuat.z,glmQuat.w),btVector3(entity.getPosition().x,entity.getPosition().y,entity.getPosition().z))); - - btVector3 inertia(0,0,0); - if(mass != 0.0 && rotate) //&& rotate lets certain objects get inertia (0,0,0) (not rotateable) - { - box->calculateLocalInertia((btScalar)mass,inertia); - } - btRigidBody::btRigidBodyConstructionInfo info(mass,motion,box,inertia); - - btRigidBody* body = new btRigidBody(info); - + if(bodies.size() == indice) + throw std::invalid_argument( "Bodies out of Sync" ); + + btBoxShape* box = new btBoxShape(btVector3(width/2,height/2,length/2)); + + glm::quat glmQuat = glm::quat_cast(entity.getRotation()); + + btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(glmQuat.x,glmQuat.y,glmQuat.z,glmQuat.w),btVector3(entity.getPosition().x,entity.getPosition().y,entity.getPosition().z))); + + btVector3 inertia(0,0,0); + if(mass != 0.0 && rotate) //&& rotate lets certain objects get inertia (0,0,0) (not rotateable) + { + box->calculateLocalInertia((btScalar)mass,inertia); + } + btRigidBody::btRigidBodyConstructionInfo info(mass,motion,box,inertia); + + btRigidBody* body = new btRigidBody(info); + body->setDamping(dampningL, dampningA); - world->addRigidBody(body,COL_OBJECTS_NO_TERRAIN, specialPhysicsCollision); //the specialPhysicsCollision allows these objects to not collide with the terrain - - bodies.push_back(body); - - if(bodies.size() != indice) - throw std::invalid_argument( "Bodies out of Sync" ); + world->addRigidBody(body,COL_OBJECTS_NO_TERRAIN, specialPhysicsCollision); //the specialPhysicsCollision allows these objects to not collide with the terrain + + bodies.push_back(body); + + if(bodies.size() != indice) + throw std::invalid_argument( "Bodies out of Sync" ); } void Physics::addBox(float width, float height, float length, Entity entity, float mass, float dampningL, float dampningA, unsigned indice,bool rotate) { - //similar to other constructors - if(bodies.size() == indice) - throw std::invalid_argument( "Bodies out of Sync" ); - - glm::quat glmQuat = glm::quat_cast(entity.getRotation()); - btBoxShape* box = new btBoxShape(btVector3(width/2,height/2,length/2)); - btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(glmQuat.x,glmQuat.y,glmQuat.z,glmQuat.w),btVector3(entity.getPosition().x,entity.getPosition().y,entity.getPosition().z))); - - btVector3 inertia(0,0,0); - if(mass != 0.0) - { - box->calculateLocalInertia((btScalar)mass,inertia); - } - - - btRigidBody::btRigidBodyConstructionInfo info(mass,motion,box,inertia); - - btRigidBody* body = new btRigidBody(info); - + //similar to other constructors + if(bodies.size() == indice) + throw std::invalid_argument( "Bodies out of Sync" ); + + glm::quat glmQuat = glm::quat_cast(entity.getRotation()); + btBoxShape* box = new btBoxShape(btVector3(width/2,height/2,length/2)); + btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(glmQuat.x,glmQuat.y,glmQuat.z,glmQuat.w),btVector3(entity.getPosition().x,entity.getPosition().y,entity.getPosition().z))); + + btVector3 inertia(0,0,0); + if(mass != 0.0) + { + box->calculateLocalInertia((btScalar)mass,inertia); + } + + btRigidBody::btRigidBodyConstructionInfo info(mass,motion,box,inertia); + + btRigidBody* body = new btRigidBody(info); + body->setDamping(dampningL, dampningA); - world->addRigidBody(body,COL_OBJECTS, objectsPhysicsCollision); - - bodies.push_back(body); - - if(bodies.size() != indice) - throw std::invalid_argument( "Bodies out of Sync" ); + world->addRigidBody(body,COL_OBJECTS, objectsPhysicsCollision); + + bodies.push_back(body); + + if(bodies.size() != indice) + throw std::invalid_argument( "Bodies out of Sync" ); } void Physics::addSphere(float rad, Entity entity, float mass, float dampningL, float dampningA, unsigned indice,bool rotate) { - if(bodies.size() == indice) //(user's initial) height, not the actual height. More... - throw std::invalid_argument( "Bodies out of Sync" ); - - btSphereShape* sphere = new btSphereShape(rad); - btVector3 inertia(0,0,0); - if(mass != 0.0) - { - sphere->calculateLocalInertia((btScalar)mass,inertia); - } - - glm::quat glmQuat = glm::quat_cast(entity.getRotation()); - - btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(glmQuat.x,glmQuat.y,glmQuat.z,glmQuat.w),btVector3(entity.getPosition().x,entity.getPosition().y,entity.getPosition().z))); - - btRigidBody::btRigidBodyConstructionInfo info(mass,motion,sphere,inertia); - - - btRigidBody* body = new btRigidBody(info); - + if(bodies.size() == indice) //(user's initial) height, not the actual height. More... + throw std::invalid_argument( "Bodies out of Sync" ); + + btSphereShape* sphere = new btSphereShape(rad); + btVector3 inertia(0,0,0); + if(mass != 0.0) + { + sphere->calculateLocalInertia((btScalar)mass,inertia); + } + + glm::quat glmQuat = glm::quat_cast(entity.getRotation()); + + btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(glmQuat.x,glmQuat.y,glmQuat.z,glmQuat.w),btVector3(entity.getPosition().x,entity.getPosition().y,entity.getPosition().z))); + + btRigidBody::btRigidBodyConstructionInfo info(mass,motion,sphere,inertia); + + btRigidBody* body = new btRigidBody(info); + body->setDamping(dampningL, dampningA); - - world->addRigidBody(body,COL_OBJECTS, objectsPhysicsCollision); - - bodies.push_back(body); - + + world->addRigidBody(body,COL_OBJECTS, objectsPhysicsCollision); + + bodies.push_back(body); + body->setSleepingThresholds(0,0); - - if(bodies.size() != indice) - throw std::invalid_argument( "Bodies out of Sync" ); - + + if(bodies.size() != indice) + throw std::invalid_argument( "Bodies out of Sync" ); } void Physics::addCamera() //Camera Creator automatically called when player is created { - btSphereShape* sphere = new btSphereShape(0.5f);//we use this to make a more interesting camera, that does not interpenetrate with the terrain/objects - - btVector3 inertia(0,0,0); //rotation handled elsewhere (as it always has to look at the player) - - btVector3 direction(1,1,1); - direction.normalize(); - direction*=5; //create a offset of lenth 5 so we have a stable camera at the beginning - btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),playerBall->getCenterOfMassPosition()+direction)); - - btRigidBody::btRigidBodyConstructionInfo info(0.001,motion,sphere,inertia); - - cameraBody = new btRigidBody(info); - - cameraBody->setDamping(0.9,0.5); //this damping factor leaves a relativly smoothe system - - world->addRigidBody(cameraBody,COL_OBJECTS, objectsPhysicsCollision); - - cameraBody->setGravity(btVector3(0,0,0)); - - cameraBody->setSleepingThresholds(0,0); //very important, otherwise camera may go to sleep, aka not move until next collision + btSphereShape* sphere = new btSphereShape(0.5f); //we use this to make a more interesting camera, that does not interpenetrate with the terrain/objects + btVector3 inertia(0,0,0); //rotation handled elsewhere (as it always has to look at the player) + + btVector3 direction(1,1,1); + direction.normalize(); + direction*=5; //create a offset of lenth 5 so we have a stable camera at the beginning + btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),playerBall->getCenterOfMassPosition()+direction)); + + btRigidBody::btRigidBodyConstructionInfo info(0.001,motion,sphere,inertia); + + cameraBody = new btRigidBody(info); + + cameraBody->setDamping(0.9,0.5); //this damping factor leaves a relativly smoothe system + + world->addRigidBody(cameraBody,COL_OBJECTS, objectsPhysicsCollision); + + cameraBody->setGravity(btVector3(0,0,0)); + + cameraBody->setSleepingThresholds(0,0); //very important, otherwise camera may go to sleep, aka not move until next collision } //update functions glm::vec3 Physics::getCameraPosition() { - btVector3 origin = cameraBody->getCenterOfMassPosition(); - glm::vec3 save(origin.getX(),origin.getY(),origin.getZ()); - return save; + btVector3 origin = cameraBody->getCenterOfMassPosition(); + glm::vec3 save(origin.getX(),origin.getY(),origin.getZ()); + return save; } -glm::vec3 Physics::getCameraToPlayer()//returns a glm::vec3 the goes from the camera to the player +glm::vec3 Physics::getCameraToPlayer() //returns a glm::vec3 the goes from the camera to the player { - btVector3 origin = playerBall->getCenterOfMassPosition() - cameraBody->getCenterOfMassPosition(); - glm::vec3 save(origin.getX(),origin.getY(),origin.getZ()); - return save; + btVector3 origin = playerBall->getCenterOfMassPosition() - cameraBody->getCenterOfMassPosition(); + glm::vec3 save(origin.getX(),origin.getY(),origin.getZ()); + return save; } glm::vec3 Physics::getPos(int i) //this and the next function are used to synchronize the graphics data and the physics data { - btVector3 origin = bodies[i]->getCenterOfMassPosition(); - glm::vec3 save(origin.getX(),origin.getY(),origin.getZ()); - return save; + btVector3 origin = bodies[i]->getCenterOfMassPosition(); + glm::vec3 save(origin.getX(),origin.getY(),origin.getZ()); + return save; } glm::mat4 Physics::getRotation(int i) { - btQuaternion quat = bodies[i]->getOrientation(); - - glm::mat4 matrix = glm::rotate( - quat.getAngle(), - glm::vec3(quat.getAxis().getX(), quat.getAxis().getY(), quat.getAxis().getZ()) - ); //somewhat clunky, but basicly creates a rotation matrix out of the angle of the body, and its axis (from the quaterion in bullet) - return matrix; + btQuaternion quat = bodies[i]->getOrientation(); + + glm::mat4 matrix = glm::rotate( + quat.getAngle(), + glm::vec3(quat.getAxis().getX(), quat.getAxis().getY(), quat.getAxis().getZ()) + ); //somewhat clunky, but basicly creates a rotation matrix out of the angle of the body, and its axis (from the quaterion in bullet) + return matrix; } //these are used to apply a force to the camera body according to the movement of the mouse @@ -388,13 +383,12 @@ void Physics::updateCameraPos(glm::vec2 mouseMovement, float strength) btVector3 change = playerBall->getCenterOfMassPosition()-cameraBody->getCenterOfMassPosition(); change.setY(0); change.normalize(); //normalize so that the distance between camera and body does not matter - change *= (mouseMovement.y);//we start with left/right movement because this needs to be calculated via a crossproduct, and the up down value would alter that + change *= (mouseMovement.y); //we start with left/right movement because this needs to be calculated via a crossproduct, and the up down value would alter that change = btCross(btVector3(0,1,0),change); - change.setY(mouseMovement.x/5);//scaleing because otherwise oup/down much stronger then left right + change.setY(mouseMovement.x/5); //scaleing because otherwise oup/down much stronger then left right change *= strength / cameraBody->getInvMass(); cameraBody->applyCentralForce(change); - } //use the crossproduct to correctly apply a torque to the palyer if function called @@ -441,47 +435,47 @@ void Physics::rollRight(glm::vec3 camPos,float strength) 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); -}//not needed anymoer, but still good for debugging + 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); +} //not needed anymoer, but still good for debugging -void Physics::kill()//delete dynamically allocated memory +void Physics::kill() //delete dynamically allocated memory { if (world == NULL) { return; } - //btDynamimcWorld* - for(unsigned i = 0; i < bodies.size();i++) - { - world->removeCollisionObject(bodies[i]); //go through the list of bodies in world for each body b, then remove exactly this body b from world - btMotionState* motionState = bodies[i]->getMotionState(); - btCollisionShape* shape = bodies[i]->getCollisionShape(); - delete shape; - delete motionState; - delete bodies[i]; - } - btMotionState* motionState = terrainBody->getMotionState();//delete the rest that are not in the array bodies - btCollisionShape* shape = terrainBody->getCollisionShape(); - delete shape; - delete motionState; - delete terrainBody; - - motionState = cameraBody->getMotionState(); - shape = cameraBody->getCollisionShape(); - delete shape; - delete motionState; - delete cameraBody; //note: palyerBall is also in the array bodies so we do not need to clean it up - - delete dispatcher; //clean up rest - delete colConfig; - delete solver; - delete broadphase; - delete world; - - //feel like a good little programmer because everything is clean + //btDynamimcWorld* + for(unsigned i = 0; i < bodies.size();i++) + { + world->removeCollisionObject(bodies[i]); //go through the list of bodies in world for each body b, then remove exactly this body b from world + btMotionState* motionState = bodies[i]->getMotionState(); + btCollisionShape* shape = bodies[i]->getCollisionShape(); + delete shape; + delete motionState; + delete bodies[i]; + } + btMotionState* motionState = terrainBody->getMotionState(); //delete the rest that are not in the array bodies + btCollisionShape* shape = terrainBody->getCollisionShape(); + delete shape; + delete motionState; + delete terrainBody; + + motionState = cameraBody->getMotionState(); + shape = cameraBody->getCollisionShape(); + delete shape; + delete motionState; + delete cameraBody; //note: palyerBall is also in the array bodies so we do not need to clean it up + + delete dispatcher; //clean up rest + delete colConfig; + delete solver; + delete broadphase; + delete world; + + //feel like a good little programmer because everything is clean } diff --git a/physics.hh b/physics.hh index f4a96f3..7ad08e3 100644 --- a/physics.hh +++ b/physics.hh @@ -81,7 +81,7 @@ class Physics { void addCamera(); //Do NOT impliment before Player has been created; btDynamicsWorld* world = NULL; //contains physical attributes of the world. - btDispatcher* dispatcher; // + btDispatcher* dispatcher; btCollisionConfiguration* colConfig; //defines the type of collision detection. btBroadphaseInterface* broadphase; //defines how objects are culled from collision detection. btConstraintSolver* solver; //solver for forces and impulses. @@ -103,7 +103,7 @@ enum collisionTypes{ class btDistanceConstraint : public btPoint2PointConstraint { protected: - btScalar m_distance; + btScalar m_distance; public: btDistanceConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, btScalar dist) : btPoint2PointConstraint(rbA, rbB, pivotInA, pivotInB) diff --git a/terrain.cc b/terrain.cc index 59be9c1..b326ec2 100644 --- a/terrain.cc +++ b/terrain.cc @@ -18,16 +18,15 @@ void Terrain::load() { if (error) { std::cout << "Decoder error " << error << " from Terrain::load: " << lodepng_error_text(error) << std::endl; } - this->heightmap = new float*[this->heightmapHeight]; //initialize the heightmap - for(unsigned int rowNum = 0; rowNum < this->heightmapHeight; rowNum++){ //read in the heightmap - this->heightmap[rowNum] = new float[this->heightmapWidth]; + this->heightmap = new float*[this->heightmapHeight]; //initialize the heightmap + for(unsigned int rowNum = 0; rowNum < this->heightmapHeight; rowNum++){ //read in the heightmap + this->heightmap[rowNum] = new float[this->heightmapWidth]; for(unsigned int columnNum = 0; columnNum < this->heightmapWidth; columnNum++){ - this->heightmap[rowNum][columnNum] = (float)(image[(rowNum*heightmapWidth+columnNum)*4]) / 6; //<--heightmap is scaled here + this->heightmap[rowNum][columnNum] = (float)(image[(rowNum*heightmapWidth+columnNum)*4]) / 6; //<--heightmap is scaled here } } this->makeTriangleMesh(); - heightmapChanged = false; //no need to make a TriangleMesh again before rendering - + heightmapChanged = false; //no need to make a TriangleMesh again before rendering } void Terrain::makeTriangleMesh(){ @@ -37,19 +36,19 @@ void Terrain::makeTriangleMesh(){ ab->defineAttribute("aPosition", GL_FLOAT, 3); ab->defineAttribute("aTexCoord", GL_FLOAT, 2); ab->defineAttribute("aNormal", GL_FLOAT, 3); - - unsigned int rowNum=0, columnNum=0, dataCount=0, floatsPerVertex=8; //initializing: + + unsigned int rowNum=0, columnNum=0, dataCount=0, floatsPerVertex=8; //initializing: bool movingRight = true, isUp = true; int numVertices = (this->heightmapHeight - 1) * (this->heightmapWidth * 2 + 1) + 1; float* abData = new float[numVertices * floatsPerVertex]; - - while(rowNum < this->heightmapHeight){ //traversing the Triangle Strip! - set_abData(abData, dataCount, rowNum, columnNum); - dataCount += floatsPerVertex; - if (isUp){ - rowNum = rowNum + 1; - isUp = false; - } + + while(rowNum < this->heightmapHeight){ //traversing the Triangle Strip! + set_abData(abData, dataCount, rowNum, columnNum); + dataCount += floatsPerVertex; + if (isUp){ + rowNum = rowNum + 1; + isUp = false; + } else if (movingRight) { if (columnNum == this->heightmapWidth - 1) { set_abData(abData, dataCount, rowNum, columnNum); @@ -58,7 +57,7 @@ void Terrain::makeTriangleMesh(){ dataCount += floatsPerVertex; movingRight = false; rowNum = rowNum + 1; - } + } else { rowNum = rowNum - 1; columnNum = columnNum + 1; @@ -81,7 +80,7 @@ void Terrain::makeTriangleMesh(){ } } } - + ab->setDataElements(numVertices, abData); this->triangleMesh = std::make_shared(); this->triangleMesh->bind(); @@ -96,16 +95,16 @@ void Terrain::set_abData(float* abData, unsigned int dataCount, unsigned int row abData[dataCount] = (float)rowNum; abData[dataCount+1] = heightmap[rowNum][columnNum]; abData[dataCount+2] = (float)columnNum; - + //set Texture Coordinate abData[dataCount+3] = (float)(rowNum % 2); abData[dataCount+4] = (float)(columnNum % 2); - + //setNormal if (rowNum==0 || rowNum==(this->heightmapHeight-1) || columnNum==0 || columnNum==(this->heightmapWidth-1)){ - abData[dataCount+5] = 0.0; - abData[dataCount+6] = 1.0; - abData[dataCount+7] = 0.0; + abData[dataCount+5] = 0.0; + abData[dataCount+6] = 1.0; + abData[dataCount+7] = 0.0; } else { glm::vec3 sumNormals = glm::vec3(0.0f, 0.0f, 0.0f); diff --git a/terrain.hh b/terrain.hh index 8d1a7e6..0df7f97 100644 --- a/terrain.hh +++ b/terrain.hh @@ -16,12 +16,12 @@ class Terrain { float** getHeightmap(); unsigned int getHeightmapHeight(); unsigned int getHeightmapWidth(); - + private: Material material; std::string heightmapFilePath; unsigned int heightmapHeight, heightmapWidth; - float** heightmap; //can be accessed like 'float[][]' + float** heightmap; //can be accessed like 'float[][]' bool heightmapChanged; ACGL::OpenGL::SharedVertexArrayObject triangleMesh; void makeTriangleMesh(); diff --git a/trigger.hh b/trigger.hh index 623402a..9f57946 100644 --- a/trigger.hh +++ b/trigger.hh @@ -15,7 +15,7 @@ class Level; class Trigger { public: Trigger(glm::vec3 position, float distance, bool isBigger, Object* object, std::string luaScript, lua_State* L, int objectToChange, std::string scriptPath); - Trigger(); + Trigger(); ~Trigger(); void triggerUpdate(); bool deleteNotification(int deletedObjectIndex);