diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index a1b138b9a74..6b8b604cb94 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -250,17 +250,13 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, /* note, commented out for follow constraint */ //if(cu->flag & CU_FOLLOW) { - + key_curve_tangent_weights(1.0f-fac, data, KEY_BSPLINE); - - dir[0]= data[0]*p0->vec[0] + data[1]*p1->vec[0] + data[2]*p2->vec[0] + data[3]*p3->vec[0] ; - dir[1]= data[0]*p0->vec[1] + data[1]*p1->vec[1] + data[2]*p2->vec[1] + data[3]*p3->vec[1] ; - dir[2]= data[0]*p0->vec[2] + data[1]*p1->vec[2] + data[2]*p2->vec[2] + data[3]*p3->vec[2] ; - + + interp_v3_v3v3v3v3(dir, p0->vec, p1->vec, p2->vec, p3->vec, data); + /* make compatible with vectoquat */ - dir[0]= -dir[0]; - dir[1]= -dir[1]; - dir[2]= -dir[2]; + negate_v3(dir); //} nu= cu->nurb.first; diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 83e2e0c29d9..75759733cad 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1569,7 +1569,7 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float * /* correct non-cyclic cases by copying direction and rotation * values onto the first & last end-points */ -static void bevel_list_cyclic_fix(BevList *bl) +static void bevel_list_cyclic_fix_3D(BevList *bl) { BevPoint *bevp, *bevp1; @@ -1837,7 +1837,7 @@ static void make_bevel_list_3D_tangent(BevList *bl) bevel_list_calc_bisect(bl); if(bl->poly== -1) /* check its not cyclic */ - bevel_list_cyclic_fix(bl); // XXX - run this now so tangents will be right before doing the flipping + bevel_list_cyclic_fix_3D(bl); // XXX - run this now so tangents will be right before doing the flipping bevel_list_flip_tangents(bl); /* correct the tangents */ @@ -1896,7 +1896,7 @@ static void make_bevel_list_3D(BevList *bl, int smooth_iter, int twist_mode) } if(bl->poly== -1) /* check its not cyclic */ - bevel_list_cyclic_fix(bl); + bevel_list_cyclic_fix_3D(bl); if(smooth_iter) bevel_list_smooth(bl, smooth_iter); @@ -1906,6 +1906,29 @@ static void make_bevel_list_3D(BevList *bl, int smooth_iter, int twist_mode) +/* only for 2 points */ +static void make_bevel_list_segment_3D(BevList *bl) +{ + float q[4]; + + BevPoint *bevp2= (BevPoint *)(bl+1); + BevPoint *bevp1= bevp2+1; + + /* simple quat/dir */ + sub_v3_v3v3(bevp1->dir, bevp1->vec, bevp2->vec); + normalize_v3(bevp1->dir); + + vec_to_quat( bevp1->quat,bevp1->dir, 5, 1); + + axis_angle_to_quat(q, bevp1->dir, bevp1->alfa); + mul_qt_qtqt(bevp1->quat, q, bevp1->quat); + normalize_qt(bevp1->quat); + VECCOPY(bevp2->dir, bevp1->dir); + QUATCOPY(bevp2->quat, bevp1->quat); +} + + + void makeBevelList(Object *ob) { /* @@ -2213,7 +2236,9 @@ void makeBevelList(Object *ob) } /* STEP 4: 2D-COSINES or 3D ORIENTATION */ - if((cu->flag & CU_3D)==0) { /* 3D */ + if((cu->flag & CU_3D)==0) { + /* note: bevp->dir and bevp->quat are not needed for beveling but are + * used when making a path from a 2D curve, therefor they need to be set - Campbell */ bl= cu->bev.first; while(bl) { @@ -2230,6 +2255,9 @@ void makeBevelList(Object *ob) calc_bevel_sin_cos(x1, y1, -x1, -y1, &(bevp1->sina), &(bevp1->cosa)); bevp2->sina= bevp1->sina; bevp2->cosa= bevp1->cosa; + + /* fill in dir & quat */ + make_bevel_list_segment_3D(bl); } else { bevp2= (BevPoint *)(bl+1); @@ -2245,6 +2273,12 @@ void makeBevelList(Object *ob) calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa)); + /* from: make_bevel_list_3D_zup, could call but avoid a second loop. + * no need for tricky tilt calculation as with 3D curves */ + bisect_v3_v3v3v3(bevp1->dir, bevp0->vec, bevp1->vec, bevp2->vec); + vec_to_quat( bevp1->quat,bevp1->dir, 5, 1); + /* done with inline make_bevel_list_3D_zup */ + bevp0= bevp1; bevp1= bevp2; bevp2++; @@ -2261,6 +2295,9 @@ void makeBevelList(Object *ob) bevp1= bevp-1; bevp->sina= bevp1->sina; bevp->cosa= bevp1->cosa; + + /* correct for the dir/quat, see above why its needed */ + bevel_list_cyclic_fix_3D(bl); } } bl= bl->next; @@ -2274,22 +2311,7 @@ void makeBevelList(Object *ob) /* do nothing */ } else if(bl->nr==2) { /* 2 pnt, treat separate */ - float q[4]; - - bevp2= (BevPoint *)(bl+1); - bevp1= bevp2+1; - - /* simple quat/dir */ - sub_v3_v3v3(bevp1->dir, bevp1->vec, bevp2->vec); - normalize_v3(bevp1->dir); - - vec_to_quat( bevp1->quat,bevp1->dir, 5, 1); - - axis_angle_to_quat(q, bevp1->dir, bevp1->alfa); - mul_qt_qtqt(bevp1->quat, q, bevp1->quat); - normalize_qt(bevp1->quat); - VECCOPY(bevp2->dir, bevp1->dir); - QUATCOPY(bevp2->quat, bevp1->quat); + make_bevel_list_segment_3D(bl); } else { make_bevel_list_3D(bl, (int)(resolu*cu->twist_smooth), cu->twist_mode); diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 26602353425..e21c3800acc 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -99,6 +99,7 @@ void interp_v2_v2v2(float r[2], float a[2], float b[2], float t); void interp_v2_v2v2v2(float r[2], float a[2], float b[2], float c[3], float t[3]); void interp_v3_v3v3(float r[3], float a[3], float b[3], float t); void interp_v3_v3v3v3(float p[3], float v1[3], float v2[3], float v3[3], float w[3]); +void interp_v3_v3v3v3v3(float p[3], float v1[3], float v2[3], float v3[3], float v4[3], float w[4]); void mid_v3_v3v3(float r[3], float a[3], float b[3]); diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 8d36c3ac524..502f241c195 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -68,6 +68,15 @@ void interp_v3_v3v3v3(float p[3], float v1[3], float v2[3], float v3[3], float w p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2]; } +/* weight 3 vectors, + * 'w' must be unit length but is not a vector, just 3 weights */ +void interp_v3_v3v3v3v3(float p[3], float v1[3], float v2[3], float v3[3], float v4[3], float w[4]) +{ + p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2] + v4[0]*w[3]; + p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2] + v4[1]*w[3]; + p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2] + v4[2]*w[3]; +} + void mid_v3_v3v3(float *v, float *v1, float *v2) { v[0]= 0.5f*(v1[0] + v2[0]);