Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/curve_deform.c
| Show First 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | static void init_curve_deform(const Object *ob_curve, const Object *ob_target, CurveDeform *cd) | ||||
| invert_m4_m4(imat, ob_target->obmat); | invert_m4_m4(imat, ob_target->obmat); | ||||
| mul_m4_m4m4(cd->objectspace, imat, ob_curve->obmat); | mul_m4_m4m4(cd->objectspace, imat, ob_curve->obmat); | ||||
| invert_m4_m4(cd->curvespace, cd->objectspace); | invert_m4_m4(cd->curvespace, cd->objectspace); | ||||
| copy_m3_m4(cd->objectspace3, cd->objectspace); | copy_m3_m4(cd->objectspace3, cd->objectspace); | ||||
| cd->no_rot_axis = 0; | cd->no_rot_axis = 0; | ||||
| } | } | ||||
| /** | /** | ||||
| * This makes sure we can extend for non-cyclic. | * For each point, rotate & translate to curve. | ||||
| * | |||||
| * \return Success. | |||||
| */ | |||||
| static bool where_on_path_deform(const Object *ob_curve, | |||||
| float ctime, | |||||
| float r_vec[4], | |||||
| float r_dir[3], | |||||
| float r_quat[4], | |||||
| float *r_radius) | |||||
| { | |||||
| BevList *bl; | |||||
| float ctime1; | |||||
| int cycl = 0; | |||||
| /* test for cyclic */ | |||||
| bl = ob_curve->runtime.curve_cache->bev.first; | |||||
| if (!bl->nr) { | |||||
| return false; | |||||
| } | |||||
| if (bl->poly > -1) { | |||||
| cycl = 1; | |||||
| } | |||||
| if (cycl == 0) { | |||||
| ctime1 = CLAMPIS(ctime, 0.0f, 1.0f); | |||||
| } | |||||
| else { | |||||
| ctime1 = ctime; | |||||
| } | |||||
| /* vec needs 4 items */ | |||||
| if (where_on_path(ob_curve, ctime1, r_vec, r_dir, r_quat, r_radius, NULL)) { | |||||
| if (cycl == 0) { | |||||
| Path *path = ob_curve->runtime.curve_cache->path; | |||||
| float dvec[3]; | |||||
| if (ctime < 0.0f) { | |||||
| sub_v3_v3v3(dvec, path->data[1].vec, path->data[0].vec); | |||||
| mul_v3_fl(dvec, ctime * (float)path->len); | |||||
| add_v3_v3(r_vec, dvec); | |||||
| if (r_quat) { | |||||
| copy_qt_qt(r_quat, path->data[0].quat); | |||||
| } | |||||
| if (r_radius) { | |||||
| *r_radius = path->data[0].radius; | |||||
| } | |||||
| } | |||||
| else if (ctime > 1.0f) { | |||||
| sub_v3_v3v3(dvec, path->data[path->len - 1].vec, path->data[path->len - 2].vec); | |||||
| mul_v3_fl(dvec, (ctime - 1.0f) * (float)path->len); | |||||
| add_v3_v3(r_vec, dvec); | |||||
| if (r_quat) { | |||||
| copy_qt_qt(r_quat, path->data[path->len - 1].quat); | |||||
| } | |||||
| if (r_radius) { | |||||
| *r_radius = path->data[path->len - 1].radius; | |||||
| } | |||||
| /* weight - not used but could be added */ | |||||
| } | |||||
| } | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| /** | |||||
| * For each point, rotate & translate to curve use path, since it has constant distances. | |||||
| * | * | ||||
| * \param co: local coord, result local too. | * \param co: local coord, result local too. | ||||
| * \param r_quat: returns quaternion for rotation, | * \param r_quat: returns quaternion for rotation, | ||||
| * using #CurveDeform.no_rot_axis axis is using another define. | * using #CurveDeform.no_rot_axis axis is using another define. | ||||
| */ | */ | ||||
| static bool calc_curve_deform( | static bool calc_curve_deform( | ||||
| const Object *ob_curve, float co[3], const short axis, const CurveDeform *cd, float r_quat[4]) | const Object *ob_curve, float co[3], const short axis, const CurveDeform *cd, float r_quat[4]) | ||||
| { | { | ||||
| Curve *cu = ob_curve->data; | Curve *cu = ob_curve->data; | ||||
| float fac, loc[4], dir[3], new_quat[4], radius; | float fac, loc[4], dir[3], new_quat[4], radius; | ||||
| short index; | short index; | ||||
| const bool is_neg_axis = (axis > 2); | const bool is_neg_axis = (axis > 2); | ||||
| if (ob_curve->runtime.curve_cache == NULL) { | if (ob_curve->runtime.curve_cache == NULL) { | ||||
| /* Happens with a cyclic dependencies. */ | /* Happens with a cyclic dependencies. */ | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (ob_curve->runtime.curve_cache->path == NULL) { | if (ob_curve->runtime.curve_cache->anim_path_accum_length == NULL) { | ||||
| return false; /* happens on append, cyclic dependencies and empty curves */ | return false; /* happens on append, cyclic dependencies and empty curves */ | ||||
| } | } | ||||
| /* options */ | /* options */ | ||||
| if (is_neg_axis) { | if (is_neg_axis) { | ||||
| index = axis - 3; | index = axis - 3; | ||||
| if (cu->flag & CU_STRETCH) { | if (cu->flag & CU_STRETCH) { | ||||
| const float divisor = cd->dmax[index] - cd->dmin[index]; | const float divisor = cd->dmax[index] - cd->dmin[index]; | ||||
| if (LIKELY(divisor > FLT_EPSILON)) { | if (LIKELY(divisor > FLT_EPSILON)) { | ||||
| fac = -(co[index] - cd->dmax[index]) / divisor; | fac = -(co[index] - cd->dmax[index]) / divisor; | ||||
| } | } | ||||
| else { | else { | ||||
| fac = 0.0f; | fac = 0.0f; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (LIKELY(ob_curve->runtime.curve_cache->path->totdist > FLT_EPSILON)) { | CurveCache *cc = ob_curve->runtime.curve_cache; | ||||
| fac = -(co[index] - cd->dmax[index]) / (ob_curve->runtime.curve_cache->path->totdist); | float totdist = BKE_anim_path_get_length(cc); | ||||
| if (LIKELY(totdist > FLT_EPSILON)) { | |||||
| fac = -(co[index] - cd->dmax[index]) / totdist; | |||||
| } | } | ||||
| else { | else { | ||||
| fac = 0.0f; | fac = 0.0f; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| index = axis; | index = axis; | ||||
| if (cu->flag & CU_STRETCH) { | if (cu->flag & CU_STRETCH) { | ||||
| const float divisor = cd->dmax[index] - cd->dmin[index]; | const float divisor = cd->dmax[index] - cd->dmin[index]; | ||||
| if (LIKELY(divisor > FLT_EPSILON)) { | if (LIKELY(divisor > FLT_EPSILON)) { | ||||
| fac = (co[index] - cd->dmin[index]) / divisor; | fac = (co[index] - cd->dmin[index]) / divisor; | ||||
| } | } | ||||
| else { | else { | ||||
| fac = 0.0f; | fac = 0.0f; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (LIKELY(ob_curve->runtime.curve_cache->path->totdist > FLT_EPSILON)) { | CurveCache *cc = ob_curve->runtime.curve_cache; | ||||
| fac = +(co[index] - cd->dmin[index]) / (ob_curve->runtime.curve_cache->path->totdist); | float totdist = BKE_anim_path_get_length(cc); | ||||
| if (LIKELY(totdist > FLT_EPSILON)) { | |||||
| fac = +(co[index] - cd->dmin[index]) / totdist; | |||||
| } | } | ||||
| else { | else { | ||||
| fac = 0.0f; | fac = 0.0f; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (where_on_path_deform(ob_curve, fac, loc, dir, new_quat, &radius)) { /* returns OK */ | if (BKE_where_on_path(ob_curve, fac, loc, dir, new_quat, &radius, NULL)) { /* returns OK */ | ||||
| float quat[4], cent[3]; | float quat[4], cent[3]; | ||||
| if (cd->no_rot_axis) { /* set by caller */ | if (cd->no_rot_axis) { /* set by caller */ | ||||
| /* This is not exactly the same as 2.4x, since the axis is having rotation removed rather | /* This is not exactly the same as 2.4x, since the axis is having rotation removed rather | ||||
| * than changing the axis before calculating the tilt but serves much the same purpose. */ | * than changing the axis before calculating the tilt but serves much the same purpose. */ | ||||
| float dir_flat[3] = {0, 0, 0}, q[4]; | float dir_flat[3] = {0, 0, 0}, q[4]; | ||||
| copy_v3_v3(dir_flat, dir); | copy_v3_v3(dir_flat, dir); | ||||
| ▲ Show 20 Lines • Show All 309 Lines • Show Last 20 Lines | |||||