Moved init/free functions for solver data out of implicit core.

This also initializes spring matrix indices (off-diagonal 3x3 blocks),
which now uses a new API function.
This commit is contained in:
Lukas Tönne 2014-09-14 14:16:03 +02:00
parent d2e8a72d8a
commit ac071de405
3 changed files with 79 additions and 56 deletions

@ -43,6 +43,45 @@
#include "BPH_mass_spring.h"
#include "implicit.h"
int BPH_cloth_solver_init(Object *UNUSED(ob), ClothModifierData *clmd)
{
Cloth *cloth = clmd->clothObject;
ClothVertex *verts = cloth->verts;
const float ZERO[3] = {0.0f, 0.0f, 0.0f};
Implicit_Data *id;
unsigned int i;
cloth->implicit = id = BPH_mass_spring_solver_create(cloth->numverts, cloth->numsprings);
for (i = 0; i < cloth->numverts; i++) {
BPH_mass_spring_set_vertex_mass(id, i, verts[i].mass);
}
// init springs
LinkNode *link = cloth->springs;
for (i = 0; link; link = link->next, ++i) {
ClothSpring *spring = (ClothSpring *)link->link;
spring->matrix_index = BPH_mass_spring_init_spring(id, i, spring->ij, spring->kl);
}
for (i = 0; i < cloth->numverts; i++) {
BPH_mass_spring_set_motion_state(id, i, verts[i].x, ZERO);
}
return 1;
}
void BPH_cloth_solver_free(ClothModifierData *clmd)
{
Cloth *cloth = clmd->clothObject;
if (cloth->implicit) {
BPH_mass_spring_solver_free(cloth->implicit);
cloth->implicit = NULL;
}
}
void BKE_cloth_solver_set_positions(ClothModifierData *clmd)
{
Cloth *cloth = clmd->clothObject;

@ -65,6 +65,8 @@ BLI_INLINE void implicit_print_matrix_elem(float v)
void BPH_mass_spring_set_root_motion(struct Implicit_Data *data, int index, const float loc[3], const float vel[3], float rot[3][3], const float angvel[3]);
void BPH_mass_spring_set_motion_state(struct Implicit_Data *data, int index, const float x[3], const float v[3]);
void BPH_mass_spring_set_vertex_mass(struct Implicit_Data *data, int index, float mass);
int BPH_mass_spring_init_spring(struct Implicit_Data *data, int index, int v1, int v2);
#ifdef __cplusplus
}

@ -549,13 +549,27 @@ static void print_bfmatrix(fmatrix3x3 *m3)
}
#endif
BLI_INLINE void init_fmatrix(fmatrix3x3 *matrix, int r, int c)
{
matrix->r = r;
matrix->c = c;
}
/* create big matrix */
DO_INLINE fmatrix3x3 *create_bfmatrix(unsigned int verts, unsigned int springs)
{
// TODO: check if memory allocation was successful */
fmatrix3x3 *temp = (fmatrix3x3 *)MEM_callocN(sizeof(fmatrix3x3) * (verts + springs), "cloth_implicit_alloc_matrix");
int i;
temp[0].vcount = verts;
temp[0].scount = springs;
/* vertex part of the matrix is diagonal blocks */
for (i = 0; i < verts; ++i) {
init_fmatrix(temp + i, i, i);
}
return temp;
}
/* delete big matrix */
@ -705,6 +719,8 @@ Implicit_Data *BPH_mass_spring_solver_create(int numverts, int numsprings)
id->root = MEM_callocN(sizeof(RootTransform) * numverts, "root transforms");
initdiag_bfmatrix(id->bigI, I);
return id;
}
@ -733,62 +749,6 @@ void BPH_mass_spring_solver_free(Implicit_Data *id)
MEM_freeN(id);
}
int BPH_cloth_solver_init(Object *UNUSED(ob), ClothModifierData *clmd)
{
Cloth *cloth = clmd->clothObject;
ClothVertex *verts = cloth->verts;
Implicit_Data *id;
unsigned int i;
LinkNode *search;
if (G.debug_value > 0)
printf("implicit_init\n");
cloth->implicit = id = BPH_mass_spring_solver_create(cloth->numverts, cloth->numsprings);
for (i = 0; i < cloth->numverts; i++) {
id->A[i].r = id->A[i].c = id->dFdV[i].r = id->dFdV[i].c = id->dFdX[i].r = id->dFdX[i].c = id->P[i].c = id->P[i].r = id->Pinv[i].c = id->Pinv[i].r = id->bigI[i].c = id->bigI[i].r = id->M[i].r = id->M[i].c = i;
initdiag_fmatrixS(id->M[i].m, verts[i].mass);
}
// init springs
search = cloth->springs;
for (i = 0; i < cloth->numsprings; i++) {
ClothSpring *spring = search->link;
// dFdV_start[i].r = big_I[i].r = big_zero[i].r =
id->A[i+cloth->numverts].r = id->dFdV[i+cloth->numverts].r = id->dFdX[i+cloth->numverts].r =
id->P[i+cloth->numverts].r = id->Pinv[i+cloth->numverts].r = id->bigI[i+cloth->numverts].r = id->M[i+cloth->numverts].r = spring->ij;
// dFdV_start[i].c = big_I[i].c = big_zero[i].c =
id->A[i+cloth->numverts].c = id->dFdV[i+cloth->numverts].c = id->dFdX[i+cloth->numverts].c =
id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = id->M[i+cloth->numverts].c = spring->kl;
spring->matrix_index = i + cloth->numverts;
search = search->next;
}
initdiag_bfmatrix(id->bigI, I);
for (i = 0; i < cloth->numverts; i++) {
copy_v3_v3(id->X[i], verts[i].x);
}
return 1;
}
void BPH_cloth_solver_free(ClothModifierData *clmd)
{
Cloth *cloth = clmd->clothObject;
if (cloth->implicit) {
BPH_mass_spring_solver_free(cloth->implicit);
cloth->implicit = NULL;
}
}
/* ==== Transformation of Moving Reference Frame ====
* x_world, v_world, f_world, a_world, dfdx_world, dfdv_world : state variables in world space
* x_root, v_root, f_root, a_root, dfdx_root, dfdv_root : state variables in root space
@ -2748,4 +2708,26 @@ void BPH_mass_spring_set_motion_state(Implicit_Data *data, int index, const floa
vel_world_to_root(data->V[index], data->X[index], v, root);
}
void BPH_mass_spring_set_vertex_mass(Implicit_Data *data, int index, float mass)
{
unit_m3(data->M[index].m);
mul_m3_fl(data->M[index].m, mass);
}
int BPH_mass_spring_init_spring(Implicit_Data *data, int index, int v1, int v2)
{
int s = data->M[0].vcount + index; /* index from array start */
init_fmatrix(data->bigI + s, v1, v2);
init_fmatrix(data->M + s, v1, v2);
init_fmatrix(data->dFdX + s, v1, v2);
init_fmatrix(data->dFdV + s, v1, v2);
init_fmatrix(data->A + s, v1, v2);
// init_fmatrix(data->S + s, v1, v2); // has no off-diagonal spring entries
init_fmatrix(data->P + s, v1, v2);
init_fmatrix(data->Pinv + s, v1, v2);
return s;
}
#endif /* IMPLICIT_SOLVER_BLENDER */