BLI_INLINE void multires_reshape_propagate_interpolate_coord( float delta[3], const MultiresPropagateCornerData corners[4], const float weights[4]) { interp_v3_v3v3v3v3(delta, corners[0].coord_delta, corners[1].coord_delta, corners[2].coord_delta, corners[3].coord_delta, weights); }
/* calculate the deformation implied by the curve path at a given parametric position, * and returns whether this operation succeeded. * * note: ctime is normalized range <0-1> * * returns OK: 1/0 */ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float quat[4], float *radius, float *weight) { Curve *cu; Nurb *nu; BevList *bl; Path *path; PathPoint *pp, *p0, *p1, *p2, *p3; float fac; float data[4]; int cycl=0, s0, s1, s2, s3; if (ob==NULL || ob->type != OB_CURVE) return 0; cu= ob->data; if (cu->path==NULL || cu->path->data==NULL) { printf("no path!\n"); return 0; } path= cu->path; pp= path->data; /* test for cyclic */ bl= cu->bev.first; if (!bl) return 0; if (!bl->nr) return 0; if (bl->poly> -1) cycl= 1; ctime *= (path->len-1); s1= (int)floor(ctime); fac= (float)(s1+1)-ctime; /* path->len is corected for cyclic */ s0= interval_test(0, path->len-1-cycl, s1-1, cycl); s1= interval_test(0, path->len-1-cycl, s1, cycl); s2= interval_test(0, path->len-1-cycl, s1+1, cycl); s3= interval_test(0, path->len-1-cycl, s1+2, cycl); p0= pp + s0; p1= pp + s1; p2= pp + s2; p3= pp + s3; /* note, commented out for follow constraint */ //if (cu->flag & CU_FOLLOW) { key_curve_tangent_weights(1.0f-fac, data, KEY_BSPLINE); interp_v3_v3v3v3v3(dir, p0->vec, p1->vec, p2->vec, p3->vec, data); /* make compatible with vectoquat */ negate_v3(dir); //} nu= cu->nurb.first; /* make sure that first and last frame are included in the vectors here */ if (nu->type == CU_POLY) key_curve_position_weights(1.0f-fac, data, KEY_LINEAR); else if (nu->type == CU_BEZIER) key_curve_position_weights(1.0f-fac, data, KEY_LINEAR); else if (s0==s1 || p2==p3) key_curve_position_weights(1.0f-fac, data, KEY_CARDINAL); else key_curve_position_weights(1.0f-fac, data, KEY_BSPLINE); vec[0]= data[0]*p0->vec[0] + data[1]*p1->vec[0] + data[2]*p2->vec[0] + data[3]*p3->vec[0] ; /* X */ vec[1]= data[0]*p0->vec[1] + data[1]*p1->vec[1] + data[2]*p2->vec[1] + data[3]*p3->vec[1] ; /* Y */ vec[2]= data[0]*p0->vec[2] + data[1]*p1->vec[2] + data[2]*p2->vec[2] + data[3]*p3->vec[2] ; /* Z */ vec[3]= data[0]*p0->vec[3] + data[1]*p1->vec[3] + data[2]*p2->vec[3] + data[3]*p3->vec[3] ; /* Tilt, should not be needed since we have quat still used */ if (quat) { float totfac, q1[4], q2[4]; totfac= data[0]+data[3]; if (totfac>FLT_EPSILON) interp_qt_qtqt(q1, p0->quat, p3->quat, data[3] / totfac); else copy_qt_qt(q1, p1->quat); totfac= data[1]+data[2]; if (totfac>FLT_EPSILON) interp_qt_qtqt(q2, p1->quat, p2->quat, data[2] / totfac); else copy_qt_qt(q2, p3->quat); totfac = data[0]+data[1]+data[2]+data[3]; if (totfac>FLT_EPSILON) interp_qt_qtqt(quat, q1, q2, (data[1]+data[2]) / totfac); else copy_qt_qt(quat, q2); } if (radius) *radius= data[0]*p0->radius + data[1]*p1->radius + data[2]*p2->radius + data[3]*p3->radius; if (weight) *weight= data[0]*p0->weight + data[1]*p1->weight + data[2]*p2->weight + data[3]*p3->weight; return 1; }