From dfca659f8143624e0bca966c28a063bfc287f85c Mon Sep 17 00:00:00 2001 From: sh960440 <54958110+sh960440@users.noreply.github.com> Date: Fri, 14 Feb 2020 00:31:34 -0500 Subject: [PATCH 1/2] Assignment 1 Shun-min Hsieh 101212629 Miko Man 101153000 --- OpenGLEngine/OpenGLEngine/BuoyancyComponent.h | 16 + OpenGLEngine/OpenGLEngine/BuoyancySystem.cpp | 42 ++ OpenGLEngine/OpenGLEngine/BuoyancySystem.h | 16 + .../OpenGLEngine/DragForceComponent.h | 16 + OpenGLEngine/OpenGLEngine/DragForceSystem.cpp | 29 + OpenGLEngine/OpenGLEngine/DragForceSystem.h | 15 + OpenGLEngine/OpenGLEngine/ECSConfig.h | 1 + .../OpenGLEngine/FPSControlSystem.cpp | 5 + .../OpenGLEngine/FireworksComponent.h | 20 + OpenGLEngine/OpenGLEngine/FireworksSystem.cpp | 60 ++ OpenGLEngine/OpenGLEngine/FireworksSystem.h | 14 + .../OpenGLEngine/FixedSpringComponent.h | 16 +- .../OpenGLEngine/FixedSpringSystem.cpp | 56 ++ OpenGLEngine/OpenGLEngine/FixedSpringSystem.h | 14 + .../OpenGLEngine/ForceAccumulatorComponent.h | 30 + .../OpenGLEngine/ForceAccumulatorSystem.cpp | 11 +- .../OpenGLEngine/ForceAccumulatorSystem.h | 2 +- .../OpenGLEngine/GravityForceComponent.h | 15 + .../OpenGLEngine/GravityForceSystem.cpp | 24 + .../OpenGLEngine/GravityForceSystem.h | 15 + OpenGLEngine/OpenGLEngine/Main.cpp | 552 ++++-------------- OpenGLEngine/OpenGLEngine/Mix/World.h | 2 + OpenGLEngine/OpenGLEngine/NBodyComponent.h | 16 + OpenGLEngine/OpenGLEngine/NBodySystem.cpp | 35 ++ OpenGLEngine/OpenGLEngine/NBodySystem.h | 14 + .../OpenGLEngine/OpenGLEngine.vcxproj | 218 ++----- .../OpenGLEngine/OpenGLEngine.vcxproj.filters | 307 +++------- .../OpenGLEngine/PairedSpringComponent.h | 19 +- .../OpenGLEngine/PairedSpringSystem.cpp | 61 ++ .../OpenGLEngine/PairedSpringSystem.h | 13 + OpenGLEngine/OpenGLEngine/ParticleComponent.h | 26 +- OpenGLEngine/OpenGLEngine/ParticleSystem.cpp | 17 +- OpenGLEngine/OpenGLEngine/ParticleSystem.h | 1 - OpenGLEngine/OpenGLEngine/RotateComponent.h | 20 +- OpenGLEngine/OpenGLEngine/RotateSystem.cpp | 25 +- OpenGLEngine/OpenGLEngine/RotateSystem.h | 15 +- 36 files changed, 830 insertions(+), 928 deletions(-) create mode 100644 OpenGLEngine/OpenGLEngine/BuoyancyComponent.h create mode 100644 OpenGLEngine/OpenGLEngine/BuoyancySystem.cpp create mode 100644 OpenGLEngine/OpenGLEngine/BuoyancySystem.h create mode 100644 OpenGLEngine/OpenGLEngine/DragForceComponent.h create mode 100644 OpenGLEngine/OpenGLEngine/DragForceSystem.cpp create mode 100644 OpenGLEngine/OpenGLEngine/DragForceSystem.h create mode 100644 OpenGLEngine/OpenGLEngine/FireworksComponent.h create mode 100644 OpenGLEngine/OpenGLEngine/FireworksSystem.cpp create mode 100644 OpenGLEngine/OpenGLEngine/FireworksSystem.h create mode 100644 OpenGLEngine/OpenGLEngine/FixedSpringSystem.cpp create mode 100644 OpenGLEngine/OpenGLEngine/FixedSpringSystem.h create mode 100644 OpenGLEngine/OpenGLEngine/ForceAccumulatorComponent.h create mode 100644 OpenGLEngine/OpenGLEngine/GravityForceComponent.h create mode 100644 OpenGLEngine/OpenGLEngine/GravityForceSystem.cpp create mode 100644 OpenGLEngine/OpenGLEngine/GravityForceSystem.h create mode 100644 OpenGLEngine/OpenGLEngine/NBodyComponent.h create mode 100644 OpenGLEngine/OpenGLEngine/NBodySystem.cpp create mode 100644 OpenGLEngine/OpenGLEngine/NBodySystem.h create mode 100644 OpenGLEngine/OpenGLEngine/PairedSpringSystem.cpp create mode 100644 OpenGLEngine/OpenGLEngine/PairedSpringSystem.h diff --git a/OpenGLEngine/OpenGLEngine/BuoyancyComponent.h b/OpenGLEngine/OpenGLEngine/BuoyancyComponent.h new file mode 100644 index 0000000..c877e70 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/BuoyancyComponent.h @@ -0,0 +1,16 @@ +#pragma once +#include "ECSConfig.h" + +namespace Reality +{ + struct BuoyancyComponent + { + BuoyancyComponent(float _maxDepth = 5.0f, float _volume = 1.0f) + :maxDepth(_maxDepth), volume(_volume) + { + + } + float maxDepth; + float volume; + }; +} diff --git a/OpenGLEngine/OpenGLEngine/BuoyancySystem.cpp b/OpenGLEngine/OpenGLEngine/BuoyancySystem.cpp new file mode 100644 index 0000000..bffd87a --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/BuoyancySystem.cpp @@ -0,0 +1,42 @@ +#include "BuoyancySystem.h" +#include "ForceAccumulatorComponent.h" + +namespace Reality +{ + BuoyancySystem::BuoyancySystem() + { + requireComponent(); + } + + void BuoyancySystem::Update(float deltaTime) + { + for (auto e : getEntities()) + { + auto& transform = e.getComponent(); + auto& forceAccumulator = e.getComponent (); + auto& buoyancy = e.getComponent(); + + getWorld().data.renderUtil->DrawCube(transform.position, Vector3(15.0f, 15.0f, 15.0f), Vector3(0, 0, 0),Color::Blue); + + // Calculate the submersion depth + float depth = transform.position.y; + Vector3 force = Vector3(0.0f, 0.0f, 0.0f); + + // Check if we're out of the water + if (depth >= waterHeight + buoyancy.maxDepth) + return; + // Check if we're at maximum depth + else if (depth <= waterHeight - buoyancy.maxDepth) + { + force.y = liquidDensity * buoyancy.volume; + forceAccumulator.AddForce(force); + } + // Otherwise we're partly submerged + else + { + force.y = liquidDensity * buoyancy.volume * (buoyancy.maxDepth - depth - waterHeight) / 2 * buoyancy.maxDepth; + forceAccumulator.AddForce(force); + } + } + } +} diff --git a/OpenGLEngine/OpenGLEngine/BuoyancySystem.h b/OpenGLEngine/OpenGLEngine/BuoyancySystem.h new file mode 100644 index 0000000..84517e8 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/BuoyancySystem.h @@ -0,0 +1,16 @@ +#pragma once +#include "ECSConfig.h" +#include "TransformComponent.h" +#include "BuoyancyComponent.h" + +namespace Reality +{ + class BuoyancySystem : public ECSSystem + { + public: + BuoyancySystem(); + void Update(float deltaTime); + float waterHeight = 5.0f; + float liquidDensity = 10.0f; + }; +} diff --git a/OpenGLEngine/OpenGLEngine/DragForceComponent.h b/OpenGLEngine/OpenGLEngine/DragForceComponent.h new file mode 100644 index 0000000..dec367f --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/DragForceComponent.h @@ -0,0 +1,16 @@ +#pragma once +#include "ECSConfig.h" + +namespace Reality +{ + struct DragForceComponent + { + DragForceComponent(float _k1 = 0.0f, float _k2 = 0.0f) + : k1(_k1), k2(_k2) + { + + } + float k1; + float k2; + }; +} diff --git a/OpenGLEngine/OpenGLEngine/DragForceSystem.cpp b/OpenGLEngine/OpenGLEngine/DragForceSystem.cpp new file mode 100644 index 0000000..591e326 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/DragForceSystem.cpp @@ -0,0 +1,29 @@ +#include "DragForceSystem.h" + +namespace Reality +{ + DragForceSystem::DragForceSystem() + { + requireComponent(); + requireComponent(); + requireComponent(); + } + + void DragForceSystem::Update(float deltaTime) + { + for (auto e : getEntities()) + { + auto& particle = e.getComponent(); + auto& forceAcc = e.getComponent(); + auto& drag = e.getComponent(); + + float speed = glm::length(particle.velocity); + if (speed > 0) + { + Vector3 force = -glm::normalize(particle.velocity); + force *= drag.k1 * speed + drag.k2 * pow(speed, 2); + forceAcc.AddForce(force); + } + } + } +} diff --git a/OpenGLEngine/OpenGLEngine/DragForceSystem.h b/OpenGLEngine/OpenGLEngine/DragForceSystem.h new file mode 100644 index 0000000..d3f21e8 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/DragForceSystem.h @@ -0,0 +1,15 @@ +#pragma once +#include "ECSConfig.h" +#include "ParticleComponent.h" +#include "ForceAccumulatorComponent.h" +#include "DragForceComponent.h" + +namespace Reality +{ + class DragForceSystem : public ECSSystem + { + public: + DragForceSystem(); + void Update(float deltaTime); + }; +} diff --git a/OpenGLEngine/OpenGLEngine/ECSConfig.h b/OpenGLEngine/OpenGLEngine/ECSConfig.h index dee62f8..08fdbcd 100644 --- a/OpenGLEngine/OpenGLEngine/ECSConfig.h +++ b/OpenGLEngine/OpenGLEngine/ECSConfig.h @@ -4,6 +4,7 @@ #include #include #define RANDOM_FLOAT(LO, HI) LO + static_cast (rand()) / (static_cast (RAND_MAX / (HI - LO))) +#define DEBUG_LOG_LEVEL 3 namespace Reality { diff --git a/OpenGLEngine/OpenGLEngine/FPSControlSystem.cpp b/OpenGLEngine/OpenGLEngine/FPSControlSystem.cpp index 39cc7d9..9e18339 100644 --- a/OpenGLEngine/OpenGLEngine/FPSControlSystem.cpp +++ b/OpenGLEngine/OpenGLEngine/FPSControlSystem.cpp @@ -30,6 +30,11 @@ namespace Reality camera.ProcessKeyboard(LEFT, fpsControl.sidewaysSpeed * deltaTime); if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) camera.ProcessKeyboard(RIGHT, fpsControl.sidewaysSpeed * deltaTime); + if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) + { + getWorld().spaceIsPressed += 1; + std::cout << "Space" << std::endl; + } // Look auto mouseMoveEvents = getWorld().getEventManager().getEvents(); diff --git a/OpenGLEngine/OpenGLEngine/FireworksComponent.h b/OpenGLEngine/OpenGLEngine/FireworksComponent.h new file mode 100644 index 0000000..f988802 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/FireworksComponent.h @@ -0,0 +1,20 @@ +#pragma once +#include "ECSConfig.h" + +namespace Reality +{ + struct FireworksComponent + { + FireworksComponent(int _numberOfParticles = 6, int _generation = 3, float _spawnTime = 3, float _velocityScale = 10.0f, Color _color = Color::Green) + :numberOfParticles(_numberOfParticles), generation(_generation), spawnTime(_spawnTime), velocityScale(_velocityScale),color(_color), timer(0.0f) + { + + } + int numberOfParticles; + int generation; + float spawnTime; + float timer; + float velocityScale; + Color color; + }; +} diff --git a/OpenGLEngine/OpenGLEngine/FireworksSystem.cpp b/OpenGLEngine/OpenGLEngine/FireworksSystem.cpp new file mode 100644 index 0000000..3d24430 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/FireworksSystem.cpp @@ -0,0 +1,60 @@ +#include "FireworksSystem.h" +#include "ParticleComponent.h" +#include "ForceAccumulatorComponent.h" +#include "GravityForceComponent.h" + +namespace Reality +{ + FireworksSystem::FireworksSystem() + { + requireComponent(); + requireComponent(); + } + + void FireworksSystem::Update(float deltaTime) + { + for (auto e : getEntities()) + { + auto& transform = e.getComponent(); + auto& fireworks = e.getComponent(); + + fireworks.timer += deltaTime; + if (fireworks.timer > fireworks.spawnTime) + { + if (fireworks.generation > 0) + { + float deltaAngle = 2 * AI_MATH_PI / fireworks.numberOfParticles; + for (int i = 0; i < fireworks.numberOfParticles; i++) + { + auto particle = getWorld().createEntity(); + particle.addComponent(transform.position); + float angle = i * deltaAngle; + Vector3 velocity = Vector3(0, 1, 0); + velocity.x = cos(angle); + velocity.z = sin(angle); + velocity *= fireworks.velocityScale; + particle.addComponent(velocity); + particle.addComponent(); + particle.addComponent(); + float colorAlpha = (float)i / (float)fireworks.numberOfParticles; + particle.addComponent( + fireworks.numberOfParticles, + fireworks.generation - 1, + fireworks.spawnTime + RANDOM_FLOAT(-0.3f, 0.3f), + fireworks.velocityScale, + Color(colorAlpha, 0, 1 - colorAlpha) + ); + + } + } + e.kill(); + } + + + if (DEBUG_LOG_LEVEL > 0) + { + getWorld().data.renderUtil->DrawSphere(transform.position, 1.0f, fireworks.color); + } + } + } +} diff --git a/OpenGLEngine/OpenGLEngine/FireworksSystem.h b/OpenGLEngine/OpenGLEngine/FireworksSystem.h new file mode 100644 index 0000000..c8bdc7f --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/FireworksSystem.h @@ -0,0 +1,14 @@ +#pragma once +#include "ECSConfig.h" +#include "TransformComponent.h" +#include "FireworksComponent.h" + +namespace Reality +{ + class FireworksSystem : public ECSSystem + { + public: + FireworksSystem(); + void Update(float deltaTime); + }; +} diff --git a/OpenGLEngine/OpenGLEngine/FixedSpringComponent.h b/OpenGLEngine/OpenGLEngine/FixedSpringComponent.h index b8b312b..daa14f8 100644 --- a/OpenGLEngine/OpenGLEngine/FixedSpringComponent.h +++ b/OpenGLEngine/OpenGLEngine/FixedSpringComponent.h @@ -5,10 +5,20 @@ namespace Reality { struct FixedSpringComponent { - FixedSpringComponent(float _springConstant = 10, float _restLength = 10, ECSEntity e = ECSEntity()) - :springConstant(_springConstant), restLength(_restLength), entity(e){} + FixedSpringComponent(float _springConstant = 10.0f, + float _restLength = 10.0f, + ECSEntity _connectedEntity = ECSEntity()) + : springConstant(_springConstant), + restLength(_restLength), + connectedEntity(_connectedEntity) + { + + } + /** Holds the spring constant. */ float springConstant; + /** Holds the rest length of the spring. */ float restLength; - ECSEntity entity; + /** The location of the anchored end of the spring. */ + ECSEntity connectedEntity; }; } diff --git a/OpenGLEngine/OpenGLEngine/FixedSpringSystem.cpp b/OpenGLEngine/OpenGLEngine/FixedSpringSystem.cpp new file mode 100644 index 0000000..a9bc461 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/FixedSpringSystem.cpp @@ -0,0 +1,56 @@ +#include "FixedSpringSystem.h" +#include "ForceAccumulatorComponent.h" + +namespace Reality +{ + FixedSpringSystem::FixedSpringSystem() + { + requireComponent(); + requireComponent(); + } + + void FixedSpringSystem::Update(float deltaTime) + { + for (auto e : getEntities()) + { + auto& springTransform = e.getComponent(); + auto& spring = e.getComponent(); + + if (spring.connectedEntity.hasComponent() + && spring.connectedEntity.hasComponent()) + { + auto& forceAcc = spring.connectedEntity.getComponent(); + auto& transform = spring.connectedEntity.getComponent(); + + Vector3 relativePosition = transform.position - springTransform.position; + + float length = glm::length(relativePosition); + if (length > 0) + { + float deltaL = length - spring.restLength; + Vector3 force = -glm::normalize(relativePosition); + force *= spring.springConstant * deltaL; + forceAcc.AddForce(force); + + float g = 1.0f / (1.0f + pow(abs(deltaL), 0.5f)); + float r = 1 - g; + + Color col = Color(r, g, 0, 1); + + float deltaLength = length / 10.0f; + Vector3 direction = -glm::normalize(relativePosition); + for (int i = 0; i < 10; i++) + { + getWorld().data.renderUtil->DrawCube( + transform.position + (float)i * deltaLength * direction, + Vector3(1.0f, 1.0f, 1.0f) * min((spring.restLength / 20.0f), 100.0f), Vector3(0, 0, 0), col); + } + + getWorld().data.renderUtil->DrawLine(springTransform.position, transform.position, + col); + } + + } + } + } +} diff --git a/OpenGLEngine/OpenGLEngine/FixedSpringSystem.h b/OpenGLEngine/OpenGLEngine/FixedSpringSystem.h new file mode 100644 index 0000000..89968b1 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/FixedSpringSystem.h @@ -0,0 +1,14 @@ +#pragma once +#include "ECSConfig.h" +#include "TransformComponent.h" +#include "FixedSpringComponent.h" + +namespace Reality +{ + class FixedSpringSystem : public ECSSystem + { + public: + FixedSpringSystem(); + void Update(float deltaTime); + }; +} diff --git a/OpenGLEngine/OpenGLEngine/ForceAccumulatorComponent.h b/OpenGLEngine/OpenGLEngine/ForceAccumulatorComponent.h new file mode 100644 index 0000000..62ca949 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/ForceAccumulatorComponent.h @@ -0,0 +1,30 @@ +#pragma once +#include "ECSConfig.h" + +namespace Reality +{ + struct ForceAccumulatorComponent + { + ForceAccumulatorComponent(float _mass = 1.0f) + : inverseMass(1.0f / _mass), forceAccumulator(Vector3(0, 0, 0)) + { + + } + float inverseMass; + + inline void AddForce(Vector3 force) + { + forceAccumulator += force; + } + inline void ResetAccumulator() + { + forceAccumulator = Vector3(0, 0, 0); + } + inline Vector3 GetAccumulatedForce() + { + return forceAccumulator; + } + private: + Vector3 forceAccumulator; + }; +} diff --git a/OpenGLEngine/OpenGLEngine/ForceAccumulatorSystem.cpp b/OpenGLEngine/OpenGLEngine/ForceAccumulatorSystem.cpp index d1bbb3d..b4f7c21 100644 --- a/OpenGLEngine/OpenGLEngine/ForceAccumulatorSystem.cpp +++ b/OpenGLEngine/OpenGLEngine/ForceAccumulatorSystem.cpp @@ -1,21 +1,22 @@ #include "ForceAccumulatorSystem.h" - namespace Reality { ForceAccumulatorSystem::ForceAccumulatorSystem() { requireComponent(); + requireComponent(); } - void ForceAccumulatorSystem::Update(float deltaTime) { for (auto e : getEntities()) { - auto &particle = e.getComponent(); - particle.accelaration = particle.GetForce() * particle.inverseMass; - particle.ResetForceAccumulator(); + auto& particle = e.getComponent(); + auto& forceAcc = e.getComponent(); + + particle.acceleration = forceAcc.GetAccumulatedForce() * forceAcc.inverseMass; + forceAcc.ResetAccumulator(); } } } diff --git a/OpenGLEngine/OpenGLEngine/ForceAccumulatorSystem.h b/OpenGLEngine/OpenGLEngine/ForceAccumulatorSystem.h index ff375ad..ce612ed 100644 --- a/OpenGLEngine/OpenGLEngine/ForceAccumulatorSystem.h +++ b/OpenGLEngine/OpenGLEngine/ForceAccumulatorSystem.h @@ -1,6 +1,7 @@ #pragma once #include "ECSConfig.h" #include "ParticleComponent.h" +#include "ForceAccumulatorComponent.h" namespace Reality { @@ -11,4 +12,3 @@ namespace Reality void Update(float deltaTime); }; } - diff --git a/OpenGLEngine/OpenGLEngine/GravityForceComponent.h b/OpenGLEngine/OpenGLEngine/GravityForceComponent.h new file mode 100644 index 0000000..09ad65b --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/GravityForceComponent.h @@ -0,0 +1,15 @@ +#pragma once +#include "ECSConfig.h" + +namespace Reality +{ + struct GravityForceComponent + { + GravityForceComponent(float _gravityScale = 1.0f) + : gravityScale(_gravityScale) + { + + } + float gravityScale; + }; +} diff --git a/OpenGLEngine/OpenGLEngine/GravityForceSystem.cpp b/OpenGLEngine/OpenGLEngine/GravityForceSystem.cpp new file mode 100644 index 0000000..07d38d6 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/GravityForceSystem.cpp @@ -0,0 +1,24 @@ +#include "GravityForceSystem.h" + +namespace Reality +{ + GravityForceSystem::GravityForceSystem() + { + requireComponent(); + requireComponent(); + } + + void GravityForceSystem::Update(float deltaTime) + { + for (auto e : getEntities()) + { + auto& forceAcc = e.getComponent(); + auto& gravity = e.getComponent(); + + if (forceAcc.inverseMass > 0) + { + forceAcc.AddForce(worldGravity * gravity.gravityScale / forceAcc.inverseMass); + } + } + } +} diff --git a/OpenGLEngine/OpenGLEngine/GravityForceSystem.h b/OpenGLEngine/OpenGLEngine/GravityForceSystem.h new file mode 100644 index 0000000..850e359 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/GravityForceSystem.h @@ -0,0 +1,15 @@ +#pragma once +#include "ECSConfig.h" +#include "ForceAccumulatorComponent.h" +#include "GravityForceComponent.h" + +namespace Reality +{ + class GravityForceSystem : public ECSSystem + { + public: + GravityForceSystem(); + void Update(float deltaTime); + Vector3 worldGravity = Vector3(0.0f, -9.8f, 0.0f); + }; +} diff --git a/OpenGLEngine/OpenGLEngine/Main.cpp b/OpenGLEngine/OpenGLEngine/Main.cpp index 91a5161..dbaecd0 100644 --- a/OpenGLEngine/OpenGLEngine/Main.cpp +++ b/OpenGLEngine/OpenGLEngine/Main.cpp @@ -1,69 +1,42 @@ //#define STB_IMAGE_IMPLEMENTATION -#include "UpdateTransformMatricesSystem.h" #include "RenderingSystem.h" -#include "RenderingSystemV2.h" #include "InputEventSystem.h" +#include "FPSControlSystem.h" #include "RotateSystem.h" -#include "ParticleSystem.h" -#include "ParticleSpawnerSystem.h" -#include "GravityForceGeneratorSystem.h" -#include "FixedSpringForceGeneratorSystem.h" +#include "GravityForceSystem.h" +#include "DragForceSystem.h" +#include "NBodySystem.h" +#include "BuoyancySystem.h" +#include "FixedSpringSystem.h" +#include "PairedSpringSystem.h" #include "ForceAccumulatorSystem.h" -#include "PairedSpringForceGeneratorSystem.h" -#include "SphereContactGeneratorSystem.h" -#include "ParticleContactResolutionSystem.h" -#include "CableComponentSystem.h" -#include "RodSystem.h" -#include "ForceAndTorqueAccumulatorSystem.h" -#include "RigidBodySystem.h" -#include "RigidbodyGravityForceGeneratorSystem.h" -#include "ContactGenerationSystem.h" -#include "ContactResolutionSystem.h" -#include "SphereColliderSystem.h" -#include "BoxColliderSystem.h" -#include "MoveInBoundsSystem.h" -#include "FPSControlSystem.h" +#include "ParticleSystem.h" #include "DynamicDirectionalLightSystem.h" #include "DynamicPointLightSystem.h" #include "DynamicSpotLightSystem.h" -#include "FlightSimulatorSystem.h" -#include "FollowCameraSystem.h" -#include "InfiniteSpawnSystem.h" -#include "InfiniteSpawnTargetSystem.h" -#include "AeroControlSystem.h" -#include "SetAerodynamicTensorSystem.h" -#include "AeroSystem.h" -#include "CameraLookSystem.h" -#include "LifeTimeSystem.h" +#include "MouseMoveEvent.h" #include #include #include -#define DEBUG_LOG_LEVEL 3 - using namespace Reality; void LoadShaders(ECSWorld& world); void LoadModels(ECSWorld& world); -void MakeABunchaObjects(ECSWorld& world); -void MakeABunchaSprings(ECSWorld& world); -void MakeABunchaSpheres(ECSWorld& world); -void MakeACable(ECSWorld& world); -void MakeCablesAndRods(ECSWorld& world); -void MakeFlight(ECSWorld& world); -void TestContacts(ECSWorld& world); -void TestCollision(ECSWorld& world); void SetupLights(ECSWorld& world); +void N_Body(ECSWorld& world); +void Buoyancy(ECSWorld& world); int main() { ECSWorld world; + // Init and Load world.data.InitRendering(); //LoadAssets(world); - - world.data.renderUtil->camera.Position = Vector3(0, 15.0f, 100.0f); + + world.data.renderUtil->camera.Position = Vector3(0, 40.0f, 50.0f); world.data.renderUtil->SetFOV(60); // Create entities @@ -71,63 +44,39 @@ int main() auto e = world.createEntity(); e.addComponent(); - //auto wall = world.createEntity(); - //wall.addComponent(Vector3(0, -3.0f, 0.0f), Vector3(0.1f, 0.1f, 0.1f), Vector3(0, 270, 0)); - //// Add mesh - //wall.addComponent("Resources/Models/Sponza-master/sponza.obj"); - SetupLights(world); - //MakeABunchaObjects(world); - //MakeABunchaSpheres(world); - //MakeABunchaSprings(world); - //MakeACable(world); - //akeCablesAndRods(world); - //MakeFlight(world); - //TestContacts(world); - TestCollision(world); + + // Question 1: Bungee Chord + auto particle1 = world.createEntity(); + particle1.addComponent(Vector3(0, 20, -50)); + particle1.addComponent(Vector3(0, 0, 0)); + particle1.addComponent(); + particle1.addComponent(); + + auto spring1 = world.createEntity(); + spring1.addComponent(Vector3(10, 60, -50)); + spring1.addComponent(20.0f, 20.0f, particle1); + + Buoyancy(world); // Question 2: Buoyancy + N_Body(world); // Question 3: N-Body // Create Systems - world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); + world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); + world.getSystemManager().addSystem(); + world.getSystemManager().addSystem(); + world.getSystemManager().addSystem(); + world.getSystemManager().addSystem(); + world.getSystemManager().addSystem(); + world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); + world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); - // Rigidbody Physics - rp3d::CollisionWorld rp3dWorld; - world.getSystemManager().addSystem(rp3dWorld); - world.getSystemManager().addSystem(rp3dWorld); - world.getSystemManager().addSystem(rp3dWorld); - world.getSystemManager().addSystem(rp3dWorld); - world.getSystemManager().addSystem(rp3dWorld); - world.getSystemManager().addSystem(); - - float time = glfwGetTime(); float stepTime = glfwGetTime(); float deltaTime = 0; @@ -142,10 +91,12 @@ int main() // ----------- while (!glfwWindowShouldClose(world.data.renderUtil->window->glfwWindow)) { + GLFWwindow* window = world.data.renderUtil->window->glfwWindow; float current = glfwGetTime(); deltaTime = current - time; deltaTime = 1 / 60.0f; time = glfwGetTime(); + Camera& camera = world.data.renderUtil->camera; world.update(); @@ -159,7 +110,7 @@ int main() { shadersLoaded = world.data.assetLoader->ShadersLoaded(); } - if(shadersLoaded && !modelsLoadStarted) + if (shadersLoaded && !modelsLoadStarted) { LoadModels(world); modelsLoadStarted = true; @@ -172,53 +123,34 @@ int main() // Game Logic Update world.getSystemManager().getSystem().Update(deltaTime); world.getSystemManager().getSystem().Update(deltaTime); - world.getSystemManager().getSystem().Update(deltaTime); - world.getSystemManager().getSystem().Update(deltaTime); - - //Flight Sim - world.getSystemManager().getSystem().Update(deltaTime); - world.getSystemManager().getSystem().Update(deltaTime); - world.getSystemManager().getSystem().Update(deltaTime); - world.getSystemManager().getSystem().Update(deltaTime); - world.getSystemManager().getSystem().Update(deltaTime); - world.getSystemManager().getSystem().Update(deltaTime); - world.getSystemManager().getSystem().Update(deltaTime); - world.getSystemManager().getSystem().Update(deltaTime); + world.getSystemManager().getSystem().Update(deltaTime); + world.getSystemManager().getSystem().Update(deltaTime); // Update Transform - world.getSystemManager().getSystem().Update(deltaTime); + // Physics - float fixedDeltaTime = glfwGetKey(world.data.renderUtil->window->glfwWindow, GLFW_KEY_SPACE) == GLFW_PRESS ? 1 / 60.0f : 0; - //float fixedDeltaTime = 1 / 60.0f; - world.getSystemManager().getSystem().Update(fixedDeltaTime); - world.getSystemManager().getSystem().Update(fixedDeltaTime); - // Particle Force Generators - world.getSystemManager().getSystem().Update(fixedDeltaTime); - world.getSystemManager().getSystem().Update(fixedDeltaTime); - world.getSystemManager().getSystem().Update(fixedDeltaTime); + //float fixedDeltaTime = glfwGetKey(world.data.renderUtil->window->glfwWindow, GLFW_KEY_SPACE) == GLFW_PRESS ? 1 / 60.0f : 0; + float fixedDeltaTime = 1 / 60.0f; + // Force Generator + world.getSystemManager().getSystem().Update(fixedDeltaTime); + world.getSystemManager().getSystem().Update(fixedDeltaTime); + world.getSystemManager().getSystem().Update(fixedDeltaTime); + world.getSystemManager().getSystem().Update(fixedDeltaTime); + + // Force Accumulator world.getSystemManager().getSystem().Update(fixedDeltaTime); + + // Integrator world.getSystemManager().getSystem().Update(fixedDeltaTime); - // Rigiidbody Force Generators and collisions - world.getSystemManager().getSystem().Update(fixedDeltaTime); - world.getSystemManager().getSystem().Update(fixedDeltaTime); - world.getSystemManager().getSystem().Update(fixedDeltaTime); - world.getSystemManager().getSystem().Update(fixedDeltaTime); - world.getSystemManager().getSystem().Update(fixedDeltaTime); - // Physics Solvers - world.getSystemManager().getSystem().Update(fixedDeltaTime); - world.getSystemManager().getSystem().Update(fixedDeltaTime); - world.getSystemManager().getSystem().Update(fixedDeltaTime); - world.getSystemManager().getSystem().Update(fixedDeltaTime); - - world.getSystemManager().getSystem().Update(fixedDeltaTime); - world.getSystemManager().getSystem().Update(fixedDeltaTime); // Rendering Update + ///*** HACK: For the last DrawCall not working on some systems + world.data.renderUtil->DrawCube(Vector3(0, 0, 0), Vector3(0, 0, 0)); + ///*** HACK: For the last DrawCall not working on some systems world.getSystemManager().getSystem().Update(deltaTime); world.getSystemManager().getSystem().Update(deltaTime); world.getSystemManager().getSystem().Update(deltaTime); world.getSystemManager().getSystem().Update(deltaTime); - world.getSystemManager().getSystem().Update(deltaTime); elapsedDeltaTime = glfwGetTime() - time; logicDelta = elapsedDeltaTime - world.data.renderUtil->GetRenderDelta(); @@ -237,11 +169,11 @@ int main() std::string renderString = logic < 10 ? " " + std::to_string(render) : std::to_string(render); int debug = (int)round(debugDelta * 100.0f / deltaTime); std::string debugString = logic < 10 ? " " + std::to_string(debug) : std::to_string(debug); - + world.data.renderUtil->RenderText("Logic : " + logicString + "%" + //+ " | Physics : " + std::to_string((int)round(physicsDelta * 100.0f / deltaTime)) + "%" + - + " | Rendering : " + renderString + "%" + - + " | Debug : " + debugString + "%" + +" | Rendering : " + renderString + "%" + + +" | Debug : " + debugString + "%" , 1680.0f, 1040.0f, 0.25f, Color(0, 1, 1, 1)); } if (DEBUG_LOG_LEVEL > 2) @@ -257,8 +189,49 @@ int main() debugDelta = glfwGetTime() - stepTime; stepTime = glfwGetTime(); + world.data.renderUtil->RenderText("Density: " + std::to_string(world.getSystemManager().getSystem().liquidDensity), 1400.0f, 500.0f, 1.0f, Color(0.5, 0.5, 0.5, 1)); + world.data.renderUtil->SwapBuffers(world.data.renderUtil->window->glfwWindow); + // User Control + if (world.spaceIsPressed % 9 == 1) + { + auto newObj = world.createEntity(); + newObj.addComponent(world.data.renderUtil->camera.Position + + Vector3( + world.data.renderUtil->camera.Front.x * 30, + 10.0f, + world.data.renderUtil->camera.Front.z * 30 + )); + newObj.addComponent(Vector3(0, 0, 0)); + newObj.addComponent(); + newObj.addComponent(); + newObj.addComponent(); + newObj.addComponent(0.5f); + + if (world.spaceIsPressed == 1) + { + auto particle2 = world.createEntity(); + particle2.addComponent(Vector3(0, 0, 0)); + particle2.addComponent(Vector3(0, 0, 0)); + particle2.addComponent(); + particle2.addComponent(); + + auto pairedSpring = world.createEntity(); + pairedSpring.addComponent(20.0f, 20.0f, particle1, particle2); + world.spaceIsPressed += 1; + } + world.spaceIsPressed++; + } + + if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) + world.getSystemManager().getSystem().liquidDensity += 0.1; + if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) + world.getSystemManager().getSystem().liquidDensity -= 0.1; + + if (world.getSystemManager().getSystem().liquidDensity <= 0.1) + world.getSystemManager().getSystem().liquidDensity = 0.1; + // Show FPS in console //std::cout << "FPS : " << 1.0f / deltaTime << std::endl; } @@ -277,364 +250,82 @@ void LoadModels(ECSWorld& world) { world.data.assetLoader->StartModelLoading({ //ModelData("Resources/Models/snowy-mountain-terrain/SnowyMountainMesh.obj"), - //ModelData("Resources/Models/Sponza-master/sponza.obj"), - //ModelData("Resources/Models/nanosuit/nanosuit.obj"),*/ + ModelData("Resources/Models/Sponza-master/sponza.obj"), + ModelData("Resources/Models/nanosuit/nanosuit.obj"), ModelData("Resources/Models/supermarine-spitfire/spitfire.fbx", {{"spitfire_d.png"}}) }); } -void MakeABunchaObjects(ECSWorld& world) -{ - auto e = world.createEntity(); - e.addComponent(Vector3(4, 10.0f, 48), Vector3(0.10f, 0.1f, 0.1f), Vector3(-90, 180, 0)); - // Add mesh - e.addComponent("Resources/Models/supermarine-spitfire/spitfire.fbx"); - e.addComponent(0, 40, 0); - - e = world.createEntity(); - e.addComponent(Vector3(4, 10.0f, -62), Vector3(0.1f, 0.1f, 0.1f), Vector3(-90, 0, 0)); - // Add mesh - e.addComponent("Resources/Models/supermarine-spitfire/spitfire.fbx"); - e.addComponent(0, 40, 0); -} - -void MakeABunchaSprings(ECSWorld& world) +void N_Body(ECSWorld& world) { - auto e = world.createEntity(); - float yOffset = 30; - e.addComponent(Vector3(-2.5f, -5 + yOffset, -3), Vector3(1.0f, 1.0f, 1.0f)); - e.addComponent(); - // Add mesh - e.addComponent("Resources/Models/nanosuit/nanosuit.obj"); - - auto springEntinty = world.createEntity(); - springEntinty.addComponent(Vector3(-2.5f, 0 + yOffset, 3)); - springEntinty.addComponent(8, 2, e); - - auto e2 = world.createEntity(); - e2.addComponent(Vector3(2.5f, -5 + yOffset, -1), Vector3(1.0f, 1.0f, 1.0f)); - e2.addComponent(); - // Add mesh - e2.addComponent("Resources/Models/nanosuit/nanosuit.obj"); - - auto springEntinty2 = world.createEntity(); - springEntinty2.addComponent(Vector3(2.5f, 0 + yOffset, 1)); - springEntinty2.addComponent(5, 5, e2); - - auto pairedSpring = world.createEntity(); - pairedSpring.addComponent(100, 5.0f, e, e2); - - auto e3 = world.createEntity(); - e3.addComponent(Vector3(-7.5f, -7.5f + yOffset, 1), Vector3(1.0f, 1.0f, 1.0f)); - e3.addComponent(); - // Add mesh - e3.addComponent("Resources/Models/nanosuit/nanosuit.obj"); - - auto springEntinty3 = world.createEntity(); - springEntinty3.addComponent(Vector3(-7.5f, -10 + yOffset, -1)); - springEntinty3.addComponent(7, 7, e3); - - auto e4 = world.createEntity(); - e4.addComponent(Vector3(7.5f, -7.5f + yOffset, 3), Vector3(1.0f, 1.0f, 1.0f)); - e4.addComponent(); - // Add mesh - e4.addComponent("Resources/Models/nanosuit/nanosuit.obj"); - - auto springEntinty4 = world.createEntity(); - springEntinty4.addComponent(Vector3(7.5f, -10 + yOffset, -3)); - springEntinty4.addComponent(5, 0, e4); - - auto pairedSpring2 = world.createEntity(); - pairedSpring2.addComponent(100, 5.2f, e, e3); - - auto pairedSpring3 = world.createEntity(); - pairedSpring3.addComponent(100, 5.2f, e2, e4); - - auto pairedSpring4 = world.createEntity(); - pairedSpring4.addComponent(100, 10.0f, e3, e4); -} - -void MakeABunchaSpheres(ECSWorld& world) -{ - for (int i = 0; i < 30; i++) - { - auto e = world.createEntity(); - //e.addComponent(Vector3(RANDOM_FLOAT(-1, 1), 20,0)); - - e.addComponent(Vector3(RANDOM_FLOAT(-15.0f, 15.0f), RANDOM_FLOAT(6.0f, 34.0f), RANDOM_FLOAT(-15.0f, 15.0f))); - e.addComponent(1, Vector3(RANDOM_FLOAT(-5, 5), RANDOM_FLOAT(-5, 5), RANDOM_FLOAT(-5, 5))); - e.addComponent(1); - Color col = Color(0, RANDOM_FLOAT(0.0f, 1.0f), RANDOM_FLOAT(0.0f, 1.0f)); - //e.addComponent(20.0f, col, col, col); - } - - auto ref = world.createEntity(); - ref.addComponent(Vector3(0, 20, 0), Vector3(0.3f, 0.3f, 0.3f), Vector3(0, 180, 0)); - // Add mesh - ref.addComponent("Resources/Models/nanosuit/nanosuit.obj"); - ref.addComponent(0, 40, 0); -} - -void MakeACable(ECSWorld& world) -{ - auto e1 = world.createEntity(); - e1.addComponent(Vector3(0, 40, 0)); - //e1.addComponent(1, Vector3(0,0,0), 0); - - auto e2 = world.createEntity(); - e2.addComponent(Vector3(0, 30, 0)); - e2.addComponent(1); - - auto e = world.createEntity(); - e.addComponent(e1, e2, 20); -} - -void MakeCablesAndRods(ECSWorld& world) -{ - auto eFixed = world.createEntity(); - eFixed.addComponent(Vector3(10, 40, 0)); - //e1.addComponent(1, Vector3(0,0,0), 0); - - auto eFixed2 = world.createEntity(); - eFixed2.addComponent(Vector3(20, 10, 0)); - - auto eFixed3 = world.createEntity(); - eFixed3.addComponent(Vector3(-20, 10, 0)); - - auto e1 = world.createEntity(); - e1.addComponent(Vector3(0, 30, 0)); - e1.addComponent(10); - - auto e2 = world.createEntity(); - e2.addComponent(Vector3(-10, 20, 0)); - e2.addComponent(10); - - auto e3 = world.createEntity(); - e3.addComponent(Vector3(0, 10, 0)); - e3.addComponent(10); - - auto e4 = world.createEntity(); - e4.addComponent(Vector3(10, 20, 0)); - e4.addComponent(10); - - auto eCable = world.createEntity(); - eCable.addComponent(eFixed, e1, 20); - - auto eCable2 = world.createEntity(); - eCable2.addComponent(1000, 20, eFixed2, e4); - - auto eCable3 = world.createEntity(); - eCable3.addComponent(1000, 20, eFixed3, e2); - - auto eRod1 = world.createEntity(); - eRod1.addComponent(e1, e2, 10 * sqrt(2)); - auto eRod2 = world.createEntity(); - eRod2.addComponent(e2, e3, 10 * sqrt(2)); - auto eRod3 = world.createEntity(); - eRod3.addComponent(e3, e4, 10 * sqrt(2)); - auto eRod4 = world.createEntity(); - eRod4.addComponent(e4, e1, 10 * sqrt(2)); - - auto eRodDiagonal1 = world.createEntity(); - eRodDiagonal1.addComponent(e1, e3, 20); - auto eRodDiagonal2 = world.createEntity(); - eRodDiagonal2.addComponent(e2, e4, 20); -} - -void MakeFlight(ECSWorld& world) -{ - auto e = world.createEntity(); - glm::vec3 rotationInRads = glm::vec3(glm::radians(-90.0f), - glm::radians(180.0f), glm::radians(0.0f)); - Quaternion orientation = glm::quat(rotationInRads); - e.addComponent(Vector3(0, 350.0f, 0), Vector3(0.10f, 0.1f, 0.1f)); - // Add mesh - e.addComponent("Resources/Models/supermarine-spitfire/spitfire.fbx", Vector3(0, -50, 20), Vector3(-90, 0, 0)); - e.addComponent(10.0f ,0.3f, 0.5f); - e.addComponent(); - e.addComponent(Vector3(0.0f, 15.0f, 40.0f)); - e.addComponent(); - e.addComponent(); - - std::vector p1 { GLFW_KEY_E }; - std::vector n1 { GLFW_KEY_Q }; - //Right Wing - auto RW = world.createEntity(); - RW.addComponent(p1, n1); - RW.addComponent(Mat3(0, 0, 0, 0, 0.000f, 0, 0, -0.0005f, 0), - Mat3(0, 0, 0, 0, 0, 0, 0, 0, 0), - Mat3(0, 0, 0, 0, -0.000f, 0, 0, 0.0005f, 0)); - RW.addComponent(e, Mat3(1.0f), Vector3(100.0f, 0, 50.0f)); - - //Left Wing - auto LW = world.createEntity(); - LW.addComponent(n1, p1); - LW.addComponent(Mat3(0, 0, 0, 0, 0.000f, 0, 0, -0.0005f, 0), - Mat3(0, 0, 0, 0, 0, 0, 0, 0, 0), - Mat3(0, 0, 0, 0, -0.000f, 0, 0, 0.0005f, 0)); - LW.addComponent(e, Mat3(1.0f), Vector3(-100.0f, 0, 50.0f)); - - //Rudder - std::vector pR = { GLFW_KEY_A }; - std::vector nR = { GLFW_KEY_D }; - auto R = world.createEntity(); - R.addComponent(pR, nR); - R.addComponent(Mat3(0, 0, 0, 0, 0, 0, 0.002f, 0, 0), - Mat3(0, 0, 0, 0, 0, 0, 0.00f, 0, 0), - Mat3(0, 0, 0, 0, 0, 0, -0.002f, 0, 0)); - R.addComponent(e, Mat3(1.0f), Vector3(0, 0, -200.0f)); - - //Back Wing - std::vector p2{ GLFW_KEY_W }; - std::vector n2{ GLFW_KEY_S }; - auto RW2 = world.createEntity(); - RW2.addComponent(p2, n2); - RW2.addComponent(Mat3(0, 0, 0, 0, 0, 0, 0, -0.0015f, 0), - Mat3(0, 0, 0, 0, 0, 0, 0, 0, 0), - Mat3(0, 0, 0, 0, 0, 0, 0, 0.0015f, 0)); - RW2.addComponent(e, Mat3(1.0f), Vector3(0.0f, 0, -200.0f)); - - for (int i = -40; i <= 40; i++) - { - auto buildingR = world.createEntity(); - buildingR.addComponent(Vector3(100.0f, 0.0f, 50.0f * i)); - buildingR.addComponent(RANDOM_FLOAT(100.0f, 500.0f)); - - auto buildingL = world.createEntity(); - buildingL.addComponent(Vector3(-100.0f, 0.0f, 50.0f * i)); - buildingL.addComponent(RANDOM_FLOAT(100.0f, 500.0f)); - } -} - -void TestContacts(ECSWorld& world) -{ - for (int i = 0; i < 30; i++) + for (int i = 0; i < 10; i++) { - auto e = world.createEntity(); - e.addComponent(Vector3(RANDOM_FLOAT(-200.0f, 200.0f), RANDOM_FLOAT(-200.0f, 200.0f), RANDOM_FLOAT(-200.0f, 200.0f)), - Vector3(1, 1, 1), - Vector3(RANDOM_FLOAT(-180.0f, 180.0f), RANDOM_FLOAT(-180.0f, 180.0f), RANDOM_FLOAT(-180.0f, 180.0f))); - e.addComponent(); - e.addComponent(Vector3(RANDOM_FLOAT(-10.0f, 10.0f), RANDOM_FLOAT(-10.0f, 10.0f), RANDOM_FLOAT(-10.0f, 10.0f)), - Vector3(200, 200, 200)); - auto col = world.createEntity(); - if ((RANDOM_FLOAT(0.0f, 1.0f) >= 0.5f)) - { - col.addComponent(e, RANDOM_FLOAT(10.0f, 50.0f)); - } - else - { - col.addComponent(e, Vector3(RANDOM_FLOAT(30.0f, 70.0f), RANDOM_FLOAT(30.0f, 70.0f), RANDOM_FLOAT(30.0f, 70.0f))); - } + auto particles = world.createEntity(); + particles.addComponent(Vector3(RANDOM_FLOAT(0.0f, 50.0f), RANDOM_FLOAT(0.0f, 50.0f), RANDOM_FLOAT(0.0f, 50.0f))); + particles.addComponent(Vector3(0, 0, 0)); + particles.addComponent(); + particles.addComponent(); } - /*for (int i = 0; i < 2; i++) - { - auto e = world.createEntity(); - e.addComponent(Vector3(50 * ( i % 2 == 0 ? -1 : 1), 0, 0)); - e.addComponent(); - e.addComponent(Vector3(10 * (i % 2 == 0 ? 1 : -1), 0, 0), Vector3(100, 100, 100)); - auto col = world.createEntity(); - col.addComponent(e, 30); - }*/ } -void TestCollision(ECSWorld& world) +void Buoyancy(ECSWorld& world) { - // Floor 1 - auto floor1 = world.createEntity(); - floor1.addComponent(Vector3(0, -50, 0), Vector3(1, 1, 1), Vector3(0, 0, 0)); - floor1.addComponent(100000.0f, 0.4f, 0.3f, Vector3(0, 0, 0), Vector3(0, 0, 0), 0); - auto floorCol1 = world.createEntity(); - floorCol1.addComponent(floor1, Vector3(1000, 10, 1000)); - - // Floor 2 - /*auto floor2 = world.createEntity(); - floor2.addComponent(Vector3(80, -50, 0), Vector3(1, 1, 1), Vector3(0, 0, 30)); - floor2.addComponent(10000.0f, 0.0f, 0.0f, Vector3(0, 0, 0), Vector3(0, 0, 0), 0); - auto floorCol2 = world.createEntity(); - floorCol2.addComponent(floor2, Vector3(300, 10, 300));*/ - - //// Object 1 - //auto object1 = world.createEntity(); - //object1.addComponent(Vector3(-30, 50, 0)); - //object1.addComponent(); - //auto objectCol1 = world.createEntity(); - //objectCol1.addComponent(object1, 10); - - // Object 2 - for (int i = 0; i < 40; i++) - { - auto object2 = world.createEntity(); - object2.addComponent(Vector3(RANDOM_FLOAT(-50.0f, 50.0f), 50, RANDOM_FLOAT(-50.0f, 50.0f)), Vector3(1, 1, 1), Vector3(RANDOM_FLOAT(0, 180), RANDOM_FLOAT(0, 180), RANDOM_FLOAT(0, 180))); - object2.addComponent(10.0f, 0.1f, 0.1f, Vector3(0, 0, 0), Vector3(0, 0, 0), 5); - auto objectCol2 = world.createEntity(); - objectCol2.addComponent(object2, Vector3(10, 10, 10)); - } + auto particle = world.createEntity(); + particle.addComponent(Vector3(0, 10.0f, 0)); + particle.addComponent(Vector3(0, 0, 0)); + particle.addComponent(); + particle.addComponent(); + particle.addComponent(); + particle.addComponent(0.5f); } void SetupLights(ECSWorld& world) { auto l = world.createEntity(); l.addComponent(Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(90, 0, 0)); - l.addComponent(Color(0.00, 0.0, 0), Color::White, Color::Orange); + l.addComponent(Color(0.0, 0.1, 0.1), Color(0.0, 0.1, 0.1), Color(0.0, 0.1, 0.1)); // Lanterns auto pl1 = world.createEntity(); pl1.addComponent(Vector3(22, 14, 48.5f)); pl1.addComponent(100.0f, Color(0.1, 0, 0), Color(1.0f, 0.0f, 0.0f), Color(1.0f, 0.0f, 0.0f)); - pl1.addComponent(); auto hook = world.createEntity(); hook.addComponent(Vector3(23, 15, 48.0f)); - hook.addComponent(5, 1, pl1); hook = world.createEntity(); hook.addComponent(Vector3(22, 13.5f, 50.5f)); - hook.addComponent(5, 1, pl1); hook = world.createEntity(); hook.addComponent(Vector3(21, 12.5f, 47.5f)); - hook.addComponent(5, 1, pl1); auto pl2 = world.createEntity(); pl2.addComponent(Vector3(-14.5f, 14, 49.0f)); pl2.addComponent(100.0f, Color(0, 0, 0.1f), Color(0.0f, 0.0f, 1.0f), Color(0.0f, 0.0f, 1.0f)); - pl2.addComponent(); hook = world.createEntity(); hook.addComponent(Vector3(-14.5f + 1, 14 - 1, 49.0f - 1)); - hook.addComponent(5, 1, pl2); hook = world.createEntity(); hook.addComponent(Vector3(-14.5f - 0.5f, 14 + 1, 49.0f)); - hook.addComponent(5, 1, pl2); hook = world.createEntity(); hook.addComponent(Vector3(-14.5f, 14 - 1, 49.0f + 1)); - hook.addComponent(5, 1, pl2); - + auto pl3 = world.createEntity(); pl3.addComponent(Vector3(22, 14, -62.0f)); pl3.addComponent(100.0f, Color(0, 0.1f, 0), Color(0.0f, 1.0f, 0.0f), Color(0.0f, 1.0f, 0.0f)); - pl3.addComponent(); hook = world.createEntity(); hook.addComponent(Vector3(22 - 1, 14 - 1, -62.0f)); - hook.addComponent(5, 1, pl3); hook = world.createEntity(); hook.addComponent(Vector3(22, 14 + 0.5f, -62.0f - 1)); - hook.addComponent(5, 1, pl3); hook = world.createEntity(); hook.addComponent(Vector3(22 + 1, 14, -62.0f + 0.5f)); - hook.addComponent(5, 1, pl3); auto pl4 = world.createEntity(); pl4.addComponent(Vector3(-14.5f, 14, -61.5f)); pl4.addComponent(100.0f, Color(0.1, 0.05, 0), Color(1.0f, 0.55f, 0.0f), Color(1.0f, 0.55f, 0.0f)); - pl4.addComponent(); hook = world.createEntity(); - hook.addComponent(Vector3(-14.5f - 1, 14, -61.5f -1)); - hook.addComponent(5, 1, pl4); + hook.addComponent(Vector3(-14.5f - 1, 14, -61.5f - 1)); hook = world.createEntity(); hook.addComponent(Vector3(-14.5f - 0.25f, 14 - 0.5f, -61.5f + 1)); - hook.addComponent(5, 1, pl4); hook = world.createEntity(); - hook.addComponent(Vector3(-14.5f + 0.5f, 14+ 1, -61.5f + 1)); - hook.addComponent(5, 1, pl4); + hook.addComponent(Vector3(-14.5f + 0.5f, 14 + 1, -61.5f + 1)); // Spears std::vector cols = { Color(1,0,0), Color(0,1,0), Color(0,0,1), Color(0.7f,0.55f,0) }; @@ -645,7 +336,6 @@ void SetupLights(ECSWorld& world) pl1 = world.createEntity(); pl1.addComponent(Vector3((i % 2 == 0 ? 8 : -1), 85, 49.5f - 37 * j), Vector3(1, 1, 1), Vector3(180, 0, 0)); pl1.addComponent(10.0f, 100, Color(0, 0, 0), cols[3 - j], cols[3 - j], 5); - pl1.addComponent((i % 2 == 0 ? 1 : -1) * 100,100,100); } } } \ No newline at end of file diff --git a/OpenGLEngine/OpenGLEngine/Mix/World.h b/OpenGLEngine/OpenGLEngine/Mix/World.h index 69e7598..6445b3e 100644 --- a/OpenGLEngine/OpenGLEngine/Mix/World.h +++ b/OpenGLEngine/OpenGLEngine/Mix/World.h @@ -39,6 +39,8 @@ class World WorldData data; + int spaceIsPressed = 0; + private: // vector of entities that are awaiting creation std::vector createdEntities; diff --git a/OpenGLEngine/OpenGLEngine/NBodyComponent.h b/OpenGLEngine/OpenGLEngine/NBodyComponent.h new file mode 100644 index 0000000..4cbd546 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/NBodyComponent.h @@ -0,0 +1,16 @@ +#pragma once +#include "ECSConfig.h" + +namespace Reality +{ + struct NBodyComponent + { + NBodyComponent(float _mass = 10.0f, Color _color = Color::Green) + :mass(_mass), color(_color) + { + + } + float mass; + Color color; + }; +} diff --git a/OpenGLEngine/OpenGLEngine/NBodySystem.cpp b/OpenGLEngine/OpenGLEngine/NBodySystem.cpp new file mode 100644 index 0000000..57d3b21 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/NBodySystem.cpp @@ -0,0 +1,35 @@ +#include "NBodySystem.h" +#include "ParticleComponent.h" +#include "ForceAccumulatorComponent.h" +#include "GravityForceComponent.h" + +namespace Reality +{ + NBodySystem::NBodySystem() + { + requireComponent(); + requireComponent(); + } + + void NBodySystem::Update(float deltaTime) + { + for (int i = 0; i < getEntities().size(); i++) + { + for (int j = i + 1; j < getEntities().size(); j++) + { + Vector3 vectorBetweenParticles = Vector3(getEntities()[i].getComponent().position - getEntities()[j].getComponent().position); + float distance = glm::length(vectorBetweenParticles); + // F = G * m1m2 / r^2 + float gravity = 9.8 * ((getEntities()[i].getComponent().mass) * (getEntities()[j].getComponent().mass)) / (distance * distance); + // Calculate and add force + Vector3 Force = vectorBetweenParticles * gravity; + getEntities()[j].getComponent().AddForce(Force); + } + } + + for (auto e : getEntities()) + { + getWorld().data.renderUtil->DrawSphere(e.getComponent().position, 1.0f, Color::White); + } + } +} diff --git a/OpenGLEngine/OpenGLEngine/NBodySystem.h b/OpenGLEngine/OpenGLEngine/NBodySystem.h new file mode 100644 index 0000000..1a79976 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/NBodySystem.h @@ -0,0 +1,14 @@ +#pragma once +#include "ECSConfig.h" +#include "TransformComponent.h" +#include "NBodyComponent.h" + +namespace Reality +{ + class NBodySystem : public ECSSystem + { + public: + NBodySystem(); + void Update(float deltaTime); + }; +} diff --git a/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj b/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj index dbb8b45..3b732f1 100644 --- a/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj +++ b/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj @@ -22,7 +22,7 @@ 15.0 {BF971B9A-9ACC-4B50-8E62-4CC32E780AA5} OpenGLEngine - 10.0.17763.0 + 10.0.18362.0 @@ -121,30 +121,13 @@ - - - - - - - - - - - - - - + - - - - - + @@ -160,33 +143,21 @@ - - - - - - + - - + - - - + - - - - @@ -196,109 +167,49 @@ - - - - - - - - - - - - - - - + - + - + - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - + + - + - @@ -320,54 +231,33 @@ - - - + - + - + - - + - - - - - - + - - - - - - + - - - - - - - - @@ -379,86 +269,46 @@ - + - + - - - - - - - - - - + - - + - + - + - - - - - - - - - + + + + - - - - + - - - - - - - - - - - - - - - - - - - - - - diff --git a/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj.filters b/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj.filters index 0199877..e9a3f90 100644 --- a/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj.filters +++ b/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj.filters @@ -43,12 +43,27 @@ {09a9940b-c17f-43c0-becf-d8da8efa3d30} - - {1a9d715c-69e4-4d0c-b881-159070a97fa6} - {3f5a8043-c367-47f5-bbe1-005323d21b00} + + {3b57134f-d90e-46bd-8888-c0777df6a173} + + + {ca789051-cc7e-4ee6-b5e9-0588e346445c} + + + {d837795e-a627-4903-896c-26f4fa36fcd1} + + + {3d4ccf92-2e99-4fba-ad16-d06712865eed} + + + {fdf89afd-47b6-4a61-b7bc-48f65fe356f2} + + + {a8329ac4-3b10-441c-af9c-a98085741757} + @@ -81,27 +96,9 @@ ECSCore - - TestCS - - - Physics\Particles - - - Physics\Particles - - - Physics\Particles - - - Physics\Particles - Input - - TestCS - Rendering @@ -126,86 +123,41 @@ Rendering - - TestCS - - - TestCS - - - TestCS - Rendering - - ComponentsCore - - + Rendering - - TestCS\FlightSim - - - TestCS\FlightSim - - - TestCS\FlightSim - - - TestCS\FlightSim - - + TestCS - + TestCS - - TestCS\FlightSim - - - TestCS\FlightSim - - - TestCS\FlightSim - - - Rendering - - - Physics\Rigidbody - - - Physics\Rigidbody - - + Physics\Particles - - Physics\Rigidbody - - - Physics\Rigidbody + + Physics\Particles - - Physics\Rigidbody + + Physics\Particles\ForceGenerators - - Physics\Particles + + Physics\Particles\ForceGenerators\Buoyancy - - Physics\Particles + + Physics\Particles\ForceGenerators\NBody - - Physics\Rigidbody + + Physics\Particles\ForceGenerators\DragForce - - TestCS + + Physics\Particles\ForceGenerators\FixedSpring - - Physics\Rigidbody + + Physics\Particles\ForceGenerators\PairedSpring @@ -272,42 +224,12 @@ ECSCore - - TestCS - - - TestCS - - - Physics\Particles - - - Physics\Particles - - - Physics\Particles - - - Physics\Particles - - - Physics\Particles - - - Physics\Particles - Input Input - - TestCS - - - TestCS - Rendering @@ -332,155 +254,68 @@ Rendering - - TestCS - - - TestCS - - - TestCS - - - TestCS - - - TestCS - - - TestCS - - - ComponentsCore - - - ComponentsCore - - + Rendering - - TestCS\FlightSim - - - TestCS\FlightSim - - - TestCS\FlightSim - - - TestCS\FlightSim - - - TestCS\FlightSim - - - TestCS\FlightSim - - - TestCS\FlightSim - - - TestCS\FlightSim - - + TestCS - + TestCS - + TestCS - + TestCS - - TestCS\FlightSim - - - TestCS\FlightSim - - - TestCS\FlightSim - - - TestCS\FlightSim - - - TestCS\FlightSim - - - TestCS\FlightSim - - - TestCS\FlightSim - - - Rendering - - - Physics\Rigidbody - - - Physics\Rigidbody - - - Physics\Rigidbody - - - Physics\Rigidbody + + Physics\Particles - + Physics\Particles - + Physics\Particles - - Physics\Rigidbody + + Physics\Particles - - Physics\Rigidbody + + Physics\Particles\ForceGenerators - - Physics\Rigidbody + + Physics\Particles\ForceGenerators - - Physics\Rigidbody + + Physics\Particles\ForceGenerators\Buoyancy - - Physics\Rigidbody + + Physics\Particles\ForceGenerators\Buoyancy - - Physics\Rigidbody + + Physics\Particles\ForceGenerators\NBody - - Physics\Particles + + Physics\Particles\ForceGenerators\NBody - - Physics\Particles + + Physics\Particles\ForceGenerators\DragForce - - Physics\Particles - - - Physics\Particles - - - Physics\Rigidbody + + Physics\Particles\ForceGenerators\DragForce - - Physics\Rigidbody + + Physics\Particles\ForceGenerators\FixedSpring - - TestCS + + Physics\Particles\ForceGenerators\FixedSpring - - TestCS + + Physics\Particles\ForceGenerators\PairedSpring - - Physics\Rigidbody + + Physics\Particles\ForceGenerators\PairedSpring diff --git a/OpenGLEngine/OpenGLEngine/PairedSpringComponent.h b/OpenGLEngine/OpenGLEngine/PairedSpringComponent.h index 88bf9a9..0511892 100644 --- a/OpenGLEngine/OpenGLEngine/PairedSpringComponent.h +++ b/OpenGLEngine/OpenGLEngine/PairedSpringComponent.h @@ -5,11 +5,20 @@ namespace Reality { struct PairedSpringComponent { - PairedSpringComponent(float _springConstant = 10, float _restLength = 10, ECSEntity a = ECSEntity(), ECSEntity b = ECSEntity()) - :springConstant(_springConstant), restLength(_restLength), entityA(a), entityB(b) {} + PairedSpringComponent(float _springConstant = 10.0f, + float _restLength = 10.0f, + ECSEntity _connectedEntityA = ECSEntity(), + ECSEntity _connectedEntityB = ECSEntity()) + : springConstant(_springConstant), + restLength(_restLength), + connectedEntityA(_connectedEntityA), + connectedEntityB(_connectedEntityB) + { + + } float springConstant; float restLength; - ECSEntity entityA; - ECSEntity entityB; + ECSEntity connectedEntityA; + ECSEntity connectedEntityB; }; -} \ No newline at end of file +} diff --git a/OpenGLEngine/OpenGLEngine/PairedSpringSystem.cpp b/OpenGLEngine/OpenGLEngine/PairedSpringSystem.cpp new file mode 100644 index 0000000..250f84c --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/PairedSpringSystem.cpp @@ -0,0 +1,61 @@ +#include "PairedSpringSystem.h" +#include "TransformComponent.h" +#include "ForceAccumulatorComponent.h" + +namespace Reality +{ + PairedSpringSystem::PairedSpringSystem() + { + requireComponent(); + } + + void PairedSpringSystem::Update(float deltaTime) + { + for (auto e : getEntities()) + { + auto& spring = e.getComponent(); + + if (spring.connectedEntityA.hasComponent() + && spring.connectedEntityB.hasComponent()) + { + auto& transformA = spring.connectedEntityA.getComponent(); + auto& transformB = spring.connectedEntityB.getComponent(); + + Vector3 relativePosition = transformA.position - transformB.position; + float length = glm::length(relativePosition); + if (length > 0) + { + float deltaL = length - spring.restLength; + Vector3 force = -glm::normalize(relativePosition); + force *= spring.springConstant * deltaL; + + if (spring.connectedEntityA.hasComponent()) + { + spring.connectedEntityA.getComponent().AddForce(force); + } + if (spring.connectedEntityB.hasComponent()) + { + spring.connectedEntityB.getComponent().AddForce(-force); + } + + float g = 1.0f / (1.0f + pow(abs(deltaL), 0.5f)); + float r = 1 - g; + + Color col = Color(r, g, 0, 1); + + float deltaLength = length / 10.0f; + Vector3 direction = glm::normalize(relativePosition); + for (int i = 0; i < 10; i++) + { + getWorld().data.renderUtil->DrawCube( + transformB.position + (float)i * deltaLength * direction, + Vector3(1.0f, 1.0f, 1.0f) * min((spring.restLength / 20.0f), 100.0f), Vector3(0, 0, 0), col); + } + getWorld().data.renderUtil->DrawLine(transformA.position, transformB.position, + col); + } + + } + } + } +} diff --git a/OpenGLEngine/OpenGLEngine/PairedSpringSystem.h b/OpenGLEngine/OpenGLEngine/PairedSpringSystem.h new file mode 100644 index 0000000..5cf0204 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/PairedSpringSystem.h @@ -0,0 +1,13 @@ +#pragma once +#include "ECSConfig.h" +#include "PairedSpringComponent.h" + +namespace Reality +{ + class PairedSpringSystem : public ECSSystem + { + public: + PairedSpringSystem(); + void Update(float deltaTime); + }; +} diff --git a/OpenGLEngine/OpenGLEngine/ParticleComponent.h b/OpenGLEngine/OpenGLEngine/ParticleComponent.h index 3c7e057..2580c48 100644 --- a/OpenGLEngine/OpenGLEngine/ParticleComponent.h +++ b/OpenGLEngine/OpenGLEngine/ParticleComponent.h @@ -5,30 +5,12 @@ namespace Reality { struct ParticleComponent { - ParticleComponent(float mass = 1.0f, Vector3 _velocity = Vector3(0,0,0), float _gravityScale = 1) : - velocity(_velocity), gravityScale(_gravityScale) + ParticleComponent(Vector3 _velocity = Vector3(0, 0, 0)) + :velocity(_velocity), acceleration(Vector3(0, 0, 0)) { - inverseMass = 1 / mass; - accelaration = Vector3(0, 0, 0); - forceAccumulator = Vector3(0, 0, 0); + } + Vector3 acceleration; Vector3 velocity; - Vector3 accelaration; - float inverseMass; - float gravityScale; - inline void AddForce(Vector3 force) - { - forceAccumulator += force; - } - inline Vector3 GetForce() - { - return forceAccumulator; - } - inline void ResetForceAccumulator() - { - forceAccumulator = Vector3(0, 0, 0); - } - private: - Vector3 forceAccumulator; }; } diff --git a/OpenGLEngine/OpenGLEngine/ParticleSystem.cpp b/OpenGLEngine/OpenGLEngine/ParticleSystem.cpp index 41744a2..ce93b11 100644 --- a/OpenGLEngine/OpenGLEngine/ParticleSystem.cpp +++ b/OpenGLEngine/OpenGLEngine/ParticleSystem.cpp @@ -1,6 +1,5 @@ #include "ParticleSystem.h" - namespace Reality { ParticleSystem::ParticleSystem() @@ -13,20 +12,10 @@ namespace Reality { for (auto e : getEntities()) { - auto &particle = e.getComponent(); - auto &transform = e.getComponent(); - - // HACK for bounce - if (transform.position.y <= -10) - { - //particle.velocity.y = -particle.velocity.y; - //e.kill(); - } - - // Update velocity from accelarartion - particle.velocity += particle.accelaration * deltaTime; + auto& transform = e.getComponent(); + auto& particle = e.getComponent(); - // Update position from velocity + particle.velocity += particle.acceleration * deltaTime; transform.position += particle.velocity * deltaTime; } } diff --git a/OpenGLEngine/OpenGLEngine/ParticleSystem.h b/OpenGLEngine/OpenGLEngine/ParticleSystem.h index 4c69212..2c926e8 100644 --- a/OpenGLEngine/OpenGLEngine/ParticleSystem.h +++ b/OpenGLEngine/OpenGLEngine/ParticleSystem.h @@ -12,4 +12,3 @@ namespace Reality void Update(float deltaTime); }; } - diff --git a/OpenGLEngine/OpenGLEngine/RotateComponent.h b/OpenGLEngine/OpenGLEngine/RotateComponent.h index ecc5968..bde45b6 100644 --- a/OpenGLEngine/OpenGLEngine/RotateComponent.h +++ b/OpenGLEngine/OpenGLEngine/RotateComponent.h @@ -1,9 +1,15 @@ #pragma once -struct RotateComponent +#include "ECSConfig.h" + +namespace Reality { - float xRot; - float yRot; - float zRot; - RotateComponent(float x = 0, float y = 0, float z = 0) - : xRot(x), yRot(y), zRot(z) {} -}; + struct RotateComponent + { + RotateComponent(Vector3 _rotationVelocity = Vector3(0, 0, 0)) + : rotationVelocity(_rotationVelocity) + { + + } + Vector3 rotationVelocity; + }; +} diff --git a/OpenGLEngine/OpenGLEngine/RotateSystem.cpp b/OpenGLEngine/OpenGLEngine/RotateSystem.cpp index 6bd16a0..19146ff 100644 --- a/OpenGLEngine/OpenGLEngine/RotateSystem.cpp +++ b/OpenGLEngine/OpenGLEngine/RotateSystem.cpp @@ -1,20 +1,21 @@ #include "RotateSystem.h" -RotateSystem::RotateSystem() +namespace Reality { - requireComponent(); - requireComponent(); -} + RotateSystem::RotateSystem() + { + requireComponent(); + requireComponent(); + } -void RotateSystem::Update(float deltaTime) -{ - for (auto e : getEntities()) + void RotateSystem::Update(float deltaTime) { - auto &rotate = e.getComponent(); - auto &transform = e.getComponent(); + for (auto e : getEntities()) + { + auto& transform = e.getComponent(); + auto& rotate = e.getComponent(); - transform.eulerAngles.x += rotate.xRot * deltaTime; - transform.eulerAngles.y += rotate.yRot * deltaTime; - transform.eulerAngles.z += rotate.zRot * deltaTime; + transform.eulerAngles += rotate.rotationVelocity * deltaTime; + } } } diff --git a/OpenGLEngine/OpenGLEngine/RotateSystem.h b/OpenGLEngine/OpenGLEngine/RotateSystem.h index 1a9cc29..76a4255 100644 --- a/OpenGLEngine/OpenGLEngine/RotateSystem.h +++ b/OpenGLEngine/OpenGLEngine/RotateSystem.h @@ -3,11 +3,12 @@ #include "TransformComponent.h" #include "RotateComponent.h" -using namespace Reality; -class RotateSystem : public ECSSystem +namespace Reality { -public: - RotateSystem(); - void Update(float deltaTime); -}; - + class RotateSystem : public ECSSystem + { + public: + RotateSystem(); + void Update(float deltaTime); + }; +} From 604995867dacd3a72ea4753dafcdc87127e38040 Mon Sep 17 00:00:00 2001 From: sh960440 <54958110+sh960440@users.noreply.github.com> Date: Mon, 2 Mar 2020 04:42:20 -0500 Subject: [PATCH 2/2] Assignment 2 Assignment 2 Shun-min Hsieh 101212629 --- OpenGLEngine/OpenGLEngine/CableComponent.h | 14 +- OpenGLEngine/OpenGLEngine/CableSystem.cpp | 49 ++ OpenGLEngine/OpenGLEngine/CableSystem.h | 13 + .../OpenGLEngine/FPSControlSystem.cpp | 5 - .../OpenGLEngine/FixedSpringComponent.h | 3 - .../OpenGLEngine/FixedSpringSystem.cpp | 1 - OpenGLEngine/OpenGLEngine/Main.cpp | 521 +++++++++++++++--- OpenGLEngine/OpenGLEngine/Mix/World.h | 2 - .../OpenGLEngine/OpenGLEngine.vcxproj | 82 ++- .../OpenGLEngine/OpenGLEngine.vcxproj.filters | 123 +++-- .../OpenGLEngine/PairedSpringSystem.cpp | 2 +- .../OpenGLEngine/ParticleContactEvent.h | 27 + .../ParticleContactResolutionSystem.cpp | 330 +++++++---- .../ParticleContactResolutionSystem.h | 15 +- .../OpenGLEngine/ParticleSphereComponent.h | 15 + .../OpenGLEngine/ParticleSphereSystem.cpp | 128 +++++ .../OpenGLEngine/ParticleSphereSystem.h | 18 + OpenGLEngine/OpenGLEngine/ParticleSystem.cpp | 5 + .../PenetrationDeltaMoveComponent.h | 14 + .../ResetPenetrationDeltaMoveSystem.cpp | 18 + .../ResetPenetrationDeltaMoveSystem.h | 13 + OpenGLEngine/OpenGLEngine/RodComponent.h | 14 +- OpenGLEngine/OpenGLEngine/RodSystem.cpp | 83 +-- OpenGLEngine/OpenGLEngine/TriangleComponent.h | 19 + OpenGLEngine/OpenGLEngine/TriangleSystem.cpp | 61 ++ OpenGLEngine/OpenGLEngine/TriangleSystem.h | 16 + 26 files changed, 1277 insertions(+), 314 deletions(-) create mode 100644 OpenGLEngine/OpenGLEngine/CableSystem.cpp create mode 100644 OpenGLEngine/OpenGLEngine/CableSystem.h create mode 100644 OpenGLEngine/OpenGLEngine/ParticleContactEvent.h create mode 100644 OpenGLEngine/OpenGLEngine/ParticleSphereComponent.h create mode 100644 OpenGLEngine/OpenGLEngine/ParticleSphereSystem.cpp create mode 100644 OpenGLEngine/OpenGLEngine/ParticleSphereSystem.h create mode 100644 OpenGLEngine/OpenGLEngine/PenetrationDeltaMoveComponent.h create mode 100644 OpenGLEngine/OpenGLEngine/ResetPenetrationDeltaMoveSystem.cpp create mode 100644 OpenGLEngine/OpenGLEngine/ResetPenetrationDeltaMoveSystem.h create mode 100644 OpenGLEngine/OpenGLEngine/TriangleComponent.h create mode 100644 OpenGLEngine/OpenGLEngine/TriangleSystem.cpp create mode 100644 OpenGLEngine/OpenGLEngine/TriangleSystem.h diff --git a/OpenGLEngine/OpenGLEngine/CableComponent.h b/OpenGLEngine/OpenGLEngine/CableComponent.h index 07d09c6..87972d5 100644 --- a/OpenGLEngine/OpenGLEngine/CableComponent.h +++ b/OpenGLEngine/OpenGLEngine/CableComponent.h @@ -1,11 +1,21 @@ #pragma once #include "ECSConfig.h" + namespace Reality { struct CableComponent { - CableComponent(ECSEntity a = ECSEntity(), ECSEntity b = ECSEntity(), float _maxLength = 10, float _restitution = 1.0f) - : entityA(a), entityB(b), maxLength(_maxLength), restitution(_restitution){} + CableComponent(ECSEntity a = ECSEntity(), + ECSEntity b = ECSEntity(), + float _maxLength = 10, + float _restitution = 1) + : entityA(a), + entityB(b), + maxLength(_maxLength), + restitution(_restitution) + { + + } ECSEntity entityA; ECSEntity entityB; float maxLength; diff --git a/OpenGLEngine/OpenGLEngine/CableSystem.cpp b/OpenGLEngine/OpenGLEngine/CableSystem.cpp new file mode 100644 index 0000000..4aa3143 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/CableSystem.cpp @@ -0,0 +1,49 @@ +#include "CableSystem.h" +#include "TransformComponent.h" +#include "ParticleContactEvent.h" + +namespace Reality +{ + CableSystem::CableSystem() + { + requireComponent(); + } + + void CableSystem::Update(float deltaTime) + { + for (auto e : getEntities()) + { + auto& cable = e.getComponent(); + + if (cable.entityA.hasComponent() && + cable.entityB.hasComponent()) + { + auto& transformA = cable.entityA.getComponent(); + auto& transformB = cable.entityB.getComponent(); + + Vector3 relativePos = transformA.position - transformB.position; + float length = glm::length(relativePos); + + if (length > cable.maxLength) + { + Vector3 normal = -glm::normalize(relativePos); + float penetration = length - cable.maxLength; + + getWorld().getEventManager().emitEvent( + cable.entityA, + cable.entityB, + cable.restitution, + normal, + penetration + ); + } + + getWorld().data.renderUtil->DrawLine( + transformA.position, + transformB.position, + Color::Magenta + ); + } + } + } +} diff --git a/OpenGLEngine/OpenGLEngine/CableSystem.h b/OpenGLEngine/OpenGLEngine/CableSystem.h new file mode 100644 index 0000000..a888363 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/CableSystem.h @@ -0,0 +1,13 @@ +#pragma once +#include "ECSConfig.h" +#include "CableComponent.h" + +namespace Reality +{ + class CableSystem : public ECSSystem + { + public: + CableSystem(); + void Update(float deltaTime); + }; +} diff --git a/OpenGLEngine/OpenGLEngine/FPSControlSystem.cpp b/OpenGLEngine/OpenGLEngine/FPSControlSystem.cpp index 9e18339..39cc7d9 100644 --- a/OpenGLEngine/OpenGLEngine/FPSControlSystem.cpp +++ b/OpenGLEngine/OpenGLEngine/FPSControlSystem.cpp @@ -30,11 +30,6 @@ namespace Reality camera.ProcessKeyboard(LEFT, fpsControl.sidewaysSpeed * deltaTime); if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) camera.ProcessKeyboard(RIGHT, fpsControl.sidewaysSpeed * deltaTime); - if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) - { - getWorld().spaceIsPressed += 1; - std::cout << "Space" << std::endl; - } // Look auto mouseMoveEvents = getWorld().getEventManager().getEvents(); diff --git a/OpenGLEngine/OpenGLEngine/FixedSpringComponent.h b/OpenGLEngine/OpenGLEngine/FixedSpringComponent.h index daa14f8..dabd2d8 100644 --- a/OpenGLEngine/OpenGLEngine/FixedSpringComponent.h +++ b/OpenGLEngine/OpenGLEngine/FixedSpringComponent.h @@ -14,11 +14,8 @@ namespace Reality { } - /** Holds the spring constant. */ float springConstant; - /** Holds the rest length of the spring. */ float restLength; - /** The location of the anchored end of the spring. */ ECSEntity connectedEntity; }; } diff --git a/OpenGLEngine/OpenGLEngine/FixedSpringSystem.cpp b/OpenGLEngine/OpenGLEngine/FixedSpringSystem.cpp index a9bc461..ae5a0f6 100644 --- a/OpenGLEngine/OpenGLEngine/FixedSpringSystem.cpp +++ b/OpenGLEngine/OpenGLEngine/FixedSpringSystem.cpp @@ -23,7 +23,6 @@ namespace Reality auto& transform = spring.connectedEntity.getComponent(); Vector3 relativePosition = transform.position - springTransform.position; - float length = glm::length(relativePosition); if (length > 0) { diff --git a/OpenGLEngine/OpenGLEngine/Main.cpp b/OpenGLEngine/OpenGLEngine/Main.cpp index dbaecd0..322a32e 100644 --- a/OpenGLEngine/OpenGLEngine/Main.cpp +++ b/OpenGLEngine/OpenGLEngine/Main.cpp @@ -3,18 +3,22 @@ #include "InputEventSystem.h" #include "FPSControlSystem.h" #include "RotateSystem.h" +#include "FireworksSystem.h" #include "GravityForceSystem.h" #include "DragForceSystem.h" -#include "NBodySystem.h" -#include "BuoyancySystem.h" #include "FixedSpringSystem.h" #include "PairedSpringSystem.h" +#include "ParticleSphereSystem.h" +#include "CableSystem.h" +#include "RodSystem.h" +#include "TriangleSystem.h" +#include "ParticleContactResolutionSystem.h" +#include "ResetPenetrationDeltaMoveSystem.h" #include "ForceAccumulatorSystem.h" #include "ParticleSystem.h" #include "DynamicDirectionalLightSystem.h" #include "DynamicPointLightSystem.h" #include "DynamicSpotLightSystem.h" -#include "MouseMoveEvent.h" #include #include #include @@ -24,19 +28,25 @@ using namespace Reality; void LoadShaders(ECSWorld& world); void LoadModels(ECSWorld& world); void SetupLights(ECSWorld& world); -void N_Body(ECSWorld& world); -void Buoyancy(ECSWorld& world); +void MakeABunchaObjects(ECSWorld& world); +void MakeFireworks(ECSWorld& world); +void Make3Particles(ECSWorld& world); +void MakeABunchaSprings(ECSWorld& world); +void MakeABunchaSpheres(ECSWorld& world); +void MakeABunchaCablesAndRods(ECSWorld& world); +void MakeARopeBridge(ECSWorld& world); + int main() { ECSWorld world; - + bool pressedE = false; // Init and Load world.data.InitRendering(); //LoadAssets(world); - - world.data.renderUtil->camera.Position = Vector3(0, 40.0f, 50.0f); + + world.data.renderUtil->camera.Position = Vector3(0, 0.0f, 50.0f); world.data.renderUtil->SetFOV(60); // Create entities @@ -45,32 +55,38 @@ int main() e.addComponent(); SetupLights(world); - - // Question 1: Bungee Chord - auto particle1 = world.createEntity(); - particle1.addComponent(Vector3(0, 20, -50)); - particle1.addComponent(Vector3(0, 0, 0)); - particle1.addComponent(); - particle1.addComponent(); - - auto spring1 = world.createEntity(); - spring1.addComponent(Vector3(10, 60, -50)); - spring1.addComponent(20.0f, 20.0f, particle1); - - Buoyancy(world); // Question 2: Buoyancy - N_Body(world); // Question 3: N-Body + //MakeABunchaObjects(world); + //MakeFireworks(world); + //Make3Particles(world); + //MakeABunchaSprings(world); + //MakeABunchaSpheres(world); + //MakeABunchaCablesAndRods(world); + MakeARopeBridge(world); + + ECSEntity sphere = world.createEntity(); + sphere.addComponent(Vector3(-3, 6, 4)); + sphere.addComponent(Vector3(0, 0, 0)); + sphere.addComponent(30); + sphere.addComponent(); + sphere.addComponent(0.2, 0.2); + sphere.addComponent(2); // Create Systems world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); + world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); - world.getSystemManager().addSystem(); + world.getSystemManager().addSystem(); + world.getSystemManager().addSystem(); + world.getSystemManager().addSystem(); + world.getSystemManager().addSystem(); + world.getSystemManager().addSystem(); + world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); world.getSystemManager().addSystem(); @@ -91,12 +107,10 @@ int main() // ----------- while (!glfwWindowShouldClose(world.data.renderUtil->window->glfwWindow)) { - GLFWwindow* window = world.data.renderUtil->window->glfwWindow; float current = glfwGetTime(); deltaTime = current - time; deltaTime = 1 / 60.0f; time = glfwGetTime(); - Camera& camera = world.data.renderUtil->camera; world.update(); @@ -110,7 +124,7 @@ int main() { shadersLoaded = world.data.assetLoader->ShadersLoaded(); } - if (shadersLoaded && !modelsLoadStarted) + if(shadersLoaded && !modelsLoadStarted) { LoadModels(world); modelsLoadStarted = true; @@ -123,14 +137,18 @@ int main() // Game Logic Update world.getSystemManager().getSystem().Update(deltaTime); world.getSystemManager().getSystem().Update(deltaTime); - world.getSystemManager().getSystem().Update(deltaTime); - world.getSystemManager().getSystem().Update(deltaTime); + world.getSystemManager().getSystem().Update(deltaTime); + world.getSystemManager().getSystem().Update(deltaTime); + world.getSystemManager().getSystem().Update(deltaTime); + world.getSystemManager().getSystem().Update(deltaTime); + world.getSystemManager().getSystem().Update(deltaTime); // Update Transform // Physics //float fixedDeltaTime = glfwGetKey(world.data.renderUtil->window->glfwWindow, GLFW_KEY_SPACE) == GLFW_PRESS ? 1 / 60.0f : 0; float fixedDeltaTime = 1 / 60.0f; + // Force Generator world.getSystemManager().getSystem().Update(fixedDeltaTime); world.getSystemManager().getSystem().Update(fixedDeltaTime); @@ -140,9 +158,23 @@ int main() // Force Accumulator world.getSystemManager().getSystem().Update(fixedDeltaTime); + // Contact Resolution + world.getSystemManager().getSystem().Update(fixedDeltaTime); + world.getSystemManager().getSystem().Update(fixedDeltaTime); + // Integrator world.getSystemManager().getSystem().Update(fixedDeltaTime); + if (glfwGetKey(world.data.renderUtil->window->glfwWindow, GLFW_KEY_E) == GLFW_PRESS && pressedE == false) + { + sphere.getComponent().position = Vector3(-3, 6, 4); + sphere.getComponent().velocity = Vector3(0, 0, 0); + } + if (glfwGetKey(world.data.renderUtil->window->glfwWindow, GLFW_KEY_E) == GLFW_RELEASE && pressedE == true) + { + pressedE = false; + } + // Rendering Update ///*** HACK: For the last DrawCall not working on some systems world.data.renderUtil->DrawCube(Vector3(0, 0, 0), Vector3(0, 0, 0)); @@ -169,11 +201,11 @@ int main() std::string renderString = logic < 10 ? " " + std::to_string(render) : std::to_string(render); int debug = (int)round(debugDelta * 100.0f / deltaTime); std::string debugString = logic < 10 ? " " + std::to_string(debug) : std::to_string(debug); - + world.data.renderUtil->RenderText("Logic : " + logicString + "%" + //+ " | Physics : " + std::to_string((int)round(physicsDelta * 100.0f / deltaTime)) + "%" + - +" | Rendering : " + renderString + "%" + - +" | Debug : " + debugString + "%" + + " | Rendering : " + renderString + "%" + + + " | Debug : " + debugString + "%" , 1680.0f, 1040.0f, 0.25f, Color(0, 1, 1, 1)); } if (DEBUG_LOG_LEVEL > 2) @@ -189,49 +221,8 @@ int main() debugDelta = glfwGetTime() - stepTime; stepTime = glfwGetTime(); - world.data.renderUtil->RenderText("Density: " + std::to_string(world.getSystemManager().getSystem().liquidDensity), 1400.0f, 500.0f, 1.0f, Color(0.5, 0.5, 0.5, 1)); - world.data.renderUtil->SwapBuffers(world.data.renderUtil->window->glfwWindow); - // User Control - if (world.spaceIsPressed % 9 == 1) - { - auto newObj = world.createEntity(); - newObj.addComponent(world.data.renderUtil->camera.Position + - Vector3( - world.data.renderUtil->camera.Front.x * 30, - 10.0f, - world.data.renderUtil->camera.Front.z * 30 - )); - newObj.addComponent(Vector3(0, 0, 0)); - newObj.addComponent(); - newObj.addComponent(); - newObj.addComponent(); - newObj.addComponent(0.5f); - - if (world.spaceIsPressed == 1) - { - auto particle2 = world.createEntity(); - particle2.addComponent(Vector3(0, 0, 0)); - particle2.addComponent(Vector3(0, 0, 0)); - particle2.addComponent(); - particle2.addComponent(); - - auto pairedSpring = world.createEntity(); - pairedSpring.addComponent(20.0f, 20.0f, particle1, particle2); - world.spaceIsPressed += 1; - } - world.spaceIsPressed++; - } - - if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) - world.getSystemManager().getSystem().liquidDensity += 0.1; - if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) - world.getSystemManager().getSystem().liquidDensity -= 0.1; - - if (world.getSystemManager().getSystem().liquidDensity <= 0.1) - world.getSystemManager().getSystem().liquidDensity = 0.1; - // Show FPS in console //std::cout << "FPS : " << 1.0f / deltaTime << std::endl; } @@ -257,27 +248,375 @@ void LoadModels(ECSWorld& world) }); } -void N_Body(ECSWorld& world) +void MakeABunchaObjects(ECSWorld& world) +{ + auto castle = world.createEntity(); + castle.addComponent(Vector3(0, -3.0f, 0.0f), Vector3(0.1f, 0.1f, 0.1f), Vector3(0, 270, 0)); + // Add mesh + castle.addComponent("Resources/Models/Sponza-master/sponza.obj"); + + //auto flight = world.createEntity(); + //flight.addComponent(Vector3(0, 30, -50), Vector3(0.1f, 0.1f, 0.1f), Vector3(270, 0, 0)); + //// Add mesh + //flight.addComponent("Resources/Models/supermarine-spitfire/spitfire.fbx"); + //flight.addComponent(Vector3(0, 90, 0)); + //flight.addComponent(Vector3(0, 30, 0)); + //flight.addComponent(); + //flight.addComponent(); + +} + +void MakeFireworks(ECSWorld & world) +{ + for (int i = 0; i < 3; i++) + { + auto fireworks = world.createEntity(); + fireworks.addComponent(Vector3(-100 + 100 * i, 30 + RANDOM_FLOAT(-10, 10), -50)); + fireworks.addComponent(Vector3(0, 100, 0)); + fireworks.addComponent(); + fireworks.addComponent(); + fireworks.addComponent(6, 3, 3 + RANDOM_FLOAT(-1, 1)); + } + +} + +void Make3Particles(ECSWorld & world) +{ + auto particle1 = world.createEntity(); + particle1.addComponent(Vector3(-10, 60, -50)); + particle1.addComponent(Vector3(0, 0, 0)); + particle1.addComponent(); + particle1.addComponent(); + particle1.addComponent(0, 0); + + auto particle2 = world.createEntity(); + particle2.addComponent(Vector3(0, 60, -50)); + particle2.addComponent(Vector3(0, 0, 0)); + particle2.addComponent(); + particle2.addComponent(); + particle2.addComponent(1, 0); + + auto particle3 = world.createEntity(); + particle3.addComponent(Vector3(10, 60, -50)); + particle3.addComponent(Vector3(0, 0, 0)); + particle3.addComponent(); + particle3.addComponent(); + particle3.addComponent(1, 1); +} + +void MakeABunchaSprings(ECSWorld & world) +{ + auto particle1 = world.createEntity(); + particle1.addComponent(Vector3(0, 20, -50)); + particle1.addComponent(Vector3(0, 0, 0)); + particle1.addComponent(); + particle1.addComponent(); + + auto particle2= world.createEntity(); + particle2.addComponent(Vector3(-10, 0, -50)); + particle2.addComponent(Vector3(0, 0, 0)); + particle2.addComponent(); + particle2.addComponent(); + + auto spring1 = world.createEntity(); + spring1.addComponent(Vector3(10, 60, -50)); + spring1.addComponent(20.0f, 20.0f, particle1); + + auto spring2 = world.createEntity(); + spring2.addComponent(Vector3(-10, 60, -50)); + spring2.addComponent(20.0f, 15.0f, particle1); + + auto pairedSpring = world.createEntity(); + pairedSpring.addComponent(20.0f, 20.0f, particle1, particle2); + +} + +void MakeABunchaSpheres(ECSWorld & world) { - for (int i = 0; i < 10; i++) + for (int i = 0; i < 40; i++) { - auto particles = world.createEntity(); - particles.addComponent(Vector3(RANDOM_FLOAT(0.0f, 50.0f), RANDOM_FLOAT(0.0f, 50.0f), RANDOM_FLOAT(0.0f, 50.0f))); - particles.addComponent(Vector3(0, 0, 0)); - particles.addComponent(); - particles.addComponent(); + auto sphere = world.createEntity(); + sphere.addComponent(Vector3(RANDOM_FLOAT(-10, 10), RANDOM_FLOAT(-10, 10), RANDOM_FLOAT(-10, 10))); + sphere.addComponent(Vector3(RANDOM_FLOAT(-40, 40), RANDOM_FLOAT(-40, 40), RANDOM_FLOAT(-40, 40))); + sphere.addComponent(1.0f); + sphere.addComponent(); + sphere.addComponent(RANDOM_FLOAT(1, 3)); } } -void Buoyancy(ECSWorld& world) +void CreateParticleArchetype(ECSEntity e) +{ + e.addComponent(); + e.addComponent(300.0f); + e.addComponent(); + //e.addComponent(); + e.addComponent(); + e.addComponent(0.2, 0.2); +} + +void MakeARopeBridge(ECSWorld & world) +{ + auto ePivot1 = world.createEntity(); + ePivot1.addComponent(Vector3(3, 10, 5)); + + auto e1 = world.createEntity(); + e1.addComponent(Vector3(3, -10, 5)); + CreateParticleArchetype(e1); + + auto ePivot2 = world.createEntity(); + ePivot2.addComponent(Vector3(3, 10, -5)); + + auto e2 = world.createEntity(); + e2.addComponent(Vector3(3, -10, -5)); + CreateParticleArchetype(e2); + + auto rod1 = world.createEntity(); + rod1.addComponent(e1, e2, 10); + + auto cable1 = world.createEntity(); + cable1.addComponent(ePivot1, e1, 20, 1); + + auto cable2 = world.createEntity(); + cable2.addComponent(ePivot2, e2, 20, 1); + + // 2 + auto ePivot3 = world.createEntity(); + ePivot3.addComponent(Vector3(3 + 10, 10, 5)); + + auto e3 = world.createEntity(); + e3.addComponent(Vector3(3 + 10, -5, 5)); + CreateParticleArchetype(e3); + + auto ePivot4 = world.createEntity(); + ePivot4.addComponent(Vector3(3 + 10, 10, -5)); + + auto e4 = world.createEntity(); + e4.addComponent(Vector3(3 + 10, -5, -5)); + CreateParticleArchetype(e4); + + auto rod2 = world.createEntity(); + rod2.addComponent(e3, e4, 10); + + auto cable3 = world.createEntity(); + cable3.addComponent(ePivot3, e3, 15, 1); + + auto cable4 = world.createEntity(); + cable4.addComponent(ePivot4, e4, 15, 1); + + // 3 + auto ePivot5 = world.createEntity(); + ePivot5.addComponent(Vector3(3 - 10, 10, 5)); + + auto e5 = world.createEntity(); + e5.addComponent(Vector3(3 - 10, -5, 5)); + CreateParticleArchetype(e5); + + auto ePivot6 = world.createEntity(); + ePivot6.addComponent(Vector3(3 - 10, 10, -5)); + + auto e6 = world.createEntity(); + e6.addComponent(Vector3(3 - 10, -5, -5)); + CreateParticleArchetype(e6); + + auto rod3 = world.createEntity(); + rod3.addComponent(e5, e6, 10); + + auto cable5 = world.createEntity(); + cable5.addComponent(ePivot5, e5, 15, 1); + + auto cable6 = world.createEntity(); + cable6.addComponent(ePivot6, e6, 15, 1); + + // 4 + auto ePivot7 = world.createEntity(); + ePivot7.addComponent(Vector3(3 + 20, 10, 5)); + + auto e7 = world.createEntity(); + e7.addComponent(Vector3(3 + 20, 0, 5)); + CreateParticleArchetype(e7); + + auto ePivot8 = world.createEntity(); + ePivot8.addComponent(Vector3(3 + 20, 10, -5)); + + auto e8 = world.createEntity(); + e8.addComponent(Vector3(3 + 20, 0, -5)); + CreateParticleArchetype(e8); + + auto rod12 = world.createEntity(); + rod12.addComponent(e7, e8, 10); + + auto cable7 = world.createEntity(); + cable7.addComponent(ePivot7, e7, 10, 1); + + auto cable8 = world.createEntity(); + cable8.addComponent(ePivot8, e8, 10, 1); + + // 5 + auto ePivot9 = world.createEntity(); + ePivot9.addComponent(Vector3(3 - 20, 10, 5)); + + auto e9 = world.createEntity(); + e9.addComponent(Vector3(3 - 20, 0, 5)); + CreateParticleArchetype(e9); + + auto ePivot10 = world.createEntity(); + ePivot10.addComponent(Vector3(3 - 20, 10, -5)); + + auto e10 = world.createEntity(); + e10.addComponent(Vector3(3 - 20, 0, -5)); + CreateParticleArchetype(e10); + + auto rod13 = world.createEntity(); + rod13.addComponent(e9, e10, 10); + + auto cable9 = world.createEntity(); + cable9.addComponent(ePivot9, e9, 10, 1); + + auto cable10 = world.createEntity(); + cable10.addComponent(ePivot10, e10, 10, 1); + + // rods + auto rod4 = world.createEntity(); + rod4.addComponent(e1, e3, 10); + auto rod5 = world.createEntity(); + rod5.addComponent(e2, e4, 10); + auto rod6 = world.createEntity(); + rod6.addComponent(e5, e1, 10); + auto rod7 = world.createEntity(); + rod7.addComponent(e6, e2, 10); + auto rod14 = world.createEntity(); + rod14.addComponent(e3, e7, 10); + auto rod15 = world.createEntity(); + rod15.addComponent(e4, e8, 10); + auto rod16 = world.createEntity(); + rod16.addComponent(e9, e5, 10); + auto rod17 = world.createEntity(); + rod17.addComponent(e10, e6, 10); + + // diagonal rods + auto rod8 = world.createEntity(); + rod8.addComponent(e1, e4, 10 * pow(2.0f, 0.5f)); + auto rod9 = world.createEntity(); + rod9.addComponent(e2, e3, 10 * pow(2.0f, 0.5f)); + auto rod10 = world.createEntity(); + rod10.addComponent(e6, e1, 10 * pow(2.0f, 0.5f)); + auto rod11 = world.createEntity(); + rod11.addComponent(e5, e2, 10 * pow(2.0f, 0.5f)); + auto rod18 = world.createEntity(); + rod18.addComponent(e3, e8, 10 * pow(2.0f, 0.5f)); + auto rod19 = world.createEntity(); + rod19.addComponent(e4, e7, 10 * pow(2.0f, 0.5f)); + auto rod20 = world.createEntity(); + rod20.addComponent(e10, e5, 10 * pow(2.0f, 0.5f)); + auto rod21 = world.createEntity(); + rod21.addComponent(e9, e6, 10 * pow(2.0f, 0.5f)); + + auto triange_1 = world.createEntity(); + triange_1.addComponent(e2, e1, e3); + auto triange_2 = world.createEntity(); + triange_2.addComponent(e3, e4, e2); + auto triange_3 = world.createEntity(); + triange_3.addComponent(e6, e5, e1); + auto triange_4 = world.createEntity(); + triange_4.addComponent(e1, e2, e6); + auto triange_5 = world.createEntity(); + triange_5.addComponent(e4, e3, e7); + auto triange_6 = world.createEntity(); + triange_6.addComponent(e7, e8, e4); + auto triange_7 = world.createEntity(); + triange_7.addComponent(e10, e9, e5); + auto triange_8 = world.createEntity(); + triange_8.addComponent(e5, e6, e10); +} + +void MakeABunchaCablesAndRods(ECSWorld & world) { - auto particle = world.createEntity(); - particle.addComponent(Vector3(0, 10.0f, 0)); - particle.addComponent(Vector3(0, 0, 0)); - particle.addComponent(); - particle.addComponent(); - particle.addComponent(); - particle.addComponent(0.5f); + auto ePivot = world.createEntity(); + ePivot.addComponent(Vector3(3, 10, 0)); + + auto e1 = world.createEntity(); + e1.addComponent(Vector3(0, 10, 0)); + e1.addComponent(); + e1.addComponent(); + e1.addComponent(); + e1.addComponent(); + e1.addComponent(); + + auto e2 = world.createEntity(); + e2.addComponent(Vector3(5, 5, 0)); + e2.addComponent(); + e2.addComponent(); + e2.addComponent(); + e2.addComponent(); + e2.addComponent(); + + auto e3 = world.createEntity(); + e3.addComponent(Vector3(0, 0, 0)); + e3.addComponent(); + e3.addComponent(); + e3.addComponent(); + e3.addComponent(); + e3.addComponent(); + + auto e4 = world.createEntity(); + e4.addComponent(Vector3(-5, 5, 0)); + e4.addComponent(); + e4.addComponent(); + e4.addComponent(); + e4.addComponent(); + e4.addComponent(); + + auto cable1 = world.createEntity(); + //cable.addComponent(ePivot, e1, 5, 1); + cable1.addComponent(50, 2, ePivot, e1); + + auto cable2 = world.createEntity(); + //cable.addComponent(ePivot, e1, 5, 1); + cable2.addComponent(50, 25, ePivot, e2); + + auto cable3 = world.createEntity(); + cable3.addComponent(ePivot, e3, 15, 1); + //cable3.addComponent(50, 20, ePivot, e3); + + auto rod1 = world.createEntity(); + rod1.addComponent(e1, e2, 5 * pow(2, 0.5f)); + + auto rod2 = world.createEntity(); + rod2.addComponent(e2, e3, 5 * pow(2, 0.5f)); + + auto rod3 = world.createEntity(); + rod3.addComponent(e3, e4, 5 * pow(2, 0.5f)); + + auto rod4 = world.createEntity(); + rod4.addComponent(e4, e1, 5 * pow(2, 0.5f)); + + auto rod5 = world.createEntity(); + rod5.addComponent(e1, e3, 10); + + auto rod6 = world.createEntity(); + rod6.addComponent(e2, e4, 10); + + //for (int i = 0; i < 20; i++) + //{ + // auto e1 = world.createEntity(); + // e1.addComponent(Vector3(RANDOM_FLOAT(-5, 5), RANDOM_FLOAT(-5, 5), RANDOM_FLOAT(-5, 5))); + // e1.addComponent(); + // e1.addComponent(); + // e1.addComponent(); + // e1.addComponent(RANDOM_FLOAT(0.5, 1.5)); + // e1.addComponent(); + + // auto e2 = world.createEntity(); + // e2.addComponent(Vector3(RANDOM_FLOAT(-5, 5), RANDOM_FLOAT(-5, 5), RANDOM_FLOAT(-5, 5))); + // e2.addComponent(); + // e2.addComponent(); + // e2.addComponent(); + // e2.addComponent(RANDOM_FLOAT(0.5, 1.5)); + // e2.addComponent(); + + // auto rod = world.createEntity(); + // rod.addComponent(e1, e2, RANDOM_FLOAT(6, 10)); + //} } void SetupLights(ECSWorld& world) @@ -306,7 +645,7 @@ void SetupLights(ECSWorld& world) hook.addComponent(Vector3(-14.5f - 0.5f, 14 + 1, 49.0f)); hook = world.createEntity(); hook.addComponent(Vector3(-14.5f, 14 - 1, 49.0f + 1)); - + auto pl3 = world.createEntity(); pl3.addComponent(Vector3(22, 14, -62.0f)); pl3.addComponent(100.0f, Color(0, 0.1f, 0), Color(0.0f, 1.0f, 0.0f), Color(0.0f, 1.0f, 0.0f)); @@ -321,11 +660,11 @@ void SetupLights(ECSWorld& world) pl4.addComponent(Vector3(-14.5f, 14, -61.5f)); pl4.addComponent(100.0f, Color(0.1, 0.05, 0), Color(1.0f, 0.55f, 0.0f), Color(1.0f, 0.55f, 0.0f)); hook = world.createEntity(); - hook.addComponent(Vector3(-14.5f - 1, 14, -61.5f - 1)); + hook.addComponent(Vector3(-14.5f - 1, 14, -61.5f -1)); hook = world.createEntity(); hook.addComponent(Vector3(-14.5f - 0.25f, 14 - 0.5f, -61.5f + 1)); hook = world.createEntity(); - hook.addComponent(Vector3(-14.5f + 0.5f, 14 + 1, -61.5f + 1)); + hook.addComponent(Vector3(-14.5f + 0.5f, 14+ 1, -61.5f + 1)); // Spears std::vector cols = { Color(1,0,0), Color(0,1,0), Color(0,0,1), Color(0.7f,0.55f,0) }; diff --git a/OpenGLEngine/OpenGLEngine/Mix/World.h b/OpenGLEngine/OpenGLEngine/Mix/World.h index 6445b3e..69e7598 100644 --- a/OpenGLEngine/OpenGLEngine/Mix/World.h +++ b/OpenGLEngine/OpenGLEngine/Mix/World.h @@ -39,8 +39,6 @@ class World WorldData data; - int spaceIsPressed = 0; - private: // vector of entities that are awaiting creation std::vector createdEntities; diff --git a/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj b/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj index 3b732f1..cd23976 100644 --- a/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj +++ b/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj @@ -22,7 +22,7 @@ 15.0 {BF971B9A-9ACC-4B50-8E62-4CC32E780AA5} OpenGLEngine - 10.0.18362.0 + 10.0.17763.0 @@ -122,7 +122,7 @@ - + @@ -143,6 +143,10 @@ + + + + @@ -167,11 +171,15 @@ - + - + + + + + @@ -181,21 +189,33 @@ + + + + + + + + + + + + - + - + @@ -231,6 +251,14 @@ + + + + + + + + @@ -269,23 +297,31 @@ - + - + - + - + - + + + + + + + + + @@ -293,9 +329,25 @@ + + + + + + + + + + + + + + + + @@ -309,6 +361,14 @@ + + + + + + + + diff --git a/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj.filters b/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj.filters index e9a3f90..8b29e15 100644 --- a/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj.filters +++ b/OpenGLEngine/OpenGLEngine/OpenGLEngine.vcxproj.filters @@ -49,20 +49,26 @@ {3b57134f-d90e-46bd-8888-c0777df6a173} - - {ca789051-cc7e-4ee6-b5e9-0588e346445c} + + {2a1ab3ed-c9b4-469a-8efb-a6ad96814ca1} - - {d837795e-a627-4903-896c-26f4fa36fcd1} + + {a47e3b81-90db-42eb-a5f1-e5a072f9b973} - - {3d4ccf92-2e99-4fba-ad16-d06712865eed} + + {05f83a53-3654-4ae0-99f7-3b5b0131942b} - {fdf89afd-47b6-4a61-b7bc-48f65fe356f2} + {4c54bdb5-bf1a-46eb-97aa-4ad2f029416e} - - {a8329ac4-3b10-441c-af9c-a98085741757} + + {26df7371-0611-42cd-b6e5-2556995c23d7} + + + {8f440b87-7f9c-4d7f-993c-ec5fa08dde39} + + + {8d7d692e-fedf-4e75-9661-f2eb1dd346c1} @@ -141,23 +147,38 @@ Physics\Particles - - Physics\Particles\ForceGenerators + + TestCS\FireWorksDemo - - Physics\Particles\ForceGenerators\Buoyancy - - - Physics\Particles\ForceGenerators\NBody + + Physics\Particles\ForceGenerators\Gravity - Physics\Particles\ForceGenerators\DragForce + Physics\Particles\ForceGenerators\Drag Physics\Particles\ForceGenerators\FixedSpring - Physics\Particles\ForceGenerators\PairedSpring + Physics\Particles\PairedSpring + + + Physics\Particles + + + TestCS\ParticleSphereDemo + + + TestCS\CablesAndRods + + + TestCS\CablesAndRods + + + Physics\Particles + + + Physics\Particles @@ -281,29 +302,23 @@ Physics\Particles - - Physics\Particles\ForceGenerators + + TestCS\FireWorksDemo - - Physics\Particles\ForceGenerators - - - Physics\Particles\ForceGenerators\Buoyancy + + TestCS\FireWorksDemo - - Physics\Particles\ForceGenerators\Buoyancy - - - Physics\Particles\ForceGenerators\NBody + + Physics\Particles\ForceGenerators\Gravity - - Physics\Particles\ForceGenerators\NBody + + Physics\Particles\ForceGenerators\Gravity - Physics\Particles\ForceGenerators\DragForce + Physics\Particles\ForceGenerators\Drag - Physics\Particles\ForceGenerators\DragForce + Physics\Particles\ForceGenerators\Drag Physics\Particles\ForceGenerators\FixedSpring @@ -312,10 +327,46 @@ Physics\Particles\ForceGenerators\FixedSpring - Physics\Particles\ForceGenerators\PairedSpring + Physics\Particles\PairedSpring - Physics\Particles\ForceGenerators\PairedSpring + Physics\Particles\PairedSpring + + + Physics\Particles + + + Physics\Particles + + + TestCS\ParticleSphereDemo + + + TestCS\ParticleSphereDemo + + + TestCS\CablesAndRods + + + TestCS\CablesAndRods + + + TestCS\CablesAndRods + + + TestCS\CablesAndRods + + + Physics\Particles + + + Physics\Particles + + + Physics\Particles + + + Physics\Particles diff --git a/OpenGLEngine/OpenGLEngine/PairedSpringSystem.cpp b/OpenGLEngine/OpenGLEngine/PairedSpringSystem.cpp index 250f84c..70e7b38 100644 --- a/OpenGLEngine/OpenGLEngine/PairedSpringSystem.cpp +++ b/OpenGLEngine/OpenGLEngine/PairedSpringSystem.cpp @@ -28,7 +28,7 @@ namespace Reality float deltaL = length - spring.restLength; Vector3 force = -glm::normalize(relativePosition); force *= spring.springConstant * deltaL; - + if (spring.connectedEntityA.hasComponent()) { spring.connectedEntityA.getComponent().AddForce(force); diff --git a/OpenGLEngine/OpenGLEngine/ParticleContactEvent.h b/OpenGLEngine/OpenGLEngine/ParticleContactEvent.h new file mode 100644 index 0000000..0d7074e --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/ParticleContactEvent.h @@ -0,0 +1,27 @@ +#pragma once +#include "ECSConfig.h" + +namespace Reality +{ + struct ParticleContactEvent + { + ParticleContactEvent(ECSEntity _entityA = ECSEntity(), + ECSEntity _entityB = ECSEntity(), + float _restitution = 1.0f, + Vector3 _normal = Vector3(0, 1.0f, 0), + float _penetration = 0.0f) + : entityA(_entityA), + entityB(_entityB), + restitution(_restitution), + normal(_normal), + penetration(_penetration) + { + + } + ECSEntity entityA; + ECSEntity entityB; + float restitution; + Vector3 normal; + float penetration; + }; +} diff --git a/OpenGLEngine/OpenGLEngine/ParticleContactResolutionSystem.cpp b/OpenGLEngine/OpenGLEngine/ParticleContactResolutionSystem.cpp index 42c892a..e8121df 100644 --- a/OpenGLEngine/OpenGLEngine/ParticleContactResolutionSystem.cpp +++ b/OpenGLEngine/OpenGLEngine/ParticleContactResolutionSystem.cpp @@ -1,65 +1,173 @@ #include "ParticleContactResolutionSystem.h" #include "ParticleComponent.h" +#include "ForceAccumulatorSystem.h" #include "TransformComponent.h" +#include "PenetrationDeltaMoveComponent.h" +#include "TriangleComponent.h" namespace Reality { ParticleContactResolutionSystem::ParticleContactResolutionSystem() { - requireComponent(); + } - float ParticleContactResolutionSystem::CalculateSeparatingVelocity(ParticleContactComponent& contact) + void ParticleContactResolutionSystem::Update(float deltaTime) { - Vector3 velocityA = contact.entityA.hasComponent() ? contact.entityA.getComponent().velocity : Vector3(0, 0, 0); - Vector3 velocityB = contact.entityB.hasComponent() ? contact.entityB.getComponent().velocity : Vector3(0, 0, 0); - Vector3 relativeVel = velocityA - velocityB; - return glm::dot(relativeVel, contact.normal); + auto contactEvents = getWorld().getEventManager().getEvents(); + if (contactEvents.size() > 0) + { + for (int i = 0; i < velocityIterations; i++) + { + // Sort from highest incoming OR most negetive separting velocity to least + std::sort(contactEvents.begin(), contactEvents.end(), + [this](auto a, auto b) + { + return CalculateSeparationVelocity(a) < CalculateSeparationVelocity(b); + }); + ResolveVelocity(contactEvents[0], deltaTime); + } + for (int i = 0; i < positionIterations; i++) + { + // Sort from highest penetration to the least + std::sort(contactEvents.begin(), contactEvents.end(), + [this](auto a, auto b) + { + return CalculateActualPenetration(a) > CalculateActualPenetration(b); + }); + ResolveInterPenetration(contactEvents[0]); + } + } + //for (auto& contact : contactEvents) + //{ + // ResolveVelocity(contact, deltaTime); + // ResolveInterPenetration(contact); + //} } - void ParticleContactResolutionSystem::ResolveVelocity(ParticleContactComponent& contact, float deltaTime) + float ParticleContactResolutionSystem::CalculateSeparationVelocity(ParticleContactEvent & contact) { - float separatingVelocity = CalculateSeparatingVelocity(contact); + Vector3 velocityA = contact.entityA.hasComponent() ? + contact.entityA.getComponent().velocity : Vector3(0, 0, 0); - if (separatingVelocity > 0) + /*Vector3 velocityB = contact.entityB.hasComponent() ? + contact.entityB.getComponent().velocity : Vector3(0, 0, 0);*/ + Vector3 velocityB; + if (contact.entityB.hasComponent()) { - return; + auto triangle = contact.entityB.getComponent(); + velocityB = triangle.vertex_1.hasComponent() ? + triangle.vertex_1.getComponent().velocity : Vector3(0, 0, 0); + } + else + { + velocityB = contact.entityB.hasComponent() ? + contact.entityB.getComponent().velocity : Vector3(0, 0, 0); } - bool isAvalid = contact.entityA.hasComponent(); - bool isBvalid = contact.entityB.hasComponent(); - float invM1 = isAvalid ? contact.entityA.getComponent().inverseMass : 0; - float invM2 = isBvalid ? contact.entityB.getComponent().inverseMass : 0; + Vector3 separationVelocity = velocityA - velocityB; + + return glm::dot(separationVelocity, contact.normal); + } + + float ParticleContactResolutionSystem::CalculateActualPenetration(ParticleContactEvent & contact) + { + float actualPenetration = contact.penetration; - float newSeparatingVelocity = -separatingVelocity * contact.restitution; + if (contact.entityA.hasComponent()) + { + Vector3 deltaMove = contact.entityA.getComponent().deltaMove; + actualPenetration -= glm::dot(deltaMove, contact.normal); + } - // Check the velocity build up due to accelaration only - Vector3 accCausedVelocity = Vector3(0, 0, 0); - if (isAvalid) + if (contact.entityB.hasComponent()) { - accCausedVelocity += contact.entityA.getComponent().accelaration; + auto triangle = contact.entityB.getComponent(); + if (triangle.vertex_1.hasComponent()) + { + Vector3 deltaMove = triangle.vertex_1.getComponent().deltaMove; + actualPenetration += glm::dot(deltaMove, contact.normal); + } } - if (isBvalid) + else { - accCausedVelocity -= contact.entityB.getComponent().accelaration; + if (contact.entityB.hasComponent()) + { + Vector3 deltaMove = contact.entityB.getComponent().deltaMove; + actualPenetration += glm::dot(deltaMove, contact.normal); + } } - float accCausedSepVelocity = glm::dot(accCausedVelocity, contact.normal) * deltaTime; - // If we have a closing velocity due to accelaration build up, - // remove it from new separating velocity + return actualPenetration; + } + + void ParticleContactResolutionSystem::ResolveVelocity(ParticleContactEvent & contact, float deltaTime) + { + float initialVelocity = CalculateSeparationVelocity(contact); + + if (initialVelocity > 0) + { + return; + } + + float finalVelocity = -initialVelocity * contact.restitution; + + Vector3 relativeAccelaration = Vector3(0, 0, 0); + if (contact.entityA.hasComponent()) + { + relativeAccelaration += contact.entityA.getComponent().acceleration; + } + if (contact.entityB.hasComponent()) + { + auto triangle = contact.entityB.getComponent(); + if (triangle.vertex_1.hasComponent()) + { + relativeAccelaration -= triangle.vertex_1.getComponent().acceleration; + } + } + else + { + if (contact.entityB.hasComponent()) + { + relativeAccelaration -= contact.entityB.getComponent().acceleration; + } + } + + float accCausedSepVelocity = glm::dot(relativeAccelaration, contact.normal) * deltaTime; + if (accCausedSepVelocity < 0) { - newSeparatingVelocity += contact.restitution * accCausedSepVelocity; - if (newSeparatingVelocity < 0) + finalVelocity += contact.restitution * accCausedSepVelocity; + + if (finalVelocity < 0) { - newSeparatingVelocity = 0; + finalVelocity = 0; } } - float deltaVelocity = newSeparatingVelocity - separatingVelocity; + float deltaVelocity = finalVelocity - initialVelocity; + + float invMA = contact.entityA.hasComponent() ? + contact.entityA.getComponent().inverseMass : 0; + + /*float invMB = contact.entityB.hasComponent() ? + contact.entityB.getComponent().inverseMass : 0;*/ - float totalInverseMass = invM1 + invM2; + float invMB; + if (contact.entityB.hasComponent()) + { + auto triangle = contact.entityB.getComponent(); + invMB = triangle.vertex_1.hasComponent() ? + triangle.vertex_1.getComponent().inverseMass : 0; + } + else + { + invMB = contact.entityB.hasComponent() ? + contact.entityB.getComponent().inverseMass : 0; + } + + float totalInverseMass = invMA + invMB; if (totalInverseMass <= 0) { @@ -67,120 +175,124 @@ namespace Reality } float impulse = deltaVelocity / totalInverseMass; + Vector3 impulsePerIMass = impulse * contact.normal; - Vector3 impulsePerIMass = contact.normal * impulse; + if (contact.entityA.hasComponent()) + { + contact.entityA.getComponent().velocity += impulsePerIMass * invMA; + } - if (isAvalid) + if (contact.entityB.hasComponent()) { - contact.entityA.getComponent().velocity += impulsePerIMass * invM1; + auto triangle = contact.entityB.getComponent(); + + if (triangle.vertex_1.hasComponent()) + triangle.vertex_1.getComponent().velocity -= impulsePerIMass * invMB; + if (triangle.vertex_2.hasComponent()) + triangle.vertex_2.getComponent().velocity -= impulsePerIMass * invMB; + if (triangle.vertex_3.hasComponent()) + triangle.vertex_3.getComponent().velocity -= impulsePerIMass * invMB; } - if (isBvalid) + else { - contact.entityB.getComponent().velocity -= impulsePerIMass * invM2; + if (contact.entityB.hasComponent()) + { + contact.entityB.getComponent().velocity -= impulsePerIMass * invMB; + } } } - - void ParticleContactResolutionSystem::ResolveInterpenetration(ParticleContactComponent& contact) + void ParticleContactResolutionSystem::ResolveInterPenetration(ParticleContactEvent & contact) { - if (contact.penetration <= 0) + float actualPenetration = CalculateActualPenetration(contact); + + if (actualPenetration < 0) { return; } - bool isAvalid = contact.entityA.hasComponent(); - bool isBvalid = contact.entityB.hasComponent(); - float invM1 = isAvalid ? contact.entityA.getComponent().inverseMass : 0; - float invM2 = isBvalid ? contact.entityB.getComponent().inverseMass : 0; + float invMassA = contact.entityA.hasComponent() ? + contact.entityA.getComponent().inverseMass : 0; - float totalInverseMass = invM1 + invM2; + /*float invMassB = contact.entityB.hasComponent() ? + contact.entityB.getComponent().inverseMass : 0;*/ - if (totalInverseMass <= 0) + float invMassB; + if (contact.entityB.hasComponent()) { - return; + auto triangle = contact.entityB.getComponent(); + invMassB = triangle.vertex_1.hasComponent() ? + triangle.vertex_1.getComponent().inverseMass : 0; } - - Vector3 movePerMass = contact.normal * (-contact.penetration / totalInverseMass); - contact.deltaMovePerMass = movePerMass; - if (isAvalid) + else { - contact.entityA.getComponent().position -= movePerMass * invM1; + invMassB = contact.entityB.hasComponent() ? + contact.entityB.getComponent().inverseMass : 0; } - if (isBvalid) - { - contact.entityB.getComponent().position += movePerMass * invM2; - } - //contact.penetration = 0; - } + float totalInverseMass = invMassA + invMassB; - void ParticleContactResolutionSystem::UpdateInterpenetration(ParticleContactComponent & bestContact, ParticleContactComponent & contact) - { - bool isAvalid = contact.entityA.hasComponent(); - bool isBvalid = contact.entityB.hasComponent(); - float invM1 = isAvalid ? contact.entityA.getComponent().inverseMass : 0; - float invM2 = isBvalid ? contact.entityB.getComponent().inverseMass : 0; - if (bestContact.entityA == contact.entityA || bestContact.entityB == contact.entityA) + if (totalInverseMass <= 0) { - float mult = bestContact.entityA == contact.entityA ? -1 : 1; - Vector3 deltaMove = mult * bestContact.deltaMovePerMass * invM1; - float deltaPenetration = glm::dot(deltaMove, contact.normal); - contact.penetration -= deltaPenetration; + return; } - if (bestContact.entityB == contact.entityB || bestContact.entityA == contact.entityB) + + Vector3 movePerUnitIMass = contact.normal * (actualPenetration / totalInverseMass); + + if (contact.entityA.hasComponent()) { - float mult = bestContact.entityA == contact.entityB ? -1 : 1; - Vector3 deltaMove = mult * bestContact.deltaMovePerMass * invM2; - float deltaPenetration = glm::dot(deltaMove, contact.normal); - contact.penetration += deltaPenetration; + Vector3 deltaMove = movePerUnitIMass * invMassA; + contact.entityA.getComponent().position += deltaMove; + if (contact.entityA.hasComponent()) + { + contact.entityA.getComponent().deltaMove += deltaMove; + } } - } - void ParticleContactResolutionSystem::Update(float deltaTime) - { - iterationsUsed = 0; - iterations = getEntities().size() * 2; + /*if (contact.entityB.hasComponent()) + { + Vector3 deltaMove = movePerUnitIMass * invMassB; + contact.entityB.getComponent().position -= movePerUnitIMass * invMassB; + if (contact.entityB.hasComponent()) + { + contact.entityB.getComponent().deltaMove -= deltaMove; + } + }*/ - if (getEntities().size() > 0) + if (contact.entityB.hasComponent()) { - unsigned int bestContactIndex = 0; - unsigned int lastBest = 0; - while (iterationsUsed < iterations) + auto triangle = contact.entityB.getComponent(); + Vector3 deltaMove = movePerUnitIMass * invMassB; + triangle.vertex_1.getComponent().position -= movePerUnitIMass * invMassB; + if (triangle.vertex_1.hasComponent()) { - // Find the contact with the largest closing velocity - float max = 0; - for (int i = 0; i < getEntities().size(); i++) - { - auto e = getEntities()[i]; - auto &contact = e.getComponent(); - if (iterationsUsed > 0) - { - UpdateInterpenetration(getEntities()[lastBest].getComponent(), contact); - } - float sepVel = CalculateSeparatingVelocity(contact); - if (sepVel < max) - { - max = sepVel; - bestContactIndex = i; - } - } - if (max >= 0) - { - break; - } - auto& bestContact = getEntities()[bestContactIndex].getComponent(); - ResolveVelocity(bestContact, deltaTime); - ResolveInterpenetration(bestContact); - lastBest = bestContactIndex; - iterationsUsed++; + triangle.vertex_1.getComponent().deltaMove -= deltaMove; } - for (auto e : getEntities()) + triangle.vertex_2.getComponent().position -= movePerUnitIMass * invMassB; + if (triangle.vertex_2.hasComponent()) { - e.kill(); + triangle.vertex_2.getComponent().deltaMove -= deltaMove; } - } + triangle.vertex_3.getComponent().position -= movePerUnitIMass * invMassB; + if (triangle.vertex_3.hasComponent()) + { + triangle.vertex_3.getComponent().deltaMove -= deltaMove; + } + } + else + { + if (contact.entityB.hasComponent()) + { + Vector3 deltaMove = movePerUnitIMass * invMassB; + contact.entityB.getComponent().position -= movePerUnitIMass * invMassB; + if (contact.entityB.hasComponent()) + { + contact.entityB.getComponent().deltaMove -= deltaMove; + } + } + } } } diff --git a/OpenGLEngine/OpenGLEngine/ParticleContactResolutionSystem.h b/OpenGLEngine/OpenGLEngine/ParticleContactResolutionSystem.h index ff0daa1..a203f9b 100644 --- a/OpenGLEngine/OpenGLEngine/ParticleContactResolutionSystem.h +++ b/OpenGLEngine/OpenGLEngine/ParticleContactResolutionSystem.h @@ -1,6 +1,6 @@ #pragma once #include "ECSConfig.h" -#include "ParticleContactComponent.h" +#include "ParticleContactEvent.h" namespace Reality { @@ -9,13 +9,12 @@ namespace Reality public: ParticleContactResolutionSystem(); void Update(float deltaTime); - unsigned int iterations = 1; private: - float CalculateSeparatingVelocity(ParticleContactComponent& contact); - void ResolveVelocity(ParticleContactComponent& contact, float deltaTime); - void ResolveInterpenetration(ParticleContactComponent& contact); - void UpdateInterpenetration(ParticleContactComponent& bestContact, ParticleContactComponent& contact); - unsigned int iterationsUsed = 0; + float CalculateSeparationVelocity(ParticleContactEvent& contact); + float CalculateActualPenetration(ParticleContactEvent& contact); + void ResolveVelocity(ParticleContactEvent& contact, float deltaTime); + void ResolveInterPenetration(ParticleContactEvent& contact); + int velocityIterations = 4; + int positionIterations = 8; }; } - diff --git a/OpenGLEngine/OpenGLEngine/ParticleSphereComponent.h b/OpenGLEngine/OpenGLEngine/ParticleSphereComponent.h new file mode 100644 index 0000000..4954332 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/ParticleSphereComponent.h @@ -0,0 +1,15 @@ +#pragma once +#include "ECSConfig.h" + +namespace Reality +{ + struct ParticleSphereComponent + { + ParticleSphereComponent(float _radius = 1.0f) + : radius(_radius) + { + + } + float radius; + }; +} diff --git a/OpenGLEngine/OpenGLEngine/ParticleSphereSystem.cpp b/OpenGLEngine/OpenGLEngine/ParticleSphereSystem.cpp new file mode 100644 index 0000000..a5e7c29 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/ParticleSphereSystem.cpp @@ -0,0 +1,128 @@ +#include "ParticleSphereSystem.h" +#include "ParticleContactEvent.h" + +namespace Reality +{ + ParticleSphereSystem::ParticleSphereSystem() + { + requireComponent(); + requireComponent(); + } + + void ParticleSphereSystem::Update(float deltaTime) + { + for (int i = 0; i < getEntities().size(); i++) + { + auto e = getEntities()[i]; + auto& transform = e.getComponent(); + auto& sphere = e.getComponent(); + + // Draw Debug Sphere + if (DEBUG_LOG_LEVEL > 0) + { + getWorld().data.renderUtil->DrawSphere( + transform.position, + sphere.radius, + Color::Orange + ); + } + + // Collision Check with X + if (abs(transform.position.x) + sphere.radius >= 10) + { + Vector3 normal = Vector3(transform.position.x > 0 ? -1 : 1, 0, 0); + float penetration = abs(transform.position.x) + sphere.radius - 10; + + getWorld().getEventManager().emitEvent( + e, + boundingBox, + 0.8f, + normal, + penetration); + + getWorld().data.renderUtil->DrawLine( + transform.position - normal * sphere.radius, + transform.position - normal * (sphere.radius - penetration), + Color::Red); + } + + // Collision Check with Y + if (abs(transform.position.y) + sphere.radius >= 10) + { + Vector3 normal = Vector3(0, transform.position.y > 0 ? -1 : 1, 0); + float penetration = abs(transform.position.y) + sphere.radius - 10; + + getWorld().getEventManager().emitEvent( + e, + boundingBox, + 0.8f, + normal, + penetration); + + getWorld().data.renderUtil->DrawLine( + transform.position - normal * sphere.radius, + transform.position - normal * (sphere.radius - penetration), + Color::Red); + } + + // Collision Check with Z + if (abs(transform.position.z) + sphere.radius >= 10) + { + Vector3 normal = Vector3(0, 0, transform.position.z > 0 ? -1 : 1); + float penetration = abs(transform.position.z) + sphere.radius - 10; + + getWorld().getEventManager().emitEvent( + e, + boundingBox, + 0.8f, + normal, + penetration); + + getWorld().data.renderUtil->DrawLine( + transform.position - normal * sphere.radius, + transform.position - normal * (sphere.radius - penetration), + Color::Red); + } + + // Collision with other spheres + if (i < getEntities().size() - 1) + { + for (int j = i + 1; j < getEntities().size(); j++) + { + CheckCollision(e, getEntities()[j]); + } + } + } + } + void ParticleSphereSystem::CheckCollision(ECSEntity sphereEntityA, ECSEntity sphereEntityB) + { + auto& transformA = sphereEntityA.getComponent(); + auto& sphereA = sphereEntityA.getComponent(); + + auto& transformB = sphereEntityB.getComponent(); + auto& sphereB = sphereEntityB.getComponent(); + + Vector3 relativePos = transformA.position - transformB.position; + float distance = glm::length(relativePos); + + if (distance < sphereA.radius + sphereB.radius) + { + Vector3 normal = glm::normalize(relativePos); + float penetration = sphereA.radius + sphereB.radius - distance; + + getWorld().getEventManager().emitEvent( + sphereEntityA, + sphereEntityB, + 0.8f, + normal, + penetration + ); + + getWorld().data.renderUtil->DrawLine( + transformA.position - normal * sphereA.radius, + transformB.position + normal * sphereB.radius, + Color::Red + ); + } + } +} diff --git a/OpenGLEngine/OpenGLEngine/ParticleSphereSystem.h b/OpenGLEngine/OpenGLEngine/ParticleSphereSystem.h new file mode 100644 index 0000000..0bda2db --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/ParticleSphereSystem.h @@ -0,0 +1,18 @@ +#pragma once +#include "ECSConfig.h" +#include "ParticleSphereComponent.h" +#include "TransformComponent.h" + +namespace Reality +{ + class ParticleSphereSystem : public ECSSystem + { + public: + ParticleSphereSystem(); + void Update(float deltaTime); + private: + bool createBox = false; + ECSEntity boundingBox; + void CheckCollision(ECSEntity sphereEntityA, ECSEntity sphereEntityB); + }; +} diff --git a/OpenGLEngine/OpenGLEngine/ParticleSystem.cpp b/OpenGLEngine/OpenGLEngine/ParticleSystem.cpp index ce93b11..c9b3b97 100644 --- a/OpenGLEngine/OpenGLEngine/ParticleSystem.cpp +++ b/OpenGLEngine/OpenGLEngine/ParticleSystem.cpp @@ -17,6 +17,11 @@ namespace Reality particle.velocity += particle.acceleration * deltaTime; transform.position += particle.velocity * deltaTime; + + if (DEBUG_LOG_LEVEL > 0) + { + getWorld().data.renderUtil->DrawSphere(transform.position); + } } } } diff --git a/OpenGLEngine/OpenGLEngine/PenetrationDeltaMoveComponent.h b/OpenGLEngine/OpenGLEngine/PenetrationDeltaMoveComponent.h new file mode 100644 index 0000000..fb50100 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/PenetrationDeltaMoveComponent.h @@ -0,0 +1,14 @@ +#pragma once +#include "ECSConfig.h" + +namespace Reality +{ + struct PenetrationDeltaMoveComponent + { + PenetrationDeltaMoveComponent() : deltaMove(Vector3(0, 0, 0)) + { + + } + Vector3 deltaMove; + }; +} diff --git a/OpenGLEngine/OpenGLEngine/ResetPenetrationDeltaMoveSystem.cpp b/OpenGLEngine/OpenGLEngine/ResetPenetrationDeltaMoveSystem.cpp new file mode 100644 index 0000000..8b1d203 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/ResetPenetrationDeltaMoveSystem.cpp @@ -0,0 +1,18 @@ +#include "ResetPenetrationDeltaMoveSystem.h" + +namespace Reality +{ + ResetPenetrationDeltaMoveSystem::ResetPenetrationDeltaMoveSystem() + { + requireComponent(); + } + + void ResetPenetrationDeltaMoveSystem::Update(float deltaTime) + { + for (auto e : getEntities()) + { + auto& penetration = e.getComponent(); + penetration.deltaMove = Vector3(0, 0, 0); + } + } +} diff --git a/OpenGLEngine/OpenGLEngine/ResetPenetrationDeltaMoveSystem.h b/OpenGLEngine/OpenGLEngine/ResetPenetrationDeltaMoveSystem.h new file mode 100644 index 0000000..958dfed --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/ResetPenetrationDeltaMoveSystem.h @@ -0,0 +1,13 @@ +#pragma once +#include "ECSConfig.h" +#include "PenetrationDeltaMoveComponent.h" + +namespace Reality +{ + class ResetPenetrationDeltaMoveSystem : public ECSSystem + { + public: + ResetPenetrationDeltaMoveSystem(); + void Update(float deltaTime); + }; +} diff --git a/OpenGLEngine/OpenGLEngine/RodComponent.h b/OpenGLEngine/OpenGLEngine/RodComponent.h index 33583ad..5c5b3ef 100644 --- a/OpenGLEngine/OpenGLEngine/RodComponent.h +++ b/OpenGLEngine/OpenGLEngine/RodComponent.h @@ -5,11 +5,17 @@ namespace Reality { struct RodComponent { - RodComponent(ECSEntity a = ECSEntity(), ECSEntity b = ECSEntity(), float _length = 10) - : entityA(a), entityB(b), length(_length) - {} + RodComponent(ECSEntity a = ECSEntity(), + ECSEntity b = ECSEntity(), + float _rodLength = 10) + : entityA(a), + entityB(b), + rodLength(_rodLength) + { + + } ECSEntity entityA; ECSEntity entityB; - float length; + float rodLength; }; } diff --git a/OpenGLEngine/OpenGLEngine/RodSystem.cpp b/OpenGLEngine/OpenGLEngine/RodSystem.cpp index f1da27e..c3f6bb7 100644 --- a/OpenGLEngine/OpenGLEngine/RodSystem.cpp +++ b/OpenGLEngine/OpenGLEngine/RodSystem.cpp @@ -1,6 +1,6 @@ #include "RodSystem.h" #include "TransformComponent.h" -#include "ParticleContactComponent.h" +#include "ParticleContactEvent.h" namespace Reality { @@ -14,49 +14,50 @@ namespace Reality for (auto e : getEntities()) { auto& rod = e.getComponent(); - float currentLength = glm::length(rod.entityA.getComponent().position - - rod.entityB.getComponent().position); - getWorld().data.renderUtil->DrawSphere(rod.entityA.getComponent().position, 1, Color::Purple); - getWorld().data.renderUtil->DrawSphere(rod.entityB.getComponent().position, 1, Color::Purple); - - if (currentLength == rod.length) + if (rod.entityA.hasComponent() && + rod.entityB.hasComponent()) { - continue; + auto& transformA = rod.entityA.getComponent(); + auto& transformB = rod.entityB.getComponent(); + + Vector3 relativePos = transformA.position - transformB.position; + float length = glm::length(relativePos); + + if (length > rod.rodLength) + { + Vector3 normal = -glm::normalize(relativePos); + float penetration = length - rod.rodLength; + + getWorld().getEventManager().emitEvent( + rod.entityA, + rod.entityB, + 0, + normal, + penetration + ); + } + + if (length < rod.rodLength) + { + Vector3 normal = glm::normalize(relativePos); + float penetration = rod.rodLength - length; + + getWorld().getEventManager().emitEvent( + rod.entityA, + rod.entityB, + 0, + normal, + penetration + ); + } + + getWorld().data.renderUtil->DrawLine( + transformA.position, + transformB.position, + Color::Beige + ); } - - Vector3 normal = glm::normalize(rod.entityB.getComponent().position - - rod.entityA.getComponent().position); - - - if (currentLength > rod.length) - { - auto contactEntity = getWorld().createEntity(); - contactEntity.addComponent( - rod.entityA, - rod.entityB, - 0, - normal, - currentLength - rod.length); - getWorld().data.renderUtil->DrawLine(rod.entityA.getComponent().position, - rod.entityB.getComponent().position, - Color::Yellow); - } - else - { - auto contactEntity = getWorld().createEntity(); - contactEntity.addComponent( - rod.entityA, - rod.entityB, - 0, - -normal, - rod.length - currentLength); - getWorld().data.renderUtil->DrawLine(rod.entityA.getComponent().position, - rod.entityB.getComponent().position, - Color::Yellow); - } - - } } } diff --git a/OpenGLEngine/OpenGLEngine/TriangleComponent.h b/OpenGLEngine/OpenGLEngine/TriangleComponent.h new file mode 100644 index 0000000..04f634d --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/TriangleComponent.h @@ -0,0 +1,19 @@ +#pragma once +#include "ECSConfig.h" + +namespace Reality +{ + struct TriangleComponent + { + TriangleComponent(ECSEntity _vertex_1 = ECSEntity(), ECSEntity _vertex_2 = ECSEntity(), ECSEntity _vertex_3 = ECSEntity()) + : vertex_1(_vertex_1), vertex_2(_vertex_2), vertex_3(_vertex_3) + { + + } + + ECSEntity vertex_1; + ECSEntity vertex_2; + ECSEntity vertex_3; + + }; +} diff --git a/OpenGLEngine/OpenGLEngine/TriangleSystem.cpp b/OpenGLEngine/OpenGLEngine/TriangleSystem.cpp new file mode 100644 index 0000000..6471ff2 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/TriangleSystem.cpp @@ -0,0 +1,61 @@ +#include "TriangleSystem.h" + + +namespace Reality +{ + TriangleSystem::TriangleSystem() + { + + } + + void TriangleSystem::Update(float deltaTime) + { + for (auto e1 : getEntities()) + { + if (e1.hasComponent()) + { + auto& triangle = e1.getComponent(); + + for (auto e2 : getEntities()) + { + if (e2.hasComponent()) + { + auto& particle = e2.getComponent(); + + if (e2.hasComponent()) + { + auto& transform = e2.getComponent(); + Vector3 vertex1 = triangle.vertex_1.getComponent().position; + Vector3 vertex2 = triangle.vertex_2.getComponent().position; + Vector3 vertex3 = triangle.vertex_3.getComponent().position; + + // Calculate normal + Vector3 v1 = glm::normalize(vertex2 - vertex1); + Vector3 v2 = glm::normalize(vertex2 - vertex3); + Vector3 normal = glm::cross(v2, v1); + + float distance = glm::dot(normal, transform.position) - glm::dot(normal, vertex2); + + + if (abs(distance) <= particle.radius) // if there is interaction + { + float penetration = fabs(particle.radius - distance); + + getWorld().getEventManager().emitEvent( + e2, + e1, + 0.8f, + normal, + penetration + ); + getWorld().data.renderUtil->DrawTriangle(vertex1, vertex2, vertex3, Color::Yellow); + } + else // if not + getWorld().data.renderUtil->DrawTriangle(vertex1, vertex2, vertex3, Color::Brown); + } + } + } + } + } + } +} diff --git a/OpenGLEngine/OpenGLEngine/TriangleSystem.h b/OpenGLEngine/OpenGLEngine/TriangleSystem.h new file mode 100644 index 0000000..ebfaf92 --- /dev/null +++ b/OpenGLEngine/OpenGLEngine/TriangleSystem.h @@ -0,0 +1,16 @@ +#pragma once +#include "ECSConfig.h" +#include "TriangleComponent.h" +#include "TransformComponent.h" +#include "ParticleSphereComponent.h" +#include "ParticleContactEvent.h" + +namespace Reality +{ + class TriangleSystem : public ECSSystem + { + public: + TriangleSystem(); + void Update(float deltaTime); + }; +}