diff --git a/grk/project/ParticleSystem.h b/grk/project/ParticleSystem.h index 123b190..1b432e4 100644 --- a/grk/project/ParticleSystem.h +++ b/grk/project/ParticleSystem.h @@ -104,7 +104,7 @@ public: glBindVertexArray(0); } - void drawParticles(GLuint program, glm::mat4 view, glm::mat4 projection, float time) { + void drawParticles(GLuint program, glm::mat4 view, glm::mat4 projection, glm::mat4 modelSrc, float time) { if (shouldGenerateNewParticle(time)) { generateNewParticle(time); } @@ -124,7 +124,8 @@ public: glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection)); - glm::mat4 model = glm::translate(glm::mat4(1.0f), sourcePosition + particle.randomPointOnCircle); + glm::mat4 model = glm::translate(glm::mat4(1), sourcePosition + particle.randomPointOnCircle); + model = model * modelSrc; model = glm::scale(model, glm::vec3(0.005f, 0.005f, 0.005f)); model = glm::translate(model, particle.direction * speed * (time - particle.birthTime)); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); diff --git a/grk/project/Planet.h b/grk/project/Planet.h index 07cf131..a44b818 100644 --- a/grk/project/Planet.h +++ b/grk/project/Planet.h @@ -41,6 +41,6 @@ public: float rotationAngle = glm::radians(time * rotationSpeed); positionMatrix = center->getPositionMatrix() * glm::eulerAngleY(time * rotationSpeed) * glm::translate(glm::vec3(distanceFromCenter, 0, 0)); glm::mat4 modelMatrix = positionMatrix * glm::scale(glm::vec3(scale)); - Core::drawObjectPBRTexture(sphereContext, modelMatrix, textureID, 0.7, 0.0, program); + Core::drawObjectPBRTexture(sphereContext, modelMatrix, textureID, normalMapID, 0.7, 0.0, program); } }; \ No newline at end of file diff --git a/grk/project/Spaceship.h b/grk/project/Spaceship.h index 06579a4..7184f47 100644 --- a/grk/project/Spaceship.h +++ b/grk/project/Spaceship.h @@ -11,6 +11,7 @@ class Spaceship : public GameEntity { private: + std::list bullets; float lastShootTime = 0.f; float shootInterval = 0.3f; @@ -48,18 +49,29 @@ public: glm::vec3 cameraPos = glm::vec3(0.479490f, 1.250000f, -2.124680f); glm::vec3 cameraDir = glm::vec3(-0.354510f, 0.000000f, 0.935054f); + glm::mat4 additionalHorRotationMatrix; + glm::mat4 additionalVerRotationMatrix; glm::mat4 calculateModelMatrix() { glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f))); glm::vec3 spaceshipUp = glm::normalize(glm::cross(spaceshipSide, spaceshipDir)); - glm::mat4 specshipCameraRotrationMatrix = glm::mat4({ - spaceshipSide.x,spaceshipSide.y,spaceshipSide.z,0, - spaceshipUp.x,spaceshipUp.y,spaceshipUp.z ,0, - -spaceshipDir.x,-spaceshipDir.y,-spaceshipDir.z,0, - 0.,0.,0.,1., + + glm::mat4 spaceshipCameraRotationMatrix = glm::mat4({ + spaceshipSide.x, spaceshipSide.y, spaceshipSide.z, 0, + spaceshipUp.x, spaceshipUp.y, spaceshipUp.z, 0, + -spaceshipDir.x, -spaceshipDir.y, -spaceshipDir.z, 0, + 0., 0., 0., 1. }); - return glm::translate(spaceshipPos) * specshipCameraRotrationMatrix * glm::eulerAngleY(glm::pi()) * glm::scale(glm::vec3(0.02f)); + float additionalVerRotationAngle = glm::radians(currentShipVerAngle); + additionalVerRotationMatrix = glm::rotate(glm::mat4(1.0f), additionalVerRotationAngle, glm::vec3(1.f, 0.f, 0.f)); + + float additionalHorRotationAngle = glm::radians(currentShipHorAngle); + additionalHorRotationMatrix = glm::rotate(glm::mat4(1.0f), additionalHorRotationAngle, glm::vec3(0.f, 0.2f, 1.f)); + + glm::mat4 modelMatrix = glm::translate(spaceshipPos) * spaceshipCameraRotationMatrix * additionalVerRotationMatrix * additionalHorRotationMatrix * glm::eulerAngleY(glm::pi()) * glm::scale(glm::vec3(0.02f)); + + return modelMatrix; } void setPerticlesParameters(float speed, float generationInterval) { @@ -69,6 +81,122 @@ public: rightParticle->generationInterval = generationInterval; } + + const float fromCameraDirHorizontalStateToStateTime = 0.2f; + const float CAMERA_DISTANCE_STATIC_HOR = 0.7f; + const float CAMERA_DISTANCE_SLOW_HOR = 0.85f; + const float CAMERA_DISTANCE_FAST_HOR = 1.f; + + float currentCameraDistanceHor = CAMERA_DISTANCE_STATIC_HOR; + float targetCameraDistanceHor = CAMERA_DISTANCE_STATIC_HOR; + int currentWState = 0; + int currentShiftState = 0; + + float calculateCameraDistanceHor(int wState, int shiftState, float time) { + currentWState = wState; + currentShiftState = shiftState; + + if (currentWState == 1 && currentShiftState == 0) { + targetCameraDistanceHor = CAMERA_DISTANCE_SLOW_HOR; + } + else if (currentWState == 1 && currentShiftState == 1) { + targetCameraDistanceHor = CAMERA_DISTANCE_FAST_HOR; + } + else { + targetCameraDistanceHor = CAMERA_DISTANCE_STATIC_HOR; + } + + float diff = targetCameraDistanceHor - currentCameraDistanceHor; + float step = diff / fromCameraDirHorizontalStateToStateTime * time; + + currentCameraDistanceHor += step; + + return currentCameraDistanceHor; + } + + const float fromCameraDirVerticalStateToStateTime = 0.2f; + const float CAMERA_DISTANCE_STATIC_VER = 0.2f; + const float CAMERA_DISTANCE_SLOW_VER = 0.25f; + const float CAMERA_DISTANCE_FAST_VER = 0.3f; + + float currentCameraDistanceVer = CAMERA_DISTANCE_STATIC_VER; + float targetCameraDistanceVer = CAMERA_DISTANCE_STATIC_VER; + + float calculateCameraDistanceVer(float time) { + if (currentWState == 1 && currentShiftState == 0) { + targetCameraDistanceVer = CAMERA_DISTANCE_SLOW_VER; + } + else if (currentWState == 1 && currentShiftState == 1) { + targetCameraDistanceVer = CAMERA_DISTANCE_FAST_VER; + } + else { + targetCameraDistanceVer = CAMERA_DISTANCE_STATIC_VER; + } + + float diff = targetCameraDistanceVer - currentCameraDistanceVer; + float step = diff / fromCameraDirVerticalStateToStateTime * time; + + currentCameraDistanceVer += step; + + return currentCameraDistanceVer; + } + + const float MAX_VERTICAL_ANGLE = 15.f; + float currentShipVerAngle = 0.f; + float targetShipVerAngle = 0.f; + int currentQState = 0; + int currentEState = 0; + + float calculateShipAngleVer(int qState, int eState, float time) { + currentQState = qState; + currentEState = eState; + + if (currentQState == 1) { + targetShipVerAngle = MAX_VERTICAL_ANGLE; + } + else if (currentEState == 1) { + targetShipVerAngle = -MAX_VERTICAL_ANGLE; + } + else { + targetShipVerAngle = 0.f; + } + + float diff = targetShipVerAngle - currentShipVerAngle; + float step = diff / 0.2f * time; + + currentShipVerAngle += step; + + return currentShipVerAngle; + } + + const float MAX_HORIZONTALL_ANGLE = 15.f; + float currentShipHorAngle = 0.f; + float targetShipHorAngle = 0.f; + int currentAState = 0; + int currentDState = 0; + + float calculateShipAngleHor(int aState, int dState, float time) { + currentAState = aState; + currentDState = dState; + + if (currentAState == 1) { + targetShipHorAngle = MAX_HORIZONTALL_ANGLE; + } + else if (currentDState == 1) { + targetShipHorAngle = -MAX_HORIZONTALL_ANGLE; + } + else { + targetShipHorAngle = 0.f; + } + + float diff = targetShipHorAngle - currentShipHorAngle; + float step = diff / 0.2f * time; + + currentShipHorAngle += step; + + return currentShipHorAngle; + } + void processInput(GLFWwindow* window, float deltaTime, float time) { static bool mouseButtonCallbackSet = false; if (!mouseButtonCallbackSet) { @@ -81,9 +209,18 @@ public: int w = glfwGetKey(window, GLFW_KEY_W); int s = glfwGetKey(window, GLFW_KEY_S); + int shiftState = glfwGetKey(window, GLFW_KEY_LEFT_SHIFT); + int qState = glfwGetKey(window, GLFW_KEY_Q); + int eState = glfwGetKey(window, GLFW_KEY_E); + int aState = glfwGetKey(window, GLFW_KEY_A); + int dState = glfwGetKey(window, GLFW_KEY_D); + + calculateShipAngleVer(qState, eState, deltaTime); + calculateShipAngleHor(aState, dState, deltaTime); + //spaceshipDir = glm::vec3(glm::eulerAngleX(verticalAngle) * glm::vec4(spaceshipDir, 0)); if (w == GLFW_PRESS) { - if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) { + if (shiftState == GLFW_PRESS) { moveSpeed *= 2; setPerticlesParameters(200.f, 0.00005f); } @@ -95,8 +232,6 @@ public: setPerticlesParameters(50.f, 0.0002f); } - - if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { glfwSetWindowShouldClose(window, true); } @@ -108,18 +243,18 @@ public: spaceshipPos += spaceshipSide * moveSpeed; if (glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS) spaceshipPos -= spaceshipSide * moveSpeed; - if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) + if (qState == GLFW_PRESS) spaceshipPos += spaceshipUp * moveSpeed; - if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS) + if (eState == GLFW_PRESS) spaceshipPos -= spaceshipUp * moveSpeed; - if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) + if (aState == GLFW_PRESS) spaceshipDir = glm::vec3(glm::eulerAngleY(angleSpeed) * glm::vec4(spaceshipDir, 0)); - if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) + if (dState == GLFW_PRESS) spaceshipDir = glm::vec3(glm::eulerAngleY(-angleSpeed) * glm::vec4(spaceshipDir, 0)); if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS) requestShoot(time); - cameraPos = spaceshipPos - 1.f * spaceshipDir + glm::vec3(0, 1, 0) * 0.2f; + cameraPos = spaceshipPos - calculateCameraDistanceHor(w, shiftState, deltaTime) * spaceshipDir + glm::vec3(0, calculateCameraDistanceVer(deltaTime), 0); cameraDir = spaceshipDir; glm::vec3 perpendicularVector = 0.04f * glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.0f, 1.0f, 0.0f))); if (leftParticle != nullptr && rightParticle != nullptr) { @@ -135,8 +270,9 @@ public: void renderParticles(GLuint program, glm::mat4 view, glm::mat4 projection, float time) { if (leftParticle != nullptr && rightParticle != nullptr) { - leftParticle->drawParticles(program, view, projection, time); - rightParticle->drawParticles(program, view, projection, time); + glm::mat4 modelSrc = additionalVerRotationMatrix * additionalHorRotationMatrix; + leftParticle->drawParticles(program, view, projection, modelSrc, time); + rightParticle->drawParticles(program, view, projection, modelSrc, time); } } @@ -192,8 +328,9 @@ public: void shoot(float time) { glm::vec3 perpendicularVector = 0.25f * glm::normalize(glm::cross(cameraDir, glm::vec3(0.0f, 1.0f, 0.0f))); - bullets.push_back(Bullet::createSimpleBullet(cameraDir, spaceshipPos - perpendicularVector, time)); - bullets.push_back(Bullet::createSimpleBullet(cameraDir, spaceshipPos + perpendicularVector, time)); + glm::vec3 dir = glm::vec4(spaceshipDir.x, spaceshipDir.y, spaceshipDir.z, 1.f) * additionalVerRotationMatrix * additionalHorRotationMatrix; + bullets.push_back(Bullet::createSimpleBullet(dir, spaceshipPos - perpendicularVector, time)); + bullets.push_back(Bullet::createSimpleBullet(dir, spaceshipPos + perpendicularVector, time)); lastShootTime = time; }