#ifndef STAN_SPRING_NETWORK_H #define STAN_SPRING_NETWORK_H #include "vec3n.h" #define SPRING_STRUCT (0) #define SPRING_SHEAR (1) #define SPRING_BEND (2) class SpringNetwork { public: class Spring { public: int type; // index into coefficients spring_k[] float restlen; int a, b; // spring endpoints vector indices int iab, iba; // indices into off-diagonal blocks of sparse matrix Spring() {} Spring(int _type, int _a, int _b, float _restlen) : type(_type), a(_a), b(_b), restlen(_restlen) { iab = iba = -1; } }; Array springs; float3N X; // positions of all points float3N V; // velocities float3N F; // force on each point float3N dV; // change in velocity float3Nx3N A; // big matrix we solve system with float3Nx3N dFdX; // big matrix of derivative of force wrt position float3Nx3N dFdV; // big matrix of derivative of force wrt velocity float3Nx3N S; // used for our constraints - contains only some diagonal blocks as needed S[i,i] int awake; float3 bmin, bmax; union { struct { float spring_struct; float spring_shear; float spring_bend; }; float spring_k[3]; }; float spring_damp; float spring_air; float cloth_step; // delta time for cloth float3 cloth_gravity; float cloth_sleepthreshold; int cloth_sleepcount; SpringNetwork(int _n); Spring &AddBlocks(Spring &s); Spring &CreateSpring(int type, int a, int b, float restlen) { return AddBlocks(springs.Add(Spring(type, a, b, restlen))); } Spring &CreateSpring(int type, int a, int b) { return CreateSpring(type, a, b, magnitude(X[b] - X[a])); } void UpdateLimits() { BoxLimits(X.element, X.count, bmin, bmax); } void Wake() { awake = cloth_sleepcount; } void Simulate(float dt); void PreSolveSpring(const Spring &s); void CalcForces(); }; #endif //STAN_SPRING_NETWORK_H