实现弹簧
parent
588bfecd65
commit
5bd6647d14
|
@ -31,6 +31,7 @@
|
||||||
<ClInclude Include="src\Mesh.h" />
|
<ClInclude Include="src\Mesh.h" />
|
||||||
<ClInclude Include="src\Model.h" />
|
<ClInclude Include="src\Model.h" />
|
||||||
<ClInclude Include="src\Particle.h" />
|
<ClInclude Include="src\Particle.h" />
|
||||||
|
<ClInclude Include="src\PhysicsManager.h" />
|
||||||
<ClInclude Include="src\RenderPass.h" />
|
<ClInclude Include="src\RenderPass.h" />
|
||||||
<ClInclude Include="src\RenderPassContext.h" />
|
<ClInclude Include="src\RenderPassContext.h" />
|
||||||
<ClInclude Include="src\Shader.h" />
|
<ClInclude Include="src\Shader.h" />
|
||||||
|
@ -51,6 +52,7 @@
|
||||||
<ClCompile Include="src\Mesh.cpp" />
|
<ClCompile Include="src\Mesh.cpp" />
|
||||||
<ClCompile Include="src\Model.cpp" />
|
<ClCompile Include="src\Model.cpp" />
|
||||||
<ClCompile Include="src\Particle.cpp" />
|
<ClCompile Include="src\Particle.cpp" />
|
||||||
|
<ClCompile Include="src\PhysicsManager.cpp" />
|
||||||
<ClCompile Include="src\RenderPass.cpp" />
|
<ClCompile Include="src\RenderPass.cpp" />
|
||||||
<ClCompile Include="src\Shader.cpp" />
|
<ClCompile Include="src\Shader.cpp" />
|
||||||
<ClCompile Include="src\World.cpp" />
|
<ClCompile Include="src\World.cpp" />
|
||||||
|
|
|
@ -22,12 +22,26 @@ DemoWorld::DemoWorld()
|
||||||
sponza->setScale(glm::vec3(2));
|
sponza->setScale(glm::vec3(2));
|
||||||
|
|
||||||
auto particle = std::make_shared<Particle>(10);
|
auto particle = std::make_shared<Particle>(10);
|
||||||
|
particle->setSpeed(glm::vec3(-1, 0, 0));
|
||||||
particle->setPosition({ 4, 5, 0 });
|
particle->setPosition({ 4, 5, 0 });
|
||||||
particle->addForce(std::make_shared<Force>(glm::vec3(0.f, -particle->getMass() * 9.8f, 0.f)));
|
//particle->addForce(std::make_shared<Force>(glm::vec3(0.f, -particle->getMass() * 9.8f, 0.f)));
|
||||||
|
auto particle2 = std::make_shared<Particle>(10, "Models/vampire/vampire.gltf");
|
||||||
|
particle2->setSpeed(glm::vec3(1, 0, 0));
|
||||||
|
particle2->setPosition({ 6, 5, 0 });
|
||||||
|
particle2->setScale(glm::vec3{ 0.4 });
|
||||||
|
|
||||||
|
auto particle3 = std::make_shared<Particle>(10);
|
||||||
|
particle3->setSpeed(glm::vec3(0, 1, 0));
|
||||||
|
particle3->setPosition({ 6, 7, 0 });
|
||||||
|
|
||||||
|
physicsManager.addSpring(particle, particle2, 2, 10, 0);
|
||||||
|
physicsManager.addSpring(particle2, particle3, 2, 10, 0);
|
||||||
|
|
||||||
addActor(actor);
|
addActor(actor);
|
||||||
addActor(actor2);
|
addActor(actor2);
|
||||||
addActor(actor3);
|
addActor(actor3);
|
||||||
addActor(sponza);
|
addActor(sponza);
|
||||||
addActor(particle);
|
addActor(particle);
|
||||||
|
addActor(particle2);
|
||||||
|
addActor(particle3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,17 +7,28 @@ Particle::Particle(float mass)
|
||||||
, debugShader(gl, "Shaders/debug.vert", "Shaders/debug.frag")
|
, debugShader(gl, "Shaders/debug.vert", "Shaders/debug.frag")
|
||||||
{
|
{
|
||||||
model = Model::createSphere(gl);
|
model = Model::createSphere(gl);
|
||||||
setScale(glm::vec3(0.4));
|
setScale(glm::vec3(0.2));
|
||||||
|
}
|
||||||
|
|
||||||
|
Particle::Particle(float mass, const std::string& path)
|
||||||
|
: Actor(path)
|
||||||
|
, mass(mass)
|
||||||
|
, debugShader(gl, "Shaders/debug.vert", "Shaders/debug.frag")
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Particle::logicalTick(float deltaTime)
|
void Particle::logicalTick(float deltaTime)
|
||||||
{
|
{
|
||||||
|
resultantForce = glm::vec3(0);
|
||||||
|
for (auto& force : forces)
|
||||||
|
resultantForce += force->value;
|
||||||
|
|
||||||
auto pos = getPosition() + speed * deltaTime + 0.5f * resultantForce / mass * deltaTime * deltaTime;
|
auto pos = getPosition() + speed * deltaTime + 0.5f * resultantForce / mass * deltaTime * deltaTime;
|
||||||
speed += resultantForce / mass * deltaTime;
|
speed += resultantForce / mass * deltaTime;
|
||||||
if (speed.y < 0 && pos.y < 0.4)
|
//if (speed.y < 0 && pos.y < 0.4)
|
||||||
{
|
//{
|
||||||
speed.y = -speed.y;
|
// speed.y = -speed.y;
|
||||||
}
|
//}
|
||||||
setPosition(pos);
|
setPosition(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +59,7 @@ void Particle::draw(const RenderPassContext& context, Shader& shader)
|
||||||
debugShader.use();
|
debugShader.use();
|
||||||
debugShader.setUniformValue("projection", *context.projection);
|
debugShader.setUniformValue("projection", *context.projection);
|
||||||
debugShader.setUniformValue("view", *context.view);
|
debugShader.setUniformValue("view", *context.view);
|
||||||
glm::mat4 modelMatrix = glm::translate(glm::mat4(1), getPosition()) * glm::scale(glm::mat4(1), getScale()) * glm::mat4_cast(getRotation());
|
glm::mat4 modelMatrix = glm::translate(glm::mat4(1), getPosition()) * glm::scale(glm::mat4(1), getScale()) * glm::mat4_cast(getRotation()) * glm::scale(glm::mat4(1), glm::vec3(glm::abs(resultantForce / mass)));
|
||||||
gl->BindVertexArray(vao);
|
gl->BindVertexArray(vao);
|
||||||
for (auto& force : forces)
|
for (auto& force : forces)
|
||||||
{
|
{
|
||||||
|
@ -64,16 +75,24 @@ void Particle::draw(const RenderPassContext& context, Shader& shader)
|
||||||
void Particle::addForce(std::shared_ptr<Force> force)
|
void Particle::addForce(std::shared_ptr<Force> force)
|
||||||
{
|
{
|
||||||
forces.insert(force);
|
forces.insert(force);
|
||||||
resultantForce += force->value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Particle::removeForce(std::shared_ptr<Force> force)
|
void Particle::removeForce(std::shared_ptr<Force> force)
|
||||||
{
|
{
|
||||||
forces.erase(force);
|
forces.erase(force);
|
||||||
resultantForce -= force->value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float Particle::getMass()
|
float Particle::getMass()
|
||||||
{
|
{
|
||||||
return mass;
|
return mass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 Particle::getSpeed()
|
||||||
|
{
|
||||||
|
return speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Particle::setSpeed(const glm::vec3& speed)
|
||||||
|
{
|
||||||
|
this->speed = speed;
|
||||||
|
}
|
||||||
|
|
|
@ -12,12 +12,15 @@ class Particle : public Actor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Particle(float mass);
|
Particle(float mass);
|
||||||
|
Particle(float mass, const std::string& path);
|
||||||
virtual ~Particle() = default;
|
virtual ~Particle() = default;
|
||||||
virtual void logicalTick(float deltaTime);
|
virtual void logicalTick(float deltaTime);
|
||||||
virtual void draw(const RenderPassContext& context, Shader& shader);
|
virtual void draw(const RenderPassContext& context, Shader& shader);
|
||||||
void addForce(std::shared_ptr<Force> force);
|
void addForce(std::shared_ptr<Force> force);
|
||||||
void removeForce(std::shared_ptr<Force> force);
|
void removeForce(std::shared_ptr<Force> force);
|
||||||
float getMass();
|
float getMass();
|
||||||
|
glm::vec3 getSpeed();
|
||||||
|
void setSpeed(const glm::vec3& speed);
|
||||||
private:
|
private:
|
||||||
float mass;
|
float mass;
|
||||||
glm::vec3 speed = glm::vec3(0.f);
|
glm::vec3 speed = glm::vec3(0.f);
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include "PhysicsManager.h"
|
||||||
|
|
||||||
|
void PhysicsManager::tick(float deltaTime)
|
||||||
|
{
|
||||||
|
for (auto iter = constraints.begin(); iter < constraints.end(); )
|
||||||
|
{
|
||||||
|
if (iter->p1.expired() || iter->p2.expired())
|
||||||
|
iter = constraints.erase(iter);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iter->f1->value = iter->solver(*iter->p1.lock(), *iter->p2.lock());
|
||||||
|
iter->f2->value = -iter->f1->value;
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsManager::addSpring(std::shared_ptr<Particle> p1, std::shared_ptr<Particle> p2, float length, float ks, float kd)
|
||||||
|
{
|
||||||
|
auto f1 = std::make_shared<Force>(glm::vec3(0));
|
||||||
|
auto f2 = std::make_shared<Force>(glm::vec3(0));
|
||||||
|
p1->addForce(f1);
|
||||||
|
p2->addForce(f2);
|
||||||
|
constraints.emplace_back(p1, p2, [length, ks, kd](Particle& p1, Particle& p2) {
|
||||||
|
auto d = glm::distance(p1.getPosition(), p2.getPosition());
|
||||||
|
float dt = 1.f;
|
||||||
|
auto vd = glm::distance(p1.getPosition() + p1.getSpeed() * dt, p2.getPosition() + p2.getSpeed() * dt) / dt;
|
||||||
|
return -(ks * (d - length) + kd * vd) * (p1.getPosition() - p2.getPosition()) / d;
|
||||||
|
}, f1, f2);
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Particle.h"
|
||||||
|
|
||||||
|
struct BinaryConstraint
|
||||||
|
{
|
||||||
|
std::weak_ptr<Particle> p1;
|
||||||
|
std::weak_ptr<Particle> p2;
|
||||||
|
std::function<glm::vec3(Particle& p1, Particle& p2)> solver; /// f1
|
||||||
|
std::shared_ptr<Force> f1;
|
||||||
|
std::shared_ptr<Force> f2;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PhysicsManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void tick(float deltaTime);
|
||||||
|
void addSpring(std::shared_ptr<Particle> p1, std::shared_ptr<Particle> p2, float length, float ks, float kd);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<BinaryConstraint> constraints;
|
||||||
|
};
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
void World::logicalTick(float deltaTime)
|
void World::logicalTick(float deltaTime)
|
||||||
{
|
{
|
||||||
|
physicsManager.tick(deltaTime);
|
||||||
for (auto& actor : actors)
|
for (auto& actor : actors)
|
||||||
actor->logicalTick(deltaTime);
|
actor->logicalTick(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Actor.h"
|
#include "Actor.h"
|
||||||
#include "RenderPassContext.h"
|
#include "RenderPassContext.h"
|
||||||
|
#include "PhysicsManager.h"
|
||||||
|
|
||||||
class World
|
class World
|
||||||
{
|
{
|
||||||
|
@ -11,5 +12,7 @@ public:
|
||||||
void draw(const RenderPassContext& context, Shader& shader);
|
void draw(const RenderPassContext& context, Shader& shader);
|
||||||
void addActor(std::shared_ptr<Actor> actor);
|
void addActor(std::shared_ptr<Actor> actor);
|
||||||
std::pair<glm::vec3, glm::vec3> getAABB();
|
std::pair<glm::vec3, glm::vec3> getAABB();
|
||||||
|
protected:
|
||||||
|
PhysicsManager physicsManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue