diff --git a/res/cubemaps/HDR_placeholder.hdr b/res/cubemaps/HDR_placeholder.hdr new file mode 100644 index 0000000..6ec756f Binary files /dev/null and b/res/cubemaps/HDR_placeholder.hdr differ diff --git a/res/models/test2.mtl b/res/models/test2.mtl index 8594d3a..28b533b 100644 --- a/res/models/test2.mtl +++ b/res/models/test2.mtl @@ -8,7 +8,7 @@ Ke 0.000000 0.000000 0.000000 Ni 1.450000 d 1.000000 illum 2 -map_Kd ../textures/Test/test_basecolor.png -map_Ns ../textures/Test/test_roughness.png -map_refl ../textures/Test/test_metallic.png -map_Bump -bm 1.000000 ../textures/Test/test_normal.png +map_Kd ../textures/test_basecolor.png +map_Ns ../textures/test_roughness.png +map_refl ../textures/test_metallic.png +map_Bump -bm 1.000000 ../textures/test_normal.png diff --git a/res/shaders/BackgroundFragmentShader.frag b/res/shaders/BackgroundFragmentShader.frag new file mode 100644 index 0000000..28ac072 --- /dev/null +++ b/res/shaders/BackgroundFragmentShader.frag @@ -0,0 +1,16 @@ +#version 330 core +out vec4 FragColor; +in vec3 World_position; + +uniform samplerCube environmentMap; + +void main() +{ + vec3 envColor = texture(environmentMap, World_position).rgb; + + // HDR tonemap and gamma correct + envColor = envColor / (envColor + vec3(1.0)); + envColor = pow(envColor, vec3(1.0/2.2)); + + FragColor = vec4(envColor, 1.0); +} \ No newline at end of file diff --git a/res/shaders/BackgroundVertexShader.vert b/res/shaders/BackgroundVertexShader.vert new file mode 100644 index 0000000..fd83f9c --- /dev/null +++ b/res/shaders/BackgroundVertexShader.vert @@ -0,0 +1,17 @@ +#version 330 core +layout (location = 0) in vec3 aPos; + +uniform mat4 projection_matrix; +uniform mat4 view_matrix; + +out vec3 World_position; + +void main() +{ + World_position = aPos; + + mat4 rotView = mat4(mat3(view_matrix)); + vec4 clipPos = projection_matrix * rotView * vec4(World_position, 1.0); + + gl_Position = clipPos.xyww; +} \ No newline at end of file diff --git a/res/shaders/HDRCubemapVertexShader.vert b/res/shaders/HDRCubemapVertexShader.vert new file mode 100644 index 0000000..bde2133 --- /dev/null +++ b/res/shaders/HDRCubemapVertexShader.vert @@ -0,0 +1,13 @@ +#version 330 core +layout (location = 0) in vec3 iv_position; + +out vec3 World_position; + +uniform mat4 projection_matrix; +uniform mat4 view_matrix; + +void main() +{ + World_position = iv_position; + gl_Position = projection_matrix * view_matrix * vec4(World_position, 1.0); +} \ No newline at end of file diff --git a/res/shaders/HDREquirectangularToCubemapFragmentShader.frag b/res/shaders/HDREquirectangularToCubemapFragmentShader.frag new file mode 100644 index 0000000..8640f5e --- /dev/null +++ b/res/shaders/HDREquirectangularToCubemapFragmentShader.frag @@ -0,0 +1,22 @@ +#version 330 core +out vec4 FragColor; +in vec3 World_position; + +uniform sampler2D equirectangularMap; + +const vec2 invAtan = vec2(0.1591, 0.3183); +vec2 SampleSphericalMap(vec3 v) +{ + vec2 uv = vec2(atan(v.z, v.x), asin(v.y)); + uv *= invAtan; + uv += 0.5; + return uv; +} + +void main() +{ + vec2 uv = SampleSphericalMap(normalize(World_position)); + vec3 color = texture(equirectangularMap, uv).rgb; + + FragColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/res/shaders/IrradianceConvolutionFragmentShader.frag b/res/shaders/IrradianceConvolutionFragmentShader.frag new file mode 100644 index 0000000..e15b3dd --- /dev/null +++ b/res/shaders/IrradianceConvolutionFragmentShader.frag @@ -0,0 +1,38 @@ +#version 330 core +out vec4 FragColor; +in vec3 World_position; + +uniform samplerCube environmentMap; + +const float PI = 3.14159265359; + +void main() +{ + vec3 N = normalize(World_position); + + vec3 irradiance = vec3(0.0); + + // tangent space calculation from origin point + vec3 up = vec3(0.0, 1.0, 0.0); + vec3 right = normalize(cross(up, N)); + up = normalize(cross(N, right)); + + float sampleDelta = 0.025; + float nrSamples = 0.0; + for(float phi = 0.0; phi < 2.0 * PI; phi += sampleDelta) + { + for(float theta = 0.0; theta < 0.5 * PI; theta += sampleDelta) + { + // spherical to cartesian (in tangent space) + vec3 tangentSample = vec3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)); + // tangent space to world + vec3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * N; + + irradiance += texture(environmentMap, sampleVec).rgb * cos(theta) * sin(theta); + nrSamples++; + } + } + irradiance = PI * irradiance * (1.0 / float(nrSamples)); + + FragColor = vec4(irradiance, 1.0); +} \ No newline at end of file diff --git a/res/shaders/PBRFragmentShader.frag b/res/shaders/PBRFragmentShader.frag index 992c890..b57f8bd 100644 --- a/res/shaders/PBRFragmentShader.frag +++ b/res/shaders/PBRFragmentShader.frag @@ -15,6 +15,10 @@ uniform sampler2D normal_map; uniform sampler2D metallic_map; uniform sampler2D roughness_map; uniform sampler2D ao_map; + + +// IBL +uniform samplerCube irradiance_map; const float PI = 3.14159265359; @@ -23,6 +27,11 @@ vec3 fresnelSchlick(float cosTheta, vec3 F0) return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); } +vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness) + { + return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0); + } + float DistributionGGX(vec3 N, vec3 H, float roughness) //funkcja rozkładu wektorów normalnych Trowbridge-Reitz GGX { float a = roughness * roughness; @@ -60,14 +69,16 @@ float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) void main() { + vec3 N = normalize(Normal); + vec3 V = normalize(camera_position - World_position); + vec3 R = reflect(-V, N); + + vec3 albedo = texture(albedo_map, Texture_coords).rgb; float metallic = texture(metallic_map, Texture_coords).r; float roughness = texture(roughness_map, Texture_coords).r; float ao = texture(ao_map, Texture_coords).r; - vec3 N = normalize(Normal); - vec3 V = normalize(camPos - WorldPos); - vec3 F0 = vec3(0.04); F0 = mix(F0, albedo, metallic); @@ -76,10 +87,10 @@ void main() for(int i = 0; i < 4; ++i) { //radiation - vec3 L = normalize(light_positions[i] - WorldPos); + vec3 L = normalize(light_positions[i] - World_position); vec3 H = normalize(V + L); - float distance = length(light_positions[i] - WorldPos); + float distance = length(light_positions[i] - World_position); float attenuation = 1.0 / (distance * distance); vec3 radiance = light_colors[i] * attenuation; @@ -93,7 +104,7 @@ void main() vec3 numerator = NDF * G * F; float denominator = 4 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0); - vec3 specular = numerator / max(denominator, 0.001; + vec3 specular = numerator / max(denominator, 0.001); vec3 kS = F; vec3 kD = 1.0 - kS; @@ -103,12 +114,20 @@ void main() float NdotL = max(dot(N, L), 0.0); Lo += (kD * albedo / PI + specular) * radiance * NdotL; } + vec3 kS = fresnelSchlickRoughness(max(dot(N, V), 0.0), F0, roughness); + vec3 kD = 1.0 - kS; + kD *= 1.0 - metallic; + vec3 irradiance = texture(irradiance_map, N).rgb; + vec3 diffuse = irradiance * albedo; + vec3 ambient = (kD * diffuse) * ao; - vec3 ambient = vec3(0.03) * albedo * ao; - vec3 color = ambient + Lo; + vec3 color = ambient + Lo; + // HDR tonemapping color = color / (color + vec3(1.0)); + // gamma correction color = pow(color, vec3(1.0/2.2)); + FragColor = vec4(color, 1.0); } diff --git a/res/shaders/PBRVertexShader.vert b/res/shaders/PBRVertexShader.vert index bd6ac2a..c20d85e 100644 --- a/res/shaders/PBRVertexShader.vert +++ b/res/shaders/PBRVertexShader.vert @@ -14,8 +14,9 @@ uniform mat4 projection_matrix; void main() { vec4 mm = model_matrix * vec4(iv_position, 1.0); - gl_Position = projection_matrix * view_matrix * mm; World_position = vec3(mm); Normal = normalize(vec3(transpose(inverse(model_matrix)) * vec4(iv_normal, 1.0)));; Texture_coords = iv_texture; + + gl_Position = projection_matrix * view_matrix * mm; } \ No newline at end of file diff --git a/res/textures/Test/test_basecolor.png b/res/textures/test_basecolor.png similarity index 100% rename from res/textures/Test/test_basecolor.png rename to res/textures/test_basecolor.png diff --git a/res/textures/Test/test_metallic.png b/res/textures/test_metallic.png similarity index 100% rename from res/textures/Test/test_metallic.png rename to res/textures/test_metallic.png diff --git a/res/textures/Test/test_normal.png b/res/textures/test_normal.png similarity index 100% rename from res/textures/Test/test_normal.png rename to res/textures/test_normal.png diff --git a/res/textures/Test/test_roughness.png b/res/textures/test_roughness.png similarity index 100% rename from res/textures/Test/test_roughness.png rename to res/textures/test_roughness.png diff --git a/src/headers/Action.h b/src/headers/Action.h deleted file mode 100644 index ec74f72..0000000 --- a/src/headers/Action.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef ACTION_H -#define ACTION_H - -enum Action -{ - // Axis Actions - MOVE, - // Button Actions - PULL_ROPE -}; - -#endif // !ACTION_H \ No newline at end of file diff --git a/src/headers/ActionMappingType.h b/src/headers/ActionMappingType.h deleted file mode 100644 index c59d0eb..0000000 --- a/src/headers/ActionMappingType.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef ACTIONMAPPINGTYPE_H -#define ACTIONMAPPINGTYPE_H - -#include "glm/glm.hpp" -#include -#include - -#include "Action.h" -#include "GamepadAxisType.h" - -union ActionMappingType -{ - int buttonID; - std::array buttonIDs; - Input::GamepadAxisType axisType; -}; - -#endif // !ACTIONMAPPINGTYPE_H \ No newline at end of file diff --git a/src/headers/Collider.h b/src/headers/Collider.h index e90eac1..8a913fb 100644 --- a/src/headers/Collider.h +++ b/src/headers/Collider.h @@ -30,7 +30,6 @@ namespace Components void Update() override; void Destroy() override; void UpdateColliders(); - void PredictColliders(); }; } diff --git a/src/headers/GamepadAxisType.h b/src/headers/GamepadAxisType.h index adbdb4a..1e0b54c 100644 --- a/src/headers/GamepadAxisType.h +++ b/src/headers/GamepadAxisType.h @@ -9,6 +9,7 @@ enum class GamepadAxisType LEFT = 0, RIGHT = 2, TRIGGERS = 4, + KEYBOARD = 6 }; } // namespace Input diff --git a/src/headers/HDRCubemap.h b/src/headers/HDRCubemap.h new file mode 100644 index 0000000..e7e7e28 --- /dev/null +++ b/src/headers/HDRCubemap.h @@ -0,0 +1,34 @@ +#ifndef HDRCUBEMAP_H +#define HDRCUBEMAP_H + +#include "glad/glad.h" +#include "string" +#include +#include "Camera.h" +#include "Shader.h" +#include "Texture.h" +#include "GLFW/glfw3.h" + +class HDRCubemap +{ +public: + std::string path_; + std::shared_ptr BackgroundShader_; + std::shared_ptr EquirectangularToCubemapShader_; + std::shared_ptr IrrandanceShader_; + + unsigned int cubeVAO = 0; + unsigned int cubeVBO = 0; + unsigned int envCubemap = 0; + unsigned int irradianceMap = 0; + + HDRCubemap(const std::string& path, std::shared_ptr BackgroundShade, + std::shared_ptr EquirectangularToCubemapShader, std::shared_ptr IrrandanceShader); + ~HDRCubemap() = default; + + void LoadHDRimg(GLFWwindow* window, std::shared_ptr camera); + void RenderCube(); + +}; + +#endif // !HDRCUBEMAP_H \ No newline at end of file diff --git a/src/headers/InputManager.h b/src/headers/InputManager.h index 6c77c0a..0a45098 100644 --- a/src/headers/InputManager.h +++ b/src/headers/InputManager.h @@ -3,7 +3,6 @@ #include "InputObserver.h" #include "GamepadAxisType.h" -#include "ActionMappingType.h" #include #include @@ -16,7 +15,19 @@ namespace Input { -static const glm::vec2 axis_directions[] = {glm::vec2(0.0f, -1.0f), glm::vec2(0.0f, 1.0f), glm::vec2(-1.0f, 0.0f), glm::vec2(1.0f, 0.0f)}; +static std::unordered_map> axis_keyboard_mappings = +{ + {GLFW_JOYSTICK_1, {GLFW_KEY_W, GLFW_KEY_S, GLFW_KEY_A, GLFW_KEY_D}}, + {GLFW_JOYSTICK_2, {GLFW_KEY_UP, GLFW_KEY_DOWN, GLFW_KEY_LEFT, GLFW_KEY_RIGHT}} +}; + +static const glm::vec2 axis_directions[] = {glm::vec2(0.0f, 1.0f), glm::vec2(0.0f, -1.0f), glm::vec2(-1.0f, 0.0f), glm::vec2(1.0f, 0.0f)}; + +static std::unordered_map> button_keyboard_mappings = +{ + {GLFW_JOYSTICK_1, {GLFW_KEY_E}}, + {GLFW_JOYSTICK_2, {GLFW_KEY_SLASH}} +}; class InputManager { @@ -50,12 +61,8 @@ class InputManager // Input stuff private: - std::unordered_map>> observers_; + std::vector> observers_; std::unordered_map old_gamepad_states_; - std::unordered_map keyboard_state; - - std::unordered_map> keyboard_mappings; - std::unordered_map> gamepad_mappings; static void JoystickStateCallback(int jid, int event); @@ -63,25 +70,12 @@ class InputManager void UpdateKeyboardState(int gamepadID); public: - float deadzone_ = 0.1f; - - void AddObserver(int gamepadID, std::shared_ptr observer); - void RemoveObserver(int gamepadID, std::shared_ptr observer); - void NotifyAction(int gamepadID, Action action, State state); + void AddObserver(InputObserver *observer, int gamepadID); + void RemoveObserver(InputObserver *observer); + void NotifyAxisChange(int gamepadID, GamepadAxisType axis_type, glm::vec2 state); + void NotifyButtonChange(int gamepadID, int buttonID, bool state); void Update(); - - glm::vec2 SafeNormalize(glm::vec2 vector) - { - if (glm::length(vector) > 0.0f) - { - return glm::normalize(vector); - } - else - { - return glm::vec2(0.0f); - } - } }; }; // namespace Input diff --git a/src/headers/InputObserver.h b/src/headers/InputObserver.h index 737cc6a..30fd775 100644 --- a/src/headers/InputObserver.h +++ b/src/headers/InputObserver.h @@ -1,24 +1,19 @@ #ifndef INPUTOBSERVER_H #define INPUTOBSERVER_H -#include "Action.h" +#include "GamepadAxisType.h" #include "glm/glm.hpp" namespace Input { -union State -{ - glm::vec2 axis; - int button; -}; - class InputObserver { public: virtual ~InputObserver() = default; - virtual void OnAction(Action action, State state) = 0; + virtual void OnAxisChange(GamepadAxisType axis_type, glm::vec2 state) = 0; + virtual void OnButtonChange(int buttonID, bool state) = 0; }; } // namespace Input diff --git a/src/headers/Material.h b/src/headers/Material.h index 17a8d99..0fbf282 100644 --- a/src/headers/Material.h +++ b/src/headers/Material.h @@ -31,6 +31,7 @@ class Material textures_loaded.push_back(albedoMap); textures_loaded.push_back(normalMap); textures_loaded.push_back(metallicMap); + std::cout << "Material created" << std::endl; } Material() = default; diff --git a/src/headers/Physics.h b/src/headers/Physics.h index 4425642..63c491a 100644 --- a/src/headers/Physics.h +++ b/src/headers/Physics.h @@ -1,6 +1,10 @@ #ifndef PHYSICS_H #define PHYSICS_H +#define gCOEFFIECENT_OF_RESTITUTION 0.9f; +#define gCLAMP_MAX 1000.0f; +#define gCLAMP_MIN -1000.0f; + #include "glm/glm.hpp" #include #include "Transform.h" @@ -22,21 +26,18 @@ namespace Components public: float inverse_mass_; float mass_; - - float drag_; - glm::vec3 forces_ = glm::vec3(0.0f); std::shared_ptr transform_; glm::vec3 velocity_ = glm::vec3(0.0f); glm::vec3 acceleration_ = glm::vec3(0.0f); - Particle(std::shared_ptr transform, float mass, float drag) : transform_(transform), inverse_mass_(1.0f / mass), mass_(mass), drag_(drag) {} + Particle(std::shared_ptr transform, float mass) : transform_(transform), inverse_mass_(1.0f / mass), mass_(mass) {} void UpdateAcceleration(); void UpdateVelocity(float t); void UpdatePosition(float t); - void AddForce(const glm::vec3& force); + void AddForce(glm::vec3 force); void ZeroForces(); void UpdatePhysics(float t); @@ -49,8 +50,6 @@ namespace Components namespace physics { - const float kMaxForce = 100.0f; - const float kCoeffiecentOfResitution = 0.5f; class ForceGenerator { public: @@ -96,10 +95,8 @@ namespace physics struct Contact { - Contact(std::shared_ptr p1, std::shared_ptr p2); std::shared_ptr a; std::shared_ptr b; - glm::vec3 contact_normal; }; class PhysicsManager @@ -108,6 +105,7 @@ namespace physics static PhysicsManager* i_; private: std::vector generator_registry_; + std::shared_ptr common_drag_generator_; std::vector> particles_; PhysicsManager(); ~PhysicsManager() = default; @@ -129,19 +127,17 @@ namespace physics } } - std::shared_ptr CreateParticle(std::shared_ptr transform, float mass, float drag); + std::shared_ptr CreateParticle(std::shared_ptr transform, float mass); void GeneratorUpdate(); void ParticleUpdate(float t); void AddFGRRecord(std::shared_ptr generator, std::shared_ptr particle); void ResolveContact(physics::Contact& contact); void ResolveContacts(std::vector contacts); - void RealizePositions(); }; void LogVec3(glm::vec3 v); float Clampf(float v, float max, float min); void ClampElementwise(glm::vec3& v, float max, float min); - void Sigmoid(glm::vec3& v); } //physics #endif // !PHYSICS_H diff --git a/src/headers/Rope.h b/src/headers/Rope.h index 6cf5e01..ab7f089 100644 --- a/src/headers/Rope.h +++ b/src/headers/Rope.h @@ -12,13 +12,13 @@ namespace Components { public: RopeSegment(std::shared_ptr left, std::shared_ptr right, std::shared_ptr transform) - : left_(left), right_(right), transform_(transform){} + : left_(left), right_(right), transform_(transform) {} ~RopeSegment() = default; std::shared_ptr left_; std::shared_ptr right_; std::shared_ptr transform_; std::string name_; - bool is_puller_; + // Inherited via Component void Start() override; void Update() override; @@ -29,10 +29,9 @@ namespace Components namespace rope { - const float kMaxDistance = 0.25f; + const float kMaxDistance = 0.5f; const float kSpringConstant = 200.0f; const float kDamping = 0.01f; - const float kAdditionalPull = 0.5f; class Rope { @@ -40,9 +39,6 @@ namespace rope std::shared_ptr left_end_; std::shared_ptr right_end_; - std::shared_ptr left_puller_; - std::shared_ptr right_puller_; - Rope(); ~Rope() = default; diff --git a/src/source/Collider.cc b/src/source/Collider.cc index 57720b2..ef4e155 100644 --- a/src/source/Collider.cc +++ b/src/source/Collider.cc @@ -31,9 +31,3 @@ void Components::Collider::UpdateColliders() collisions::UpdateCentre(bp_collider_, transform_->get_position()); collisions::UpdateVertices(np_collider_, transform_->get_model_matrix()); } - -void Components::Collider::PredictColliders() -{ - collisions::UpdateCentre(bp_collider_, transform_->get_predicted_position()); - collisions::UpdateVertices(np_collider_, transform_->get_prediction_matrix()); -} \ No newline at end of file diff --git a/src/source/HDRCubemap.cpp b/src/source/HDRCubemap.cpp new file mode 100644 index 0000000..f3c4c9d --- /dev/null +++ b/src/source/HDRCubemap.cpp @@ -0,0 +1,213 @@ +#include "../headers/HDRCubemap.h" + + + +HDRCubemap::HDRCubemap(const std::string& path, std::shared_ptr BackgroundShade, std::shared_ptr EquirectangularToCubemapShader, std::shared_ptr IrrandanceShader) +{ + path_ = path; + BackgroundShader_ = BackgroundShade; + EquirectangularToCubemapShader_ = EquirectangularToCubemapShader; + IrrandanceShader_ = IrrandanceShader; +} + + + +void HDRCubemap::LoadHDRimg(GLFWwindow* window, std::shared_ptr camera) +{ + + + // pbr: setup framebuffer + // ---------------------- + unsigned int captureFBO; + unsigned int captureRBO; + glGenFramebuffers(1, &captureFBO); + glGenRenderbuffers(1, &captureRBO); + + glBindFramebuffer(GL_FRAMEBUFFER, captureFBO); + glBindRenderbuffer(GL_RENDERBUFFER, captureRBO); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 512, 512); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO); + + // pbr: load the HDR environment map + // --------------------------------- + stbi_set_flip_vertically_on_load(true); + int width, height, nrComponents; + float* data = stbi_loadf(path_.c_str(), &width, &height, &nrComponents, 0); + unsigned int hdrTexture = 0; + if (data) + { + glGenTextures(1, &hdrTexture); + glBindTexture(GL_TEXTURE_2D, hdrTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, data); // note how we specify the texture's data value to be float + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + stbi_image_free(data); + } + else + { + std::cout << "Failed to load HDR image." << std::endl; + } + + // pbr: setup cubemap to render to and attach to framebuffer + // --------------------------------------------------------- + + glGenTextures(1, &envCubemap); + glBindTexture(GL_TEXTURE_CUBE_MAP, envCubemap); + for (unsigned int i = 0; i < 6; ++i) + { + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 512, 512, 0, GL_RGB, GL_FLOAT, nullptr); + } + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // pbr: set up projection and view matrices for capturing data onto the 6 cubemap face directions + // ---------------------------------------------------------------------------------------------- + glm::mat4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f); + glm::mat4 captureViews[] = + { + glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)), + glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)), + glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)), + glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)), + glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)), + glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f)) + }; + + // pbr: convert HDR equirectangular environment map to cubemap equivalent + // ---------------------------------------------------------------------- + EquirectangularToCubemapShader_->Use(); + EquirectangularToCubemapShader_->SetInt("equirectangularMap", 0); + EquirectangularToCubemapShader_->SetMatrix4("projection_matrix", captureProjection); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, hdrTexture); + + glViewport(0, 0, 512, 512); // don't forget to configure the viewport to the capture dimensions. + glBindFramebuffer(GL_FRAMEBUFFER, captureFBO); + for (unsigned int i = 0; i < 6; ++i) + { + EquirectangularToCubemapShader_->SetMatrix4("view_matrix", captureViews[i]); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, envCubemap, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + RenderCube(); + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + // pbr: create an irradiance cubemap, and re-scale capture FBO to irradiance scale. + // -------------------------------------------------------------------------------- + + glGenTextures(1, &irradianceMap); + glBindTexture(GL_TEXTURE_CUBE_MAP, irradianceMap); + for (unsigned int i = 0; i < 6; ++i) + { + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 32, 32, 0, GL_RGB, GL_FLOAT, nullptr); + } + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glBindFramebuffer(GL_FRAMEBUFFER, captureFBO); + glBindRenderbuffer(GL_RENDERBUFFER, captureRBO); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 32, 32); + + // pbr: solve diffuse integral by convolution to create an irradiance (cube)map. + // ----------------------------------------------------------------------------- + IrrandanceShader_->Use(); + IrrandanceShader_->SetInt("environmentMap", 0); + IrrandanceShader_->SetMatrix4("projection_matrix", captureProjection); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_CUBE_MAP, envCubemap); + + glViewport(0, 0, 32, 32); // don't forget to configure the viewport to the capture dimensions. + glBindFramebuffer(GL_FRAMEBUFFER, captureFBO); + for (unsigned int i = 0; i < 6; ++i) + { + IrrandanceShader_->SetMatrix4("view_matrix", captureViews[i]); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, irradianceMap, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + RenderCube(); + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +void HDRCubemap::RenderCube() +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_CUBE_MAP, envCubemap); + if (cubeVAO == 0) + { + float vertices[] = { + // back face + -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, // bottom-left + 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, // top-right + 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, // bottom-right + 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, // top-right + -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, // bottom-left + -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, // top-left + // front face + -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom-left + 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, // bottom-right + 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // top-right + 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // top-right + -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // top-left + -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom-left + // left face + -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-right + -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top-left + -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-left + -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-left + -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom-right + -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-right + // right face + 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-left + 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-right + 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top-right + 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-right + 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-left + 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom-left + // bottom face + -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, // top-right + 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, // top-left + 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom-left + 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom-left + -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom-right + -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, // top-right + // top face + -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // top-left + 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom-right + 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top-right + 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom-right + -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // top-left + -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f // bottom-left + }; + glGenVertexArrays(1, &cubeVAO); + glGenBuffers(1, &cubeVBO); + + glBindBuffer(GL_ARRAY_BUFFER, cubeVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glBindVertexArray(cubeVAO); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float))); + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + } + + glBindVertexArray(cubeVAO); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindVertexArray(0); +} diff --git a/src/source/InputManager.cc b/src/source/InputManager.cc index 3a0e851..e68cc75 100644 --- a/src/source/InputManager.cc +++ b/src/source/InputManager.cc @@ -8,41 +8,6 @@ Input::InputManager::InputManager(GLFWwindow *window) glfwSetJoystickCallback(JoystickStateCallback); old_gamepad_states_.emplace(GLFW_JOYSTICK_1, GLFWgamepadstate()); old_gamepad_states_.emplace(GLFW_JOYSTICK_2, GLFWgamepadstate()); - for (int i = GLFW_KEY_SPACE; i <= GLFW_KEY_LAST; i++) - { - keyboard_state[i] = false; - } - - observers_.emplace(GLFW_JOYSTICK_1, std::vector>()); - observers_.emplace(GLFW_JOYSTICK_2, std::vector>()); - - keyboard_mappings = - { - {GLFW_JOYSTICK_1, - { - {Action::MOVE, ActionMappingType{.buttonIDs = {GLFW_KEY_I, GLFW_KEY_K, GLFW_KEY_J, GLFW_KEY_L}}}, - {Action::PULL_ROPE, ActionMappingType{.buttonID = GLFW_KEY_U}} - }}, - {GLFW_JOYSTICK_2, - { - {Action::MOVE, ActionMappingType{.buttonIDs = {GLFW_KEY_T, GLFW_KEY_G, GLFW_KEY_F, GLFW_KEY_H}}}, - {Action::PULL_ROPE, ActionMappingType{.buttonID = GLFW_KEY_Y}} - }} - }; - - gamepad_mappings = - { - {GLFW_JOYSTICK_1, - { - {Action::MOVE, ActionMappingType{.axisType = GamepadAxisType::LEFT}}, - {Action::PULL_ROPE, ActionMappingType{.buttonID = GLFW_GAMEPAD_BUTTON_A}} - }}, - {GLFW_JOYSTICK_2, - { - {Action::MOVE, ActionMappingType{.axisType = GamepadAxisType::LEFT}}, - {Action::PULL_ROPE, ActionMappingType{.buttonID = GLFW_GAMEPAD_BUTTON_A}} - }} - }; } void Input::InputManager::JoystickStateCallback(int jid, int event) @@ -62,28 +27,23 @@ void Input::InputManager::UpdateGamepadState(int gamepadID) GLFWgamepadstate new_gamepad_state; if (glfwGetGamepadState(gamepadID, &new_gamepad_state)) { - int axis_type = static_cast(gamepad_mappings[gamepadID][Action::MOVE].axisType); - glm::vec2 new_axis_state(new_gamepad_state.axes[axis_type], new_gamepad_state.axes[axis_type + 1]); - glm::vec2 old_axis_state(old_gamepad_states_[gamepadID].axes[axis_type], old_gamepad_states_[gamepadID].axes[axis_type + 1]); - - if (glm::length(new_axis_state) < deadzone_) - { - new_axis_state = glm::vec2(0.0f); - } - if (glm::length(old_axis_state) < deadzone_) + for (int i = 0; i < GLFW_GAMEPAD_AXIS_LAST; i += 2) { - old_axis_state = glm::vec2(0.0f); - } + glm::vec2 new_axis_state(new_gamepad_state.axes[i], new_gamepad_state.axes[i + 1]); + glm::vec2 old_axis_state(old_gamepad_states_[gamepadID].axes[i], old_gamepad_states_[gamepadID].axes[i + 1]); - if (new_axis_state != old_axis_state) - { - NotifyAction(gamepadID, Action::MOVE, State(new_axis_state)); + if (new_axis_state != old_axis_state) + { + NotifyAxisChange(gamepadID, static_cast(i), new_axis_state); + } } - auto pull_rope_button = gamepad_mappings[gamepadID][Action::PULL_ROPE].buttonID; - if (new_gamepad_state.buttons[pull_rope_button] != old_gamepad_states_[gamepadID].buttons[pull_rope_button]) + for (int i = 0; i < GLFW_GAMEPAD_BUTTON_LAST; i++) { - NotifyAction(gamepadID, Action::PULL_ROPE, State{.button = (int)new_gamepad_state.buttons[pull_rope_button]}); + if (new_gamepad_state.buttons[i] != old_gamepad_states_[gamepadID].buttons[i]) + { + NotifyButtonChange(gamepadID, i, new_gamepad_state.buttons[i]); + } } old_gamepad_states_[gamepadID] = new_gamepad_state; @@ -92,67 +52,67 @@ void Input::InputManager::UpdateGamepadState(int gamepadID) void Input::InputManager::UpdateKeyboardState(int gamepadID) { - auto &move_action_buttons = keyboard_mappings[gamepadID][Action::MOVE].buttonIDs; glm::vec2 axis_state(0.0f); - bool key_state_changed = false; + auto keys = axis_keyboard_mappings[gamepadID]; for (int i = 0; i < 4; i++) { - bool key_state = glfwGetKey(window_, move_action_buttons[i]); - if (keyboard_state[move_action_buttons[i]] != key_state) - { - keyboard_state[move_action_buttons[i]] = key_state; - key_state_changed = true; - } - if (key_state) + if (glfwGetKey(window_, keys[i]) == GLFW_PRESS) { axis_state += axis_directions[i]; } } - if (key_state_changed) - { - axis_state = SafeNormalize(axis_state); - NotifyAction(gamepadID, Action::MOVE, State(axis_state)); - } +} - auto &pull_rope_button = keyboard_mappings[gamepadID][Action::PULL_ROPE].buttonID; - int pull_rope_button_state = glfwGetKey(window_, pull_rope_button); - if (pull_rope_button_state != keyboard_state[pull_rope_button]) - { - keyboard_state[pull_rope_button] = pull_rope_button_state; - NotifyAction(gamepadID, Action::PULL_ROPE, State{.button = pull_rope_button_state}); - } +void Input::InputManager::AddObserver(InputObserver *observer, int gamepadID) +{ + observers_.push_back(std::make_pair(observer, gamepadID)); } -void Input::InputManager::AddObserver(int gamepadID, std::shared_ptr observer) +void Input::InputManager::RemoveObserver(InputObserver *observer) { - observers_[gamepadID].push_back(observer); + for (auto it = observers_.begin(); it != observers_.end(); it++) + { + if (it->first == observer) + { + observers_.erase(it); + break; + } + } } -void Input::InputManager::RemoveObserver(int gamepadID, std::shared_ptr observer) +void Input::InputManager::NotifyAxisChange(int gamepadID, GamepadAxisType axis_type, glm::vec2 state) { - auto &observers = observers_[gamepadID]; - observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end()); + for (auto &observer : observers_) + { + if (observer.second == gamepadID) + { + observer.first->OnAxisChange(axis_type, state); + } + } } -void Input::InputManager::NotifyAction(int gamepadID, Action action, State state) +void Input::InputManager::NotifyButtonChange(int gamepadID, int buttonID, bool state) { - for (auto &observer : observers_[gamepadID]) + for (auto &observer : observers_) { - observer->OnAction(action, state); + if (observer.second == gamepadID) + { + observer.first->OnButtonChange(buttonID, state); + } } } void Input::InputManager::Update() { - for (int gamepadID = GLFW_JOYSTICK_1; gamepadID <= GLFW_JOYSTICK_2; gamepadID++) + for (auto &gamepad : old_gamepad_states_) { - if (glfwJoystickPresent(gamepadID)) + if (glfwJoystickPresent(gamepad.first)) { - UpdateGamepadState(gamepadID); + UpdateGamepadState(gamepad.first); } else { - UpdateKeyboardState(gamepadID); + UpdateKeyboardState(gamepad.first); } } } \ No newline at end of file diff --git a/src/source/Physics.cc b/src/source/Physics.cc index 5541c49..d2c18ba 100644 --- a/src/source/Physics.cc +++ b/src/source/Physics.cc @@ -2,7 +2,7 @@ void physics::LogVec3(glm::vec3 a) { - std::cout << "x: " << a.x << " y: " << a.y << " z: " << a.z << "\n"; + std::cout << a.x << " " << a.y << " " << a.z << "\n"; } float physics::Clampf(float v, float max, float min) @@ -17,6 +17,8 @@ float physics::Clampf(float v, float max, float min) } return v; + + } void physics::ClampElementwise(glm::vec3& v, float max, float min) @@ -26,33 +28,26 @@ void physics::ClampElementwise(glm::vec3& v, float max, float min) v.z = Clampf(v.z, max, min); } -void physics::Sigmoid(glm::vec3& v) -{ - v.x = std::exp2f(-v.x); - v.y = 0.0f; - v.z = std::exp2f(-v.z); -} - - void Components::Particle::UpdateAcceleration() { - physics::ClampElementwise(forces_, physics::kMaxForce, -physics::kMaxForce); acceleration_ = inverse_mass_ * forces_; + physics::ClampElementwise(acceleration_, 1000.f, -1000.f); + } void Components::Particle::UpdateVelocity(float t) { - velocity_ = velocity_ + acceleration_ * t; + velocity_ = velocity_ + acceleration_ * t; + physics::ClampElementwise(velocity_, 1000.f, -1000.f); } void Components::Particle::UpdatePosition(float t) { - velocity_ *= drag_; auto new_position = transform_->get_position() + velocity_ * t + 0.5f * acceleration_ * t * t; - transform_->set_predicted_position(new_position); + transform_->set_position(new_position); } -void Components::Particle::AddForce(const glm::vec3& force) +void Components::Particle::AddForce(glm::vec3 force) { forces_ += force; } @@ -69,6 +64,12 @@ void Components::Particle::UpdatePhysics(float t) UpdateAcceleration(); UpdateVelocity(t); ZeroForces(); + /*std::cout << "acc: "; + LogVec3(acceleration_); + std::cout << "vel: "; + LogVec3(velocity_); + std::cout << "pos: "; + LogVec3(transform_->get_position());*/ } void Components::Particle::Start() @@ -77,10 +78,8 @@ void Components::Particle::Start() void Components::Particle::Update() { - } - physics::DragGenerator::DragGenerator(float k1, float k2) { this->k1_ = k1; @@ -111,24 +110,27 @@ void physics::BasicGenerator::GenerateForce(std::shared_ptrAddForce(direction_ * magnitude_); } - void physics::FGRRecord::Generate() { generator->GenerateForce(particle); } - physics::PhysicsManager* physics::PhysicsManager::i_ = nullptr; physics::PhysicsManager::PhysicsManager() { + common_drag_generator_ = std::make_shared(7.0f, 15.0f); generator_registry_ = std::vector(); particles_ = std::vector>(); } -std::shared_ptr physics::PhysicsManager::CreateParticle(std::shared_ptr transform, float mass, float drag) +std::shared_ptr physics::PhysicsManager::CreateParticle(std::shared_ptr transform, float mass) { - auto return_value = std::make_shared(transform, mass, drag); + auto return_value = std::make_shared(transform, mass); + FGRRecord new_record; + new_record.generator = common_drag_generator_; + new_record.particle = return_value; + generator_registry_.push_back(new_record); particles_.push_back(return_value); return return_value; } @@ -160,30 +162,24 @@ void physics::PhysicsManager::AddFGRRecord(std::shared_ptrvelocity_ - contact.b->velocity_), contact.contact_normal); - if (separating_velocity > 0) - { - return; - } - - float new_sep_vel = -separating_velocity * kCoeffiecentOfResitution; - float delta_velocity = new_sep_vel - separating_velocity; - - float total_inverse_mass = contact.a->inverse_mass_ + contact.b->inverse_mass_; + glm::vec3 ua = contact.a->velocity_; + glm::vec3 ub = contact.b->velocity_; - if (total_inverse_mass <= 0) - { - return; - } + float ma = contact.a->mass_; + float mb = contact.b->mass_; + + float mass_sum = ma + mb; + assert(mass_sum > 0.00001f); + glm::vec3 mumu = ma * ua + mb * ub; - float impulse = delta_velocity / total_inverse_mass; - glm::vec3 impulse_per_mass_unit = contact.contact_normal * impulse; + va = ( (mumu + (0.1f * mb * (ub - ua))) / (mass_sum)); + vb = ( (mumu + (0.1f * ma * (ua - ub))) / (mass_sum)); - contact.a->velocity_ += impulse_per_mass_unit * contact.a->inverse_mass_; - contact.b->velocity_ += -impulse_per_mass_unit * contact.b->inverse_mass_; + contact.a->velocity_ = va; + contact.b->velocity_ = vb; } void physics::PhysicsManager::ResolveContacts(std::vector contacts) @@ -193,27 +189,3 @@ void physics::PhysicsManager::ResolveContacts(std::vector cont ResolveContact(contact); } } - -void physics::PhysicsManager::RealizePositions() -{ - for (auto& p : particles_) - { - p->transform_->set_position(p->transform_->get_predicted_position()); - } -} - - -physics::Contact::Contact(std::shared_ptr p1, std::shared_ptr p2) -{ - a = p1; - b = p2; - contact_normal = glm::cross(p1->transform_->get_position(), p2->transform_->get_position()); - auto dir = p1->transform_->get_position() - p2->transform_->get_position(); - auto rotation_matrix = glm::rotate(glm::mat4(1.0f), glm::radians(-90.0f), glm::vec3(0.0f, 1.0f, 0.0f)); - glm::vec4 tmp = glm::vec4(dir.x, 0.0f, dir.z, 1.0f); - tmp = tmp * rotation_matrix; - contact_normal.x = tmp.x; - contact_normal.y = tmp.y; - contact_normal.z = tmp.z; - glm::normalize(contact_normal); -} diff --git a/src/source/Rope.cc b/src/source/Rope.cc index d66e82c..6469e41 100644 --- a/src/source/Rope.cc +++ b/src/source/Rope.cc @@ -2,39 +2,34 @@ void rope::Rope::CheckRestraints(std::shared_ptr a, std::shared_ptr b, float t) { - float distance = glm::distance(a->transform_->get_predicted_position(), b->transform_->get_predicted_position()); - auto particle_a = a->transform_->game_object_->GetComponent(); - auto particle_b = b->transform_->game_object_->GetComponent(); - assert(particle_a != nullptr); - assert(particle_b != nullptr); - + float distance = glm::distance(a->transform_->get_position(), b->transform_->get_position()); if (distance >= kMaxDistance) { - glm::vec3 force = particle_b->transform_->get_predicted_position(); - force -= particle_a->transform_->get_predicted_position(); + auto particle_a = a->transform_->game_object_->GetComponent(); + auto particle_b = b->transform_->game_object_->GetComponent(); + assert(particle_a != nullptr); + assert(particle_b != nullptr); + + glm::vec3 force = particle_b->transform_->get_position(); + force -= particle_a->transform_->get_position(); float magnitude = glm::length(force); magnitude = std::abs(magnitude - kMaxDistance); magnitude *= kSpringConstant; glm::normalize(force); force *= -magnitude; particle_b->AddForce(force); - particle_a->AddForce(-force); - if (!a->is_puller_ && !b->is_puller_) - { - auto vl = left_puller_->gameObject_.lock()->GetComponent()->velocity_; - auto rl = right_puller_->gameObject_.lock()->GetComponent()->velocity_; - - if(glm::dot(vl, rl) > 0.0f) - { - auto v = vl + rl; - v *= kAdditionalPull; - particle_a->velocity_ += v; - particle_b->velocity_ += v; - //physics::LogVec3(v); - } - } + + force = particle_a->transform_->get_position(); + force -= particle_b->transform_->get_position(); + magnitude = glm::length(force); + magnitude = std::abs(magnitude - kMaxDistance); + magnitude *= kSpringConstant; + glm::normalize(force); + force *= -magnitude; + particle_a->AddForce(force); } + } void rope::Rope::EnforceRestraints(float t)