Compare commits

...

2 Commits

Author SHA1 Message Date
wuyize b0f893faed 合并 2023-04-20 00:24:03 +08:00
wuyize 05347b94e0 完成吊桥 2023-04-20 00:21:22 +08:00
5 changed files with 86 additions and 28 deletions

View File

@ -20,34 +20,63 @@ DemoWorld::DemoWorld()
actor3->setPosition({ -1,0,-1 });
auto sponza = std::make_shared<Actor>("Models\\Sponza\\Sponza.gltf");
sponza->setScale(glm::vec3(2));
auto particle = std::make_shared<Particle>(10);
particle->setSpeed(glm::vec3(-1, 0, 0));
particle->setPosition({ 4, 5, 0 });
//particle->addForce(std::make_shared<Force>(glm::vec3(0.f, -particle->getMass() * 9.8f, 0.f)));
auto particle2 = std::make_shared<Particle>(10, "Models\\pallet_wood\\pallet_wood.gltf");
particle2->setSpeed(glm::vec3(1, 0, 0));
particle2->setPosition({ 6, 5, 0 });
particle2->setScale(glm::vec3{ 0.002 });
auto particle3 = std::make_shared<Particle>(10);
particle3->setSpeed(glm::vec3(0, 1, 0));
particle3->setPosition({ 6, 7, 0 });
auto shoot = std::make_shared<Actor>("Models\\shootgun\\scene.gltf");
shoot->setPosition({ 5,0,-1 });
shoot->setScale(glm::vec3{ 50 });
physicsManager.addSpring(particle, particle2, 2, 10, 0);
physicsManager.addSpring(particle2, particle3, 2, 10, 0);
addActor(actor);
addActor(actor2);
addActor(actor3);
addActor(sponza);
addActor(particle);
addActor(particle2);
addActor(particle3);
addActor(shoot);
float boardMass = 10;
glm::vec3 boardScale(0.01);
auto boardFilePath = "Models\\pallet_wood\\pallet_wood.gltf";
int particleCount = 5;
for (int i = 0; i < particleCount; i++)
{
auto particle = std::make_shared<Particle>(boardMass, boardFilePath);
particle->setPosition({ 0, 8, glm::mix(-3.1f,2.f,(double)i / (particleCount - 1)) });
particle->setScale(boardScale);
if (i == 0 || i == particleCount - 1)
{
particle->setFixed(true);
}
else
{
particle->enableGravity();
}
particles.push_back(particle);
addActor(particle);
if (i != 0)
{
float ks = 300, kd = 100;
physicsManager.addSpring(particles[i - 1], particle, 0.005, ks, kd);
}
}
}
void DemoWorld::logicalTick(float deltaTime)
{
World::logicalTick(deltaTime);
for (int i = 0; i < particles.size(); i++)
{
glm::vec3 d;
if (i == 0)
d = glm::normalize(particles[i + 1]->getPosition() - particles[i]->getPosition());
else if (i == particles.size() - 1)
d = glm::normalize(particles[i]->getPosition() - particles[i - 1]->getPosition());
else
{
auto dL = particles[i + 1]->getPosition() - particles[i]->getPosition();
auto dR = particles[i]->getPosition() - particles[i - 1]->getPosition();
d = (glm::normalize(dL) + glm::normalize(dR)) / 2.f;
}
particles[i]->setRotaion(glm::rotation(glm::vec3(0, 0, 1), d));
}
}

View File

@ -5,5 +5,8 @@ class DemoWorld : public World
{
public:
DemoWorld();
virtual void logicalTick(float deltaTime) override;
private:
std::vector<std::shared_ptr<Particle>> particles;
};

View File

@ -23,13 +23,22 @@ void Particle::logicalTick(float deltaTime)
for (auto& force : forces)
resultantForce += force->value;
auto pos = getPosition() + speed * deltaTime + 0.5f * resultantForce / mass * deltaTime * deltaTime;
speed += resultantForce / mass * deltaTime;
//if (speed.y < 0 && pos.y < 0.4)
//{
// speed.y = -speed.y;
//}
setPosition(pos);
if (fixed)
{
speed = glm::vec3(0);
}
else
{
//auto pos = getPosition() + speed * deltaTime + 0.5f * resultantForce / mass * deltaTime * deltaTime;
speed += resultantForce / mass * deltaTime;
auto pos = getPosition() + speed * deltaTime;
//if (speed.y < 0 && pos.y < 0.4)
//{
// speed.y = -speed.y;
//}
setPosition(pos);
}
}
void Particle::draw(const RenderPassContext& context, Shader& shader)
@ -57,9 +66,10 @@ void Particle::draw(const RenderPassContext& context, Shader& shader)
}
debugShader.use();
gl->DepthMask(false);
debugShader.setUniformValue("projection", *context.projection);
debugShader.setUniformValue("view", *context.view);
glm::mat4 modelMatrix = glm::translate(glm::mat4(1), getPosition()) * glm::mat4_cast(getRotation()) * glm::scale(glm::mat4(1), glm::vec3(glm::abs(resultantForce / mass)));
glm::mat4 modelMatrix = glm::translate(glm::mat4(1), getPosition());// *glm::scale(glm::mat4(1), glm::vec3(glm::abs(resultantForce / mass)));
gl->BindVertexArray(vao);
for (auto& force : forces)
{
@ -68,6 +78,7 @@ void Particle::draw(const RenderPassContext& context, Shader& shader)
gl->DrawArrays(GL_LINES, 0, 2);
}
gl->BindVertexArray(0);
gl->DepthMask(true);
shader.use();
}
}
@ -96,3 +107,13 @@ void Particle::setSpeed(const glm::vec3& speed)
{
this->speed = speed;
}
void Particle::setFixed(bool fixed)
{
this->fixed = fixed;
}
void Particle::enableGravity()
{
addForce(std::make_shared<Force>(glm::vec3(0.f, -getMass() * 9.80665f, 0.f)));
}

View File

@ -21,8 +21,12 @@ public:
float getMass();
glm::vec3 getSpeed();
void setSpeed(const glm::vec3& speed);
void setFixed(bool fixed);
void enableGravity();
private:
bool fixed = false;
float mass;
glm::vec3 acceleration = glm::vec3(0);
glm::vec3 speed = glm::vec3(0.f);
std::set<std::shared_ptr<Force>> forces;
glm::vec3 resultantForce = glm::vec3(0);

View File

@ -25,6 +25,7 @@ void PhysicsManager::addSpring(std::shared_ptr<Particle> p1, std::shared_ptr<Par
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;
if (d == 0) return glm::vec3(0);
return -(ks * (d - length) + kd * vd) * (p1.getPosition() - p2.getPosition()) / d;
}, f1, f2);
}