dust3d/src/ragdoll.h

92 lines
2.3 KiB
C++

#ifndef DUST3D_RAGDOLL_H
#define DUST3D_RAGDOLL_H
#include <vector>
#include <QVector3D>
#include <unordered_map>
class Ragdoll
{
public:
struct Parameters
{
size_t iterations = 1;
};
struct Chain
{
size_t from;
size_t to;
double restLength;
};
struct VertexMotion
{
QVector3D position;
QVector3D lastPosition;
QVector3D force;
bool fixed = false;
double radius = 0.0;
};
struct JointConstraint
{
size_t joint;
size_t first;
size_t second;
double minDegrees;
double maxDegrees;
};
Ragdoll(const std::vector<QVector3D> *vertices,
const std::vector<std::pair<size_t, size_t>> *links) :
m_vertices(vertices),
m_links(links)
{
}
void addJointConstraint(size_t joint,
size_t first,
size_t second,
double minDegrees,
double maxDegrees)
{
JointConstraint jointConstraint = {
joint, first, second, minDegrees, maxDegrees
};
m_jointConstraints.push_back(jointConstraint);
}
void setExternalForce(const QVector3D &externalForce)
{
m_externalForce = externalForce;
}
void start();
void simulate(double stepSize);
const VertexMotion &getVertexMotion(size_t vertexIndex);
void updateVertexPosition(size_t vertexIndex, const QVector3D &position);
void updateVertexRadius(size_t vertexIndex, double radius);
void fixVertexPosition(size_t vertexIndex);
private:
Parameters m_parameters;
std::vector<Chain> m_chains;
const std::vector<QVector3D> *m_vertices = nullptr;
const std::vector<std::pair<size_t, size_t>> *m_links = nullptr;
std::vector<JointConstraint> m_jointConstraints;
std::unordered_map<size_t, VertexMotion> m_vertexMotions;
QVector3D m_externalForce;
double m_groundY = 0.0;
void initializeVertexMotions();
void prepareChains();
void updateVertexForces();
void applyConstraints();
void doVerletIntegration(double stepSize);
void applyBoundingConstraints(VertexMotion *vertexMotion);
void outputChainsForDebug(const char *filename, const std::vector<Chain> &springs);
};
#endif