|
|
|
#version 450
|
|
|
|
|
|
|
|
layout (local_size_x = 32) in;
|
|
|
|
|
|
|
|
struct Vertex {
|
|
|
|
vec3 position;
|
|
|
|
vec3 color;
|
|
|
|
vec3 normal;
|
|
|
|
vec3 velocity;
|
|
|
|
vec3 prevPosition;
|
|
|
|
float w;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Edge {
|
|
|
|
uint a;
|
|
|
|
uint b;
|
|
|
|
float restLength;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
layout (std430, set = 0, binding = 0) buffer VertexBuffer {
|
|
|
|
Vertex vertices[];
|
|
|
|
};
|
|
|
|
|
|
|
|
layout (std430, set = 0, binding = 2) buffer EdgeBuffer {
|
|
|
|
Edge edges[];
|
|
|
|
};
|
|
|
|
|
|
|
|
layout (std140, set = 0, binding = 5) uniform Sizes {
|
|
|
|
uint vertexCount;
|
|
|
|
uint faceCount;
|
|
|
|
};
|
|
|
|
|
|
|
|
layout (std140, set = 1, binding = 0) uniform Properties {
|
|
|
|
vec3 gravity;
|
|
|
|
float dt;
|
|
|
|
uint k;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Partition {
|
|
|
|
uint offset;
|
|
|
|
uint size;
|
|
|
|
};
|
|
|
|
|
|
|
|
layout (push_constant, std430) uniform PushConstants {
|
|
|
|
uint state;
|
|
|
|
Partition edgePartition;
|
|
|
|
Partition tetrahedronPartition;
|
|
|
|
};
|
|
|
|
|
|
|
|
void preSolve(uint vID){
|
|
|
|
vertices[vID].prevPosition = vertices[vID].position;
|
|
|
|
// vertices[vID].velocity += dt * gravity;
|
|
|
|
vertices[vID].position += dt * vertices[vID].velocity;
|
|
|
|
}
|
|
|
|
|
|
|
|
void solveEdge(uint eID){
|
|
|
|
Edge e = edges[eID];
|
|
|
|
|
|
|
|
Vertex v1 = vertices[e.a];
|
|
|
|
Vertex v2 = vertices[e.b];
|
|
|
|
|
|
|
|
vec3 diff = v1.position - v2.position;
|
|
|
|
float currentLength = length(diff);
|
|
|
|
|
|
|
|
float alpha = 0.0001 / (dt * dt);
|
|
|
|
|
|
|
|
float s = (currentLength - e.restLength) / (1 + 1 + alpha);
|
|
|
|
|
|
|
|
vec3 g1 = normalize(diff);
|
|
|
|
vec3 g2 = -g1;
|
|
|
|
|
|
|
|
vec3 delta1 = -s * 1 * g1;
|
|
|
|
vec3 delta2 = -s * 1 * g2;
|
|
|
|
|
|
|
|
vertices[e.a].position += delta1;
|
|
|
|
vertices[e.b].position += delta2;
|
|
|
|
}
|
|
|
|
|
|
|
|
void solveTetrahedron(uint tetID){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void postSolve(uint vID){
|
|
|
|
vertices[vID].velocity = (vertices[vID].position - vertices[vID].prevPosition) / dt;
|
|
|
|
}
|
|
|
|
|
|
|
|
void main() {
|
|
|
|
uint id = gl_GlobalInvocationID.x;
|
|
|
|
switch (state){
|
|
|
|
case 0:
|
|
|
|
if (id < vertexCount){
|
|
|
|
preSolve(id);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (id < edgePartition.size){
|
|
|
|
solveEdge(id + edgePartition.offset);
|
|
|
|
}
|
|
|
|
if (id < tetrahedronPartition.size){
|
|
|
|
solveTetrahedron(id + tetrahedronPartition.offset);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if (id < vertexCount){
|
|
|
|
postSolve(id);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|