|
|
|
@ -17,7 +17,13 @@ struct Edge { |
|
|
|
|
float restLength; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct Tetrahedron { |
|
|
|
|
uint a; |
|
|
|
|
uint b; |
|
|
|
|
uint c; |
|
|
|
|
uint d; |
|
|
|
|
float restVolume; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
layout (std430, set = 0, binding = 0) buffer VertexBuffer { |
|
|
|
@ -28,6 +34,10 @@ layout (std430, set = 0, binding = 2) buffer EdgeBuffer { |
|
|
|
|
Edge edges[]; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
layout (std430, set = 0, binding = 4) buffer TetrahedronBuffer { |
|
|
|
|
Tetrahedron tetrahedra[]; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
layout (std140, set = 0, binding = 5) uniform Sizes { |
|
|
|
|
uint vertexCount; |
|
|
|
|
uint faceCount; |
|
|
|
@ -57,30 +67,68 @@ void preSolve(uint vID){ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void solveEdge(uint eID){ |
|
|
|
|
Edge e = edges[eID]; |
|
|
|
|
Edge edge = edges[eID]; |
|
|
|
|
|
|
|
|
|
Vertex v1 = vertices[e.a]; |
|
|
|
|
Vertex v2 = vertices[e.b]; |
|
|
|
|
Vertex v1 = vertices[edge.a]; |
|
|
|
|
Vertex v2 = vertices[edge.b]; |
|
|
|
|
|
|
|
|
|
vec3 diff = v1.position - v2.position; |
|
|
|
|
float currentLength = length(diff); |
|
|
|
|
|
|
|
|
|
float alpha = 0.0001 / (dt * dt); |
|
|
|
|
float alpha = 0.3 / dt / dt; |
|
|
|
|
|
|
|
|
|
float s = (currentLength - e.restLength) / (1 + 1 + alpha); |
|
|
|
|
float s = -(currentLength - edge.restLength) / (v1.w + v2.w + alpha); |
|
|
|
|
|
|
|
|
|
vec3 g1 = normalize(diff); |
|
|
|
|
vec3 g2 = -g1; |
|
|
|
|
|
|
|
|
|
vec3 delta1 = -s * 1 * g1; |
|
|
|
|
vec3 delta2 = -s * 1 * g2; |
|
|
|
|
vec3 delta1 = s * v1.w * g1; |
|
|
|
|
vec3 delta2 = s * v2.w * g2; |
|
|
|
|
|
|
|
|
|
vertices[e.a].position += delta1; |
|
|
|
|
vertices[e.b].position += delta2; |
|
|
|
|
vertices[edge.a].position += delta1; |
|
|
|
|
vertices[edge.b].position += delta2; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void solveTetrahedron(uint tetID){ |
|
|
|
|
Tetrahedron tetrahedron = tetrahedra[tetID]; |
|
|
|
|
|
|
|
|
|
Vertex va = vertices[tetrahedron.a]; |
|
|
|
|
Vertex vb = vertices[tetrahedron.b]; |
|
|
|
|
Vertex vc = vertices[tetrahedron.c]; |
|
|
|
|
Vertex vd = vertices[tetrahedron.d]; |
|
|
|
|
|
|
|
|
|
vec3 a = va.position; |
|
|
|
|
vec3 b = vb.position; |
|
|
|
|
vec3 c = vc.position; |
|
|
|
|
vec3 d = vd.position; |
|
|
|
|
|
|
|
|
|
float volumeError = dot(d - a, cross(b - a, c - a)) / 6 - tetrahedron.restVolume; |
|
|
|
|
|
|
|
|
|
vec3 ga = cross(d - b, c - b) / 6; |
|
|
|
|
vec3 gb = cross(c - a, d - a) / 6; |
|
|
|
|
vec3 gc = cross(d - a, b - a) / 6; |
|
|
|
|
vec3 gd = cross(b - a, c - a) / 6; |
|
|
|
|
|
|
|
|
|
float w = |
|
|
|
|
va.w * dot(ga, ga) + |
|
|
|
|
vb.w * dot(gb, gb) + |
|
|
|
|
vc.w * dot(gc, gc) + |
|
|
|
|
vd.w * dot(gd, gd); |
|
|
|
|
|
|
|
|
|
if (w == 0) return; |
|
|
|
|
|
|
|
|
|
float alpha = 0 / dt / dt; |
|
|
|
|
float s = -volumeError / (w + alpha); |
|
|
|
|
|
|
|
|
|
vec3 addA = s * ga * va.w; |
|
|
|
|
vec3 addB = s * gb * vb.w; |
|
|
|
|
vec3 addC = s * gc * vc.w; |
|
|
|
|
vec3 addD = s * gd * vd.w; |
|
|
|
|
|
|
|
|
|
vertices[tetrahedron.a].position += addA; |
|
|
|
|
vertices[tetrahedron.b].position += addB; |
|
|
|
|
vertices[tetrahedron.c].position += addC; |
|
|
|
|
vertices[tetrahedron.d].position += addD; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void postSolve(uint vID){ |
|
|
|
|