3222
3241
transform_evaluate /* evaluate */
3244
/* ---------- Shrinkwrap Constraint ----------- */
3246
static int shrinkwrap_get_tars (bConstraint *con, ListBase *list)
3249
bShrinkwrapConstraint *data = con->data;
3250
bConstraintTarget *ct;
3252
SINGLETARGETNS_GET_TARS(con, data->target, ct, list)
3261
static void shrinkwrap_flush_tars (bConstraint *con, ListBase *list, short nocopy)
3264
bShrinkwrapConstraint *data = con->data;
3265
bConstraintTarget *ct= list->first;
3267
SINGLETARGETNS_FLUSH_TARS(con, data->target, ct, list, nocopy)
3272
static void shrinkwrap_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
3274
bShrinkwrapConstraint *scon = (bShrinkwrapConstraint *) con->data;
3276
if( VALID_CONS_TARGET(ct) && (ct->tar->type == OB_MESH) )
3279
float co[3] = {0.0f, 0.0f, 0.0f};
3280
float no[3] = {0.0f, 0.0f, 0.0f};
3283
SpaceTransform transform;
3284
DerivedMesh *target = object_get_derived_final(ct->tar, CD_MASK_BAREMESH);
3286
BVHTreeNearest nearest;
3288
BVHTreeFromMesh treeData;
3289
memset( &treeData, 0, sizeof(treeData) );
3292
nearest.dist = FLT_MAX;
3295
hit.dist = 100000.0f; //TODO should use FLT_MAX.. but normal projection doenst yet supports it
3297
Mat4One(ct->matrix);
3301
space_transform_from_matrixs(&transform, cob->matrix, ct->tar->obmat);
3303
switch(scon->shrinkType)
3305
case MOD_SHRINKWRAP_NEAREST_SURFACE:
3306
case MOD_SHRINKWRAP_NEAREST_VERTEX:
3308
if(scon->shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX)
3309
bvhtree_from_mesh_verts(&treeData, target, 0.0, 2, 6);
3311
bvhtree_from_mesh_faces(&treeData, target, 0.0, 2, 6);
3313
if(treeData.tree == NULL)
3319
space_transform_apply(&transform, co);
3321
BLI_bvhtree_find_nearest(treeData.tree, co, &nearest, treeData.nearest_callback, &treeData);
3323
dist = VecLenf(co, nearest.co);
3324
VecLerpf(co, co, nearest.co, (dist - scon->dist)/dist); /* linear interpolation */
3325
space_transform_invert(&transform, co);
3328
case MOD_SHRINKWRAP_PROJECT:
3329
if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS) no[0] = 1.0f;
3330
if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS) no[1] = 1.0f;
3331
if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS) no[2] = 1.0f;
3333
if(INPR(no,no) < FLT_EPSILON)
3342
bvhtree_from_mesh_faces(&treeData, target, scon->dist, 4, 6);
3343
if(treeData.tree == NULL)
3349
if(normal_projection_project_vertex(0, co, no, &transform, treeData.tree, &hit, treeData.raycast_callback, &treeData) == FALSE)
3354
VECCOPY(co, hit.co);
3358
free_bvhtree_from_mesh(&treeData);
3360
target->release(target);
3364
/* Don't move the point */
3365
co[0] = co[1] = co[2] = 0.0f;
3368
/* co is in local object coordinates, change it to global and update target position */
3369
VecMat4MulVecfl(co, cob->matrix, co);
3370
VECCOPY(ct->matrix[3], co);
3375
static void shrinkwrap_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
3377
bConstraintTarget *ct= targets->first;
3379
/* only evaluate if there is a target */
3380
if (VALID_CONS_TARGET(ct))
3382
VECCOPY(cob->matrix[3], ct->matrix[3]);
3386
static bConstraintTypeInfo CTI_SHRINKWRAP = {
3387
CONSTRAINT_TYPE_SHRINKWRAP, /* type */
3388
sizeof(bShrinkwrapConstraint), /* size */
3389
"Shrinkwrap", /* name */
3390
"bShrinkwrapConstraint", /* struct name */
3391
NULL, /* free data */
3392
NULL, /* relink data */
3393
NULL, /* copy data */
3394
NULL, /* new data */
3395
shrinkwrap_get_tars, /* get constraint targets */
3396
shrinkwrap_flush_tars, /* flush constraint targets */
3397
shrinkwrap_get_tarmat, /* get a target matrix */
3398
shrinkwrap_evaluate /* evaluate */
3225
3403
/* ************************* Constraints Type-Info *************************** */
3226
3404
/* All of the constraints api functions use bConstraintTypeInfo structs to carry out
3227
3405
* and operations that involve constraint specifc code.