//.........这里部分代码省略.........
case WALK_MODAL_SLOW_ENABLE:
walk->is_slow = true;
break;
case WALK_MODAL_SLOW_DISABLE:
walk->is_slow = false;
break;
#define JUMP_SPEED_MIN 1.0f
#define JUMP_TIME_MAX 0.2f /* s */
#define JUMP_SPEED_MAX sqrtf(2.0f * walk->gravity * walk->jump_height)
case WALK_MODAL_JUMP_STOP:
if (walk->gravity_state == WALK_GRAVITY_STATE_JUMP) {
float t;
/* delta time */
t = (float)(PIL_check_seconds_timer() - walk->teleport.initial_time);
/* reduce the veolocity, if JUMP wasn't hold for long enough */
t = min_ff(t, JUMP_TIME_MAX);
walk->speed_jump = JUMP_SPEED_MIN + t * (JUMP_SPEED_MAX - JUMP_SPEED_MIN) / JUMP_TIME_MAX;
/* when jumping, duration is how long it takes before we start going down */
walk->teleport.duration = getVelocityZeroTime(walk->gravity, walk->speed_jump);
/* no more increase of jump speed */
walk->gravity_state = WALK_GRAVITY_STATE_ON;
}
break;
case WALK_MODAL_JUMP:
if ((walk->navigation_mode == WALK_MODE_GRAVITY) &&
(walk->gravity_state == WALK_GRAVITY_STATE_OFF) &&
(walk->teleport.state == WALK_TELEPORT_STATE_OFF))
{
/* no need to check for ground,
* walk->gravity wouldn't be off
* if we were over a hole */
walk->gravity_state = WALK_GRAVITY_STATE_JUMP;
walk->speed_jump = JUMP_SPEED_MAX;
walk->teleport.initial_time = PIL_check_seconds_timer();
copy_v3_v3(walk->teleport.origin, walk->rv3d->viewinv[3]);
/* using previous vec because WASD keys are not called when SPACE is */
copy_v2_v2(walk->teleport.direction, walk->dvec_prev);
/* when jumping, duration is how long it takes before we start going down */
walk->teleport.duration = getVelocityZeroTime(walk->gravity, walk->speed_jump);
}
break;
case WALK_MODAL_TELEPORT:
{
float loc[3], nor[3];
float distance;
bool ret = walk_ray_cast(C, walk->rv3d, walk, loc, nor, &distance);
/* in case we are teleporting middle way from a jump */
walk->speed_jump = 0.0f;
if (ret) {
WalkTeleport *teleport = &walk->teleport;
teleport->state = WALK_TELEPORT_STATE_ON;
teleport->initial_time = PIL_check_seconds_timer();
teleport->duration = U.walk_navigation.teleport_time;
teleport->navigation_mode = walk->navigation_mode;
walk_navigation_mode_set(C, walk, WALK_MODE_FREE);
copy_v3_v3(teleport->origin, walk->rv3d->viewinv[3]);
/* stop the camera from a distance (camera height) */
normalize_v3(nor);
mul_v3_fl(nor, walk->view_height);
add_v3_v3(loc, nor);
sub_v3_v3v3(teleport->direction, loc, teleport->origin);
}
else {
walk->teleport.state = WALK_TELEPORT_STATE_OFF;
}
break;
}
#undef JUMP_SPEED_MAX
#undef JUMP_TIME_MAX
#undef JUMP_SPEED_MIN
case WALK_MODAL_TOGGLE:
if (walk->navigation_mode == WALK_MODE_GRAVITY) {
walk_navigation_mode_set(C, walk, WALK_MODE_FREE);
}
else { /* WALK_MODE_FREE */
walk_navigation_mode_set(C, walk, WALK_MODE_GRAVITY);
}
break;
}
}
}
static void cloth_hair_update_bending_targets(ClothModifierData *clmd)
{
Cloth *cloth = clmd->clothObject;
LinkNode *search = NULL;
float hair_frame[3][3], dir_old[3], dir_new[3];
int prev_mn; /* to find hair chains */
if (!clmd->hairdata)
return;
/* XXX Note: we need to propagate frames from the root up,
* but structural hair springs are stored in reverse order.
* The bending springs however are then inserted in the same
* order as vertices again ...
* This messy situation can be resolved when solver data is
* generated directly from a dedicated hair system.
*/
prev_mn = -1;
for (search = cloth->springs; search; search = search->next) {
ClothSpring *spring = search->link;
ClothHairData *hair_ij, *hair_kl;
bool is_root = spring->kl != prev_mn;
if (spring->type != CLOTH_SPRING_TYPE_BENDING_ANG) {
continue;
}
hair_ij = &clmd->hairdata[spring->ij];
hair_kl = &clmd->hairdata[spring->kl];
if (is_root) {
/* initial hair frame from root orientation */
copy_m3_m3(hair_frame, hair_ij->rot);
/* surface normal is the initial direction,
* parallel transport then keeps it aligned to the hair direction
*/
copy_v3_v3(dir_new, hair_frame[2]);
}
copy_v3_v3(dir_old, dir_new);
sub_v3_v3v3(dir_new, cloth->verts[spring->mn].x, cloth->verts[spring->kl].x);
normalize_v3(dir_new);
#if 0
if (clmd->debug_data && (spring->ij == 0 || spring->ij == 1)) {
float a[3], b[3];
copy_v3_v3(a, cloth->verts[spring->kl].x);
// BKE_sim_debug_data_add_dot(clmd->debug_data, cloth_vert ? cloth_vert->x : key->co, 1, 1, 0, "frames", 8246, p, k);
mul_v3_v3fl(b, hair_frame[0], clmd->sim_parms->avg_spring_len);
BKE_sim_debug_data_add_vector(clmd->debug_data, a, b, 1, 0, 0, "frames", 8247, spring->kl, spring->mn);
mul_v3_v3fl(b, hair_frame[1], clmd->sim_parms->avg_spring_len);
BKE_sim_debug_data_add_vector(clmd->debug_data, a, b, 0, 1, 0, "frames", 8248, spring->kl, spring->mn);
mul_v3_v3fl(b, hair_frame[2], clmd->sim_parms->avg_spring_len);
BKE_sim_debug_data_add_vector(clmd->debug_data, a, b, 0, 0, 1, "frames", 8249, spring->kl, spring->mn);
}
#endif
/* get local targets for kl/mn vertices by putting rest targets into the current frame,
* then multiply with the rest length to get the actual goals
*/
mul_v3_m3v3(spring->target, hair_frame, hair_kl->rest_target);
mul_v3_fl(spring->target, spring->restlen);
/* move frame to next hair segment */
cloth_parallel_transport_hair_frame(hair_frame, dir_old, dir_new);
prev_mn = spring->mn;
}
}
开发者ID:DrangPo,项目名称:blender,代码行数:74,代码来源:cloth.c
示例13: cloth_from_object
static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float UNUSED(framenr), int first)
{
int i = 0;
MVert *mvert = NULL;
ClothVertex *verts = NULL;
float (*shapekey_rest)[3] = NULL;
float tnull[3] = {0, 0, 0};
Cloth *cloth = NULL;
float maxdist = 0;
// If we have a clothObject, free it.
if ( clmd->clothObject != NULL ) {
cloth_free_modifier ( clmd );
if (G.debug_value > 0)
printf("cloth_free_modifier cloth_from_object\n");
}
// Allocate a new cloth object.
clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" );
if ( clmd->clothObject ) {
clmd->clothObject->old_solver_type = 255;
// clmd->clothObject->old_collision_type = 255;
cloth = clmd->clothObject;
clmd->clothObject->edgeset = NULL;
}
else if (!clmd->clothObject) {
modifier_setError(&(clmd->modifier), "Out of memory on allocating clmd->clothObject");
return 0;
}
// mesh input objects need DerivedMesh
if ( !dm )
return 0;
DM_ensure_looptri(dm);
cloth_from_mesh ( clmd, dm );
// create springs
clmd->clothObject->springs = NULL;
clmd->clothObject->numsprings = -1;
if ( clmd->sim_parms->shapekey_rest )
shapekey_rest = dm->getVertDataArray ( dm, CD_CLOTH_ORCO );
mvert = dm->getVertArray (dm);
verts = clmd->clothObject->verts;
// set initial values
for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) {
if (first) {
copy_v3_v3(verts->x, mvert[i].co);
mul_m4_v3(ob->obmat, verts->x);
if ( shapekey_rest ) {
verts->xrest= shapekey_rest[i];
mul_m4_v3(ob->obmat, verts->xrest);
}
else
verts->xrest = verts->x;
}
/* no GUI interface yet */
verts->mass = clmd->sim_parms->mass;
verts->impulse_count = 0;
if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
verts->goal= clmd->sim_parms->defgoal;
else
verts->goal= 0.0f;
verts->flags = 0;
copy_v3_v3 ( verts->xold, verts->x );
copy_v3_v3 ( verts->xconst, verts->x );
copy_v3_v3 ( verts->txold, verts->x );
copy_v3_v3 ( verts->tx, verts->x );
mul_v3_fl(verts->v, 0.0f);
verts->impulse_count = 0;
copy_v3_v3 ( verts->impulse, tnull );
}
// apply / set vertex groups
// has to be happen before springs are build!
cloth_apply_vgroup (clmd, dm);
if ( !cloth_build_springs ( clmd, dm ) ) {
cloth_free_modifier ( clmd );
modifier_setError(&(clmd->modifier), "Cannot build springs");
printf("cloth_free_modifier cloth_build_springs\n");
return 0;
}
for ( i = 0; i < dm->getNumVerts(dm); i++) {
if ((!(cloth->verts[i].flags & CLOTH_VERT_FLAG_PINNED)) && (cloth->verts[i].goal > ALMOST_ZERO)) {
cloth_add_spring (clmd, i, i, 0.0, CLOTH_SPRING_TYPE_GOAL);
}
}
//.........这里部分代码省略.........
开发者ID:DrangPo,项目名称:blender,代码行数:101,代码来源:cloth.c
示例14: initLaplacianMatrix
/**
* This method computes the Laplacian Matrix and Differential Coordinates for all vertex in the mesh.
* The Linear system is LV = d
* Where L is Laplacian Matrix, V as the vertexes in Mesh, d is the differential coordinates
* The Laplacian Matrix is computes as a
* Lij = sum(Wij) (if i == j)
* Lij = Wij (if i != j)
* Wij is weight between vertex Vi and vertex Vj, we use cotangent weight
*
* The Differential Coordinate is computes as a
* di = Vi * sum(Wij) - sum(Wij * Vj)
* Where :
* di is the Differential Coordinate i
* sum (Wij) is the sum of all weights between vertex Vi and its vertexes neighbors (Vj)
* sum (Wij * Vj) is the sum of the product between vertex neighbor Vj and weight Wij for all neighborhood.
*
* This Laplacian Matrix is described in the paper:
* Desbrun M. et.al, Implicit fairing of irregular meshes using diffusion and curvature flow, SIGGRAPH '99, pag 317-324,
* New York, USA
*
* The computation of Laplace Beltrami operator on Hybrid Triangle/Quad Meshes is described in the paper:
* Pinzon A., Romero E., Shape Inflation With an Adapted Laplacian Operator For Hybrid Quad/Triangle Meshes,
* Conference on Graphics Patterns and Images, SIBGRAPI, 2013
*
* The computation of Differential Coordinates is described in the paper:
* Sorkine, O. Laplacian Surface Editing. Proceedings of the EUROGRAPHICS/ACM SIGGRAPH Symposium on Geometry Processing,
* 2004. p. 179-188.
*/
static void initLaplacianMatrix(LaplacianSystem *sys)
{
float v1[3], v2[3], v3[3], v4[3], no[3];
float w2, w3, w4;
int i, j, fi;
bool has_4_vert;
unsigned int idv1, idv2, idv3, idv4;
for (fi = 0; fi < sys->total_faces; fi++) {
const unsigned int *vidf = sys->faces[fi];
idv1 = vidf[0];
idv2 = vidf[1];
idv3 = vidf[2];
idv4 = vidf[3];
has_4_vert = vidf[3] ? 1 : 0;
if (has_4_vert) {
normal_quad_v3(no, sys->co[idv1], sys->co[idv2], sys->co[idv3], sys->co[idv4]);
add_v3_v3(sys->no[idv4], no);
i = 4;
}
else {
normal_tri_v3(no, sys->co[idv1], sys->co[idv2], sys->co[idv3]);
i = 3;
}
add_v3_v3(sys->no[idv1], no);
add_v3_v3(sys->no[idv2], no);
add_v3_v3(sys->no[idv3], no);
for (j = 0; j < i; j++) {
idv1 = vidf[j];
idv2 = vidf[(j + 1) % i];
idv3 = vidf[(j + 2) % i];
idv4 = has_4_vert ? vidf[(j + 3) % i] : 0;
copy_v3_v3(v1, sys->co[idv1]);
copy_v3_v3(v2, sys->co[idv2]);
copy_v3_v3(v3, sys->co[idv3]);
if (has_4_vert) {
copy_v3_v3(v4, sys->co[idv4]);
}
if (has_4_vert) {
w2 = (cotangent_tri_weight_v3(v4, v1, v2) + cotangent_tri_weight_v3(v3, v1, v2)) / 2.0f;
w3 = (cotangent_tri_weight_v3(v2, v3, v1) + cotangent_tri_weight_v3(v4, v1, v3)) / 2.0f;
w4 = (cotangent_tri_weight_v3(v2, v4, v1) + cotangent_tri_weight_v3(v3, v4, v1)) / 2.0f;
sys->delta[idv1][0] -= v4[0] * w4;
sys->delta[idv1][1] -= v4[1] * w4;
sys->delta[idv1][2] -= v4[2] * w4;
nlRightHandSideAdd(0, idv1, -v4[0] * w4);
nlRightHandSideAdd(1, idv1, -v4[1] * w4);
nlRightHandSideAdd(2, idv1, -v4[2] * w4);
nlMatrixAdd(idv1, idv4, -w4);
}
else {
w2 = cotangent_tri_weight_v3(v3, v1, v2);
w3 = cotangent_tri_weight_v3(v2, v3, v1);
w4 = 0.0f;
}
sys->delta[idv1][0] += v1[0] * (w2 + w3 + w4);
sys->delta[idv1][1] += v1[1] * (w2 + w3 + w4);
sys->delta[idv1][2] += v1[2] * (w2 + w3 + w4);
sys->delta[idv1][0] -= v2[0] * w2;
sys->delta[idv1][1] -= v2[1] * w2;
sys->delta[idv1][2] -= v2[2] * w2;
//.........这里部分代码省略.........
请发表评论