looks like 2 merges are needed to skip a commit.
This commit is contained in:
Campbell Barton
2009-09-07 08:31:03 +00:00
4 changed files with 156 additions and 36 deletions

View File

@@ -1550,7 +1550,7 @@ void makeBevelList(Object *ob)
BPoint *bp;
BevList *bl, *blnew, *blnext;
BevPoint *bevp, *bevp2, *bevp1 = NULL, *bevp0;
float min, inp, x1, x2, y1, y2, vec[3];
float min, inp, x1, x2, y1, y2, vec[3], vec_prev[3], q[4], quat[4], quat_prev[4], cross[3];
float *coord_array, *tilt_array=NULL, *radius_array=NULL, *coord_fp, *tilt_fp=NULL, *radius_fp=NULL;
float *v1, *v2;
struct bevelsort *sortdata, *sd, *sd1;
@@ -1909,7 +1909,10 @@ void makeBevelList(Object *ob)
bl= cu->bev.first;
while(bl) {
if(bl->nr==2) { /* 2 pnt, treat separate */
if(bl->nr < 2) {
/* do nothing */
}
else if(bl->nr==2) { /* 2 pnt, treat separate */
bevp2= (BevPoint *)(bl+1);
bevp1= bevp2+1;
@@ -1923,56 +1926,106 @@ void makeBevelList(Object *ob)
if(cu->flag & CU_3D) { /* 3D */
float quat[4], q[4];
vec[0]= bevp1->x - bevp2->x;
vec[1]= bevp1->y - bevp2->y;
vec[2]= bevp1->z - bevp2->z;
VecSubf(vec, &bevp1->x, &bevp2->x);
vectoquat(vec, 5, 1, quat);
Normalize(vec);
q[0]= (float)cos(0.5*bevp1->alfa);
x1= (float)sin(0.5*bevp1->alfa);
q[1]= x1*vec[0];
q[2]= x1*vec[1];
q[3]= x1*vec[2];
AxisAngleToQuat(q, vec, bevp1->alfa);
QuatMul(quat, q, quat);
QuatToMat3(quat, bevp1->mat);
Mat3CpyMat3(bevp2->mat, bevp1->mat);
}
}
else if(bl->nr>2) {
} /* this has to be >2 points */
else if(cu->flag & CU_NO_TWIST && cu->flag & CU_3D && bl->poly != -1) {
/* Special case, cyclic curve with no twisy. tricky... */
float quat[4], q[4], cross[3];
/* correcting a cyclic curve is more complicated, need to be corrected from both ends */
float *quat_tmp1, *quat_tmp2; /* store a quat in the matrix temporarily */
int iter_dir;
BevPoint *bevp_start= (BevPoint *)(bl+1);
/* loop over the points twice, once up, once back, accumulate the quat rotations
* in both directions, then blend them in the 3rd loop and apply the tilt */
for(iter_dir = 0; iter_dir < 2; iter_dir++) {
bevp2= (BevPoint *)(bl+1);
bevp1= bevp2+(bl->nr-1);
bevp0= bevp1-1;
nr= bl->nr;
while(nr--) {
/* Normalizes */
Vec3ToTangent(vec, &bevp0->x, &bevp1->x, &bevp2->x);
if(bl->nr==nr+1) { /* first time */
vectoquat(vec, 5, 1, quat);
}
else {
float angle = NormalizedVecAngle2(vec_prev, vec);
if(angle > 0.0f) { /* otherwise we can keep as is */
Crossf(cross, vec_prev, vec);
AxisAngleToQuat(q, cross, angle);
QuatMul(quat, q, quat_prev);
}
else {
QUATCOPY(quat, quat_prev);
}
}
QUATCOPY(quat_prev, quat); /* quat_prev can't have the tilt applied */
VECCOPY(vec_prev, vec);
if(iter_dir==0) { /* up, first time */
quat_tmp1= (float *)bevp1->mat;
bevp0= bevp1;
bevp1= bevp2;
bevp2++;
}
else { /* down second time */
quat_tmp1= ((float *)bevp1->mat)+4;
bevp2= bevp1;
bevp1= bevp0;
bevp0--;
/* wrap around */
if (bevp0 < bevp_start)
bevp0= bevp_start+(bl->nr-1);
}
QUATCOPY(quat_tmp1, quat);
}
}
/* Now interpolate the 2 quats and apply tilt */
bevp2= (BevPoint *)(bl+1);
bevp1= bevp2+(bl->nr-1);
bevp0= bevp1-1;
nr= bl->nr;
while(nr--) {
if(cu->flag & CU_3D) { /* 3D */
float quat[4], q[4];
vec[0]= bevp2->x - bevp0->x;
vec[1]= bevp2->y - bevp0->y;
vec[2]= bevp2->z - bevp0->z;
Normalize(vec);
vectoquat(vec, 5, 1, quat);
q[0]= (float)cos(0.5*bevp1->alfa);
x1= (float)sin(0.5*bevp1->alfa);
q[1]= x1*vec[0];
q[2]= x1*vec[1];
q[3]= x1*vec[2];
QuatMul(quat, q, quat);
QuatToMat3(quat, bevp1->mat);
}
Vec3ToTangent(vec, &bevp0->x, &bevp1->x, &bevp2->x);
quat_tmp1= (float *)bevp1->mat;
quat_tmp2= quat_tmp1+4;
/* blend the 2 rotations gathered from both directions */
QuatInterpol(quat, quat_tmp1, quat_tmp2, 1.0 - (((float)nr)/bl->nr));
AxisAngleToQuat(q, vec, bevp1->alfa);
QuatMul(quat, q, quat);
QuatToMat3(quat, bevp1->mat);
/* generic */
x1= bevp1->x- bevp0->x;
x2= bevp1->x- bevp2->x;
y1= bevp1->y- bevp0->y;
@@ -1980,11 +2033,62 @@ void makeBevelList(Object *ob)
calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa));
bevp0= bevp1;
bevp1= bevp2;
bevp2++;
}
}
else {
/* Any curve with 3 or more points */
bevp2= (BevPoint *)(bl+1);
bevp1= bevp2+(bl->nr-1);
bevp0= bevp1-1;
nr= bl->nr;
while(nr--) {
if(cu->flag & CU_3D) { /* 3D */
/* Normalizes */
Vec3ToTangent(vec, &bevp0->x, &bevp1->x, &bevp2->x);
if(bl->nr==nr+1 || !(cu->flag & CU_NO_TWIST)) { /* first time */
vectoquat(vec, 5, 1, quat);
}
else {
float angle = NormalizedVecAngle2(vec_prev, vec);
if(angle > 0.0f) { /* otherwise we can keep as is */
Crossf(cross, vec_prev, vec);
AxisAngleToQuat(q, cross, angle);
QuatMul(quat, q, quat_prev);
}
else {
QUATCOPY(quat, quat_prev);
}
}
QUATCOPY(quat_prev, quat); /* quat_prev can't have the tilt applied */
VECCOPY(vec_prev, vec);
AxisAngleToQuat(q, vec, bevp1->alfa);
QuatMul(quat, q, quat);
QuatToMat3(quat, bevp1->mat);
}
x1= bevp1->x- bevp0->x;
x2= bevp1->x- bevp2->x;
y1= bevp1->y- bevp0->y;
y2= bevp1->y- bevp2->y;
calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa));
bevp0= bevp1;
bevp1= bevp2;
bevp2++;
}
/* correct non-cyclic cases */
if(bl->poly== -1) {
if(bl->nr>2) {

View File

@@ -380,6 +380,7 @@ void AxisAngleToQuat(float *q, float *axis, float angle);
void RotationBetweenVectorsToQuat(float *q, float v1[3], float v2[3]);
void vectoquat(float *vec, short axis, short upflag, float *q);
void Vec3ToTangent(float *v, float *v1, float *v2, float *v3);
float VecAngle2(float *v1, float *v2);
float VecAngle3(float *v1, float *v2, float *v3);
float NormalizedVecAngle2(float *v1, float *v2);

View File

@@ -3374,6 +3374,19 @@ void VecRotToQuat(float *vec, float phi, float *quat)
}
}
/* get a direction from 3 vectors that wont depend
* on the distance between the points */
void Vec3ToTangent(float *v, float *v1, float *v2, float *v3)
{
float d_12[3], d_23[3];
VecSubf(d_12, v2, v1);
VecSubf(d_23, v3, v2);
Normalize(d_12);
Normalize(d_23);
VecAddf(v, d_12, d_23);
Normalize(v);
}
/* Return the angle in degrees between vecs 1-2 and 2-3 in degrees
If v1 is a shoulder, v2 is the elbow and v3 is the hand,
this would return the angle at the elbow */

View File

@@ -225,6 +225,8 @@ typedef struct Curve {
#define CU_RETOPO 1024
#define CU_DS_EXPAND 2048
#define CU_NO_TWIST 4096
/* spacemode */
#define CU_LEFT 0
#define CU_MIDDLE 1