#include "ParticleWorld.h" #include #include ParticleWorld::ParticleWorld() { light.lightDirection = glm::normalize(glm::vec3((cos(lightPitch) * cos(lightYaw)), (sin(lightPitch)), (cos(lightPitch) * sin(lightYaw)))); light.radiance = 15.f * lightColor; { auto p0 = std::make_shared(1); p0->setPosition({ 0,1,0 }); p0->setFixed(true); auto p1 = std::make_shared(1); p1->setPosition({ 0,0,0 }); p1->setEnableGravity(true); addActor(p0); addActor(p1); physicsManager.addSpring(p0, p1, 2, 5, 0.1); } for (int i = 0, particleCount = 5; i < particleCount; i++) { auto particle = std::make_shared(1); particle->setPosition({ 5, 0, glm::mix(-3.1f,2.f,(double)i / (particleCount - 1)) }); if (i == 0 || i == particleCount - 1) particle->setFixed(true); else particle->setEnableGravity(true); particles.push_back(particle); addActor(particle); if (i != 0) { float ks = 10, kd = 0.1; physicsManager.addRubberBand(particles[i - 1], particle, 0.01, ks, kd); } } { star = std::make_shared(100); star->setPosition({ -10,0,0 }); star->setFixed(true); auto p = std::make_shared(1); p->setPosition({ -15,0,0 }); p->setSpeed(glm::vec3(0, 0, 1) * glm::sqrt(G * star->getMass() / glm::distance(star->getPosition(), p->getPosition()))); addActor(star); addActor(p); physicsManager.addGravitation(star, p, G); } } void ParticleWorld::logicalTick(float deltaTime) { World::logicalTick(deltaTime); } void ParticleWorld::rendererTick(float deltaTime) { World::rendererTick(deltaTime); for (auto iter = particles.begin(); iter != particles.end(); ) { if (glm::length2((*iter)->getPosition()) > 1e4) { removeActor(*iter); iter = particles.erase(iter); } else iter++; } } void ParticleWorld::cursorPosCallback(GLFWwindow* window, double xpos, double ypos) { static bool firstMouse = true; static float lastX; static float lastY; float xoffset = xpos - lastX; float yoffset = lastY - ypos; lastX = xpos; lastY = ypos; if (firstMouse) { firstMouse = false; return; } if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS) camera.processMouseMovement(xoffset, yoffset); } void ParticleWorld::mouseButtonCallback(GLFWwindow* window, int button, int action, int mods) { if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) { auto p = std::make_shared(1); p->setPosition(camera.Position + glm::vec3(0, -0.3, 0)); p->setSpeed(5.f * glm::normalize(camera.Front)); addActor(p); physicsManager.addGravitation(star, p, G); particles.push_back(p); } } void ParticleWorld::scrollCallback(GLFWwindow* window, double xoffset, double yoffset) { if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) lightPitch = glm::mod(lightPitch + yoffset / 100., glm::pi()); else if (glfwGetKey(window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS) lightYaw = glm::mod(lightYaw + yoffset / 100., 2 * glm::pi()); else if (glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS) light.radiance = glm::clamp((light.radiance / lightColor).x + (float)yoffset, 0.f, 100.f) * lightColor; else if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS) RenderingSystem::instance().exposure = glm::clamp(RenderingSystem::instance().exposure + (float)yoffset * 0.1f, 0.f, 2.f); else camera.processMouseScroll(yoffset); light.lightDirection = glm::normalize(glm::vec3((cos(lightPitch) * cos(lightYaw)), (sin(lightPitch)), (cos(lightPitch) * sin(lightYaw)))); } void ParticleWorld::processInput(GLFWwindow* window, float deltaTime) { if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) camera.processKeyboard(FORWARD, deltaTime); if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) camera.processKeyboard(BACKWARD, deltaTime); if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) camera.processKeyboard(LEFT, deltaTime); if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) camera.processKeyboard(RIGHT, deltaTime); if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) camera.processKeyboard(UP, deltaTime); if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) camera.processKeyboard(DOWN, deltaTime); }