diff options
author | Martin Poirier <theeth@yahoo.com> | 2004-09-06 00:21:16 +0400 |
---|---|---|
committer | Martin Poirier <theeth@yahoo.com> | 2004-09-06 00:21:16 +0400 |
commit | ae9347662b4d7baf9ad2d5cbdb89c923d463db60 (patch) | |
tree | e1f9b702a553294951814da78cf013159215b4c8 /source | |
parent | 81e960d1c47ccd8701c218b303013cf52e513a5b (diff) |
Stretch To constraint
Read today's meeting minutes for a description.
Bjornmose: We'll need some example and screenshots for the dev pages of blender3d.org. If you can do some, neat, if not, I'll do them.
Matt, Emilie and Chris: Please review UI addition. Pixel alignement and all that fun stuff has not be overly looked for (though I did some cleaning by adding alignment blocks).
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 196 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 14 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 3 | ||||
-rw-r--r-- | source/blender/include/butspace.h | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_constraint_types.h | 48 | ||||
-rw-r--r-- | source/blender/src/buttons_object.c | 76 | ||||
-rw-r--r-- | source/blender/src/editconstraint.c | 23 |
7 files changed, 316 insertions, 48 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index e590dd1dc24..221847de6bf 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -122,6 +122,12 @@ char constraint_has_target (bConstraint *con) { if (data->tar) return 1; } + case CONSTRAINT_TYPE_STRETCHTO: + { + bStretchToConstraint *data = con->data; + if (data->tar) + return 1; + } break; } // Unknown types or CONSTRAINT_TYPE_NULL or no target @@ -130,54 +136,59 @@ char constraint_has_target (bConstraint *con) { Object *get_constraint_target(bConstraint *con) { - /* - * If the target for this constraint is target, return a pointer - * to the name for this constraints subtarget ... NULL otherwise - */ +/* +* If the target for this constraint is target, return a pointer +* to the name for this constraints subtarget ... NULL otherwise + */ switch (con->type) { - - case CONSTRAINT_TYPE_ACTION: + case CONSTRAINT_TYPE_ACTION: { bActionConstraint *data = con->data; return data->tar; } break; - case CONSTRAINT_TYPE_LOCLIKE: + case CONSTRAINT_TYPE_LOCLIKE: { bLocateLikeConstraint *data = con->data; return data->tar; } break; - case CONSTRAINT_TYPE_ROTLIKE: + case CONSTRAINT_TYPE_ROTLIKE: { bRotateLikeConstraint *data = con->data; return data->tar; } break; - case CONSTRAINT_TYPE_KINEMATIC: + case CONSTRAINT_TYPE_KINEMATIC: { bKinematicConstraint *data = con->data; return data->tar; } break; - case CONSTRAINT_TYPE_TRACKTO: + case CONSTRAINT_TYPE_TRACKTO: { bTrackToConstraint *data = con->data; return data->tar; } break; - case CONSTRAINT_TYPE_LOCKTRACK: + case CONSTRAINT_TYPE_LOCKTRACK: { bLockTrackConstraint *data = con->data; return data->tar; } break; - case CONSTRAINT_TYPE_FOLLOWPATH: + case CONSTRAINT_TYPE_FOLLOWPATH: { bFollowPathConstraint *data = con->data; return data->tar; } break; + case CONSTRAINT_TYPE_STRETCHTO: + { + bStretchToConstraint *data = con->data; + return (data->tar); + } + break; } return NULL; @@ -310,6 +321,18 @@ void *new_constraint_data (short type) result = data; } break; + case CONSTRAINT_TYPE_STRETCHTO: + { + bStretchToConstraint *data; + data = MEM_callocN(sizeof(bStretchToConstraint), "StretchToConstraint"); + + data->volmode = 0; + data->plane = 0; + data->orglength = 0.0; + data->bulge = 1.0; + result = data; + } + break; default: result = NULL; break; @@ -722,6 +745,21 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own Mat4One (mat); } break; + case CONSTRAINT_TYPE_STRETCHTO: + { + bStretchToConstraint *data; + data = (bStretchToConstraint*)con->data; + + if (data->tar){ + where_is_object_time (data->tar, ctime); + constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime); + valid = 1; + } + else + Mat4One (mat); + } + break; + default: Mat4One(mat); break; @@ -796,6 +834,15 @@ void relink_constraints (struct ListBase *list) ID_NEW(data->tar); } break; + case CONSTRAINT_TYPE_STRETCHTO: + { + bStretchToConstraint *data; + data = con->data; + + ID_NEW(data->tar); + } + break; + } } } @@ -907,6 +954,14 @@ void copy_constraints (ListBase *dst, ListBase *src) data = (bFollowPathConstraint*) con->data; } break; + case CONSTRAINT_TYPE_STRETCHTO: + { + bStretchToConstraint *data; + + con->data = MEM_dupallocN (con->data); + data = (bStretchToConstraint*) con->data; + } + break; default: con->data = MEM_dupallocN (con->data); break; @@ -1427,6 +1482,123 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, } } break; + case CONSTRAINT_TYPE_STRETCHTO: + { + bStretchToConstraint *data; + float scale[3],vec[3],xx[3],zz[3],orth[3]; + float totmat[3][3]; + float tmat[4][4]; + float dist; + data=(bStretchToConstraint*)constraint->data; + + if (data->tar){ + + /* store X orientation before destroying obmat */ + xx[0] = ob->obmat[0][0]; + xx[1] = ob->obmat[0][1]; + xx[2] = ob->obmat[0][2]; + Normalise(xx); + + /* store Z orientation before destroying obmat */ + zz[0] = ob->obmat[2][0]; + zz[1] = ob->obmat[2][1]; + zz[2] = ob->obmat[2][2]; + Normalise(zz); + + dist = VecLenf( ob->obmat[3], targetmat[3]); + + if (data->orglength == 0) data->orglength = dist; + if (data->bulge ==0) data->bulge = 1.0; + + scale[1] = dist/data->orglength; + switch (data->volmode){ + /* volume preserving scaling */ + case VOLUME_XZ : + scale[0] = 1.0f - (float)sqrt(data->bulge) + (float)sqrt(data->bulge*(data->orglength/dist)); + scale[2] = scale[0]; + break; + case VOLUME_X: + scale[0] = 1.0f + data->bulge * (data->orglength /dist - 1); + scale[2] = 1.0; + break; + case VOLUME_Z: + scale[0] = 1.0; + scale[2] = 1.0f + data->bulge * (data->orglength /dist - 1); + break; + /* don't care for volume */ + case NO_VOLUME: + scale[0] = 1.0; + scale[2] = 1.0; + break; + default: /* should not happen, but in case*/ + return; + } /* switch (data->volmode) */ + + /* Clear the object's rotation and scale */ + ob->obmat[0][0]=ob->size[0]*scale[0]; + ob->obmat[0][1]=0; + ob->obmat[0][2]=0; + ob->obmat[1][0]=0; + ob->obmat[1][1]=ob->size[1]*scale[1]; + ob->obmat[1][2]=0; + ob->obmat[2][0]=0; + ob->obmat[2][1]=0; + ob->obmat[2][2]=ob->size[2]*scale[2]; + + VecSubf(vec, ob->obmat[3], targetmat[3]); + Normalise(vec); + /* new Y aligns object target connection*/ + totmat[1][0] = -vec[0]; + totmat[1][1] = -vec[1]; + totmat[1][2] = -vec[2]; + switch (data->plane){ + case PLANE_X: + /* build new Z vector */ + /* othogonal to "new Y" "old X! plane */ + Crossf(orth, vec, xx); + Normalise(orth); + + /* new Z*/ + totmat[2][0] = orth[0]; + totmat[2][1] = orth[1]; + totmat[2][2] = orth[2]; + + /* we decided to keep X plane*/ + Crossf(xx,orth, vec); + Normalise(xx); + totmat[0][0] = xx[0]; + totmat[0][1] = xx[1]; + totmat[0][2] = xx[2]; + break; + case PLANE_Z: + /* build new X vector */ + /* othogonal to "new Y" "old Z! plane */ + Crossf(orth, vec, zz); + Normalise(orth); + + /* new X*/ + totmat[0][0] = -orth[0]; + totmat[0][1] = -orth[1]; + totmat[0][2] = -orth[2]; + + /* we decided to keep Z */ + Crossf(zz,orth, vec); + Normalise(zz); + totmat[2][0] = zz[0]; + totmat[2][1] = zz[1]; + totmat[2][2] = zz[2]; + break; + } /* switch (data->plane) */ + + + Mat4CpyMat4(tmat, ob->obmat); + + Mat4MulMat34(ob->obmat, totmat, tmat); + + } + } + break; + default: printf ("Error: Unknown constraint type\n"); break; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 498b84abb2c..1e9b7aa8e99 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1347,6 +1347,14 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist) data->tar = newlibadr(fd, id->lib, data->tar); }; break; + case CONSTRAINT_TYPE_STRETCHTO: + { + bStretchToConstraint *data; + data= ((bStretchToConstraint*)con->data); + data->tar = newlibadr(fd, id->lib, data->tar); + }; + break; + case CONSTRAINT_TYPE_NULL: break; } @@ -4805,6 +4813,12 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb) expand_doit(fd, mainvar, data->tar); break; } + case CONSTRAINT_TYPE_STRETCHTO: + { + bStretchToConstraint *data = (bStretchToConstraint*)curcon->data; + expand_doit(fd, mainvar, data->tar); + break; + } case CONSTRAINT_TYPE_NULL: break; default: diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 6d84c120422..159b1e7a11f 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -603,6 +603,9 @@ static void write_constraints(WriteData *wd, ListBase *conlist) case CONSTRAINT_TYPE_FOLLOWPATH: writestruct(wd, DATA, "bFollowPathConstraint", 1, con->data); break; + case CONSTRAINT_TYPE_STRETCHTO: + writestruct(wd, DATA, "bStretchToConstraint", 1, con->data); + break; default: break; } diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 878f9491052..54af18adfb3 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -520,7 +520,9 @@ enum { B_CONSTRAINT_ADD_ACTION, B_CONSTRAINT_ADD_LOCKTRACK, B_CONSTRAINT_ADD_FOLLOWPATH, - B_CONSTRAINT_ADD_DISTANCELIMIT + B_CONSTRAINT_ADD_DISTANCELIMIT, + B_CONSTRAINT_ADD_STRETCHTO + }; /* *********************** */ diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index b4b380a6a2e..06a7844b785 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -144,6 +144,15 @@ typedef struct bRotationConstraint{ float zmin, zmax; } bRotationConstraint; +/* Stretch to constraint */ +typedef struct bStretchToConstraint{ + Object *tar; + int volmode; + int plane; + float orglength; + float bulge; + char subtarget[32]; +} bStretchToConstraint; /* bConstraint.type */ @@ -185,23 +194,7 @@ typedef struct bRotationConstraint{ #define LOCLIKE_Z 0x00000004 #define LOCSPACE 0x00000008 -/* Tracking flags */ -#define LOCK_X 0x00000000 -#define LOCK_Y 0x00000001 -#define LOCK_Z 0x00000002 - -#define UP_X 0x00000000 -#define UP_Y 0x00000001 -#define UP_Z 0x00000002 - -#define TRACK_X 0x00000000 -#define TRACK_Y 0x00000001 -#define TRACK_Z 0x00000002 -#define TRACK_nX 0x00000003 -#define TRACK_nY 0x00000004 -#define TRACK_nZ 0x00000005 - -/* Tracking flags */ +/* Axis flags */ #define LOCK_X 0x00000000 #define LOCK_Y 0x00000001 #define LOCK_Z 0x00000002 @@ -217,21 +210,14 @@ typedef struct bRotationConstraint{ #define TRACK_nY 0x00000004 #define TRACK_nZ 0x00000005 -/* Tracking flags */ -#define LOCK_X 0x00000000 -#define LOCK_Y 0x00000001 -#define LOCK_Z 0x00000002 +#define VOLUME_XZ 0x00000000 +#define VOLUME_X 0x00000001 +#define VOLUME_Z 0x00000002 +#define NO_VOLUME 0x00000003 -#define UP_X 0x00000000 -#define UP_Y 0x00000001 -#define UP_Z 0x00000002 - -#define TRACK_X 0x00000000 -#define TRACK_Y 0x00000001 -#define TRACK_Z 0x00000002 -#define TRACK_nX 0x00000003 -#define TRACK_nY 0x00000004 -#define TRACK_nZ 0x00000005 +#define PLANE_X 0x00000000 +#define PLANE_Y 0x00000001 +#define PLANE_Z 0x00000002 #endif diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 0708fea0b13..ecb23733523 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -290,6 +290,9 @@ static void get_constraint_typestring (char *str, bConstraint *con) case CONSTRAINT_TYPE_FOLLOWPATH: strcpy (str, "Follow Path"); return; + case CONSTRAINT_TYPE_STRETCHTO: + strcpy (str, "Stretch To"); + return; default: strcpy (str, "Unknown"); return; @@ -315,6 +318,8 @@ static int get_constraint_col(bConstraint *con) return TH_BUT_SETTING; case CONSTRAINT_TYPE_FOLLOWPATH: return TH_BUT_SETTING2; + case CONSTRAINT_TYPE_STRETCHTO: + return TH_BUT_SETTING; default: return TH_REDALERT; } @@ -524,7 +529,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s strcpy (data->subtarget, ""); uiBlockEndAlign(block); - uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Tolerance:", *xco+((width/2)-117), *yco-64, 120, 18, &data->tolerance, 0.0001, 1.0, 0.0, 0.0, "Maximum distance to target after solving"); + uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Tolerance:", *xco+((width/2)-117), *yco-64, 120, 18, &data->tolerance, 0.0001f, 1.0, 0.0, 0.0, "Maximum distance to target after solving"); uiDefButI(block, NUM, B_CONSTRAINT_REDRAW, "Iterations:", *xco+((width/2)+3), *yco-64, 120, 18, &data->iterations, 1, 10000, 0.0, 0.0, "Maximum number of solving iterations"); } @@ -656,6 +661,54 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s uiBlockEndAlign(block); } break; + case CONSTRAINT_TYPE_STRETCHTO: + { + bStretchToConstraint *data = con->data; + bArmature *arm; + height = 105; + BIF_ThemeColor(curCol); + + glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18); + + uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); + + + /* Draw target parameters */ + uiBlockBeginAlign(block); + uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); + + arm = get_armature(data->tar); + if (arm){ + but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone"); + } + else + strcpy (data->subtarget, ""); + uiBlockEndAlign(block); + + + uiBlockBeginAlign(block); + uiDefButF(block,BUTM,B_CONSTRAINT_REDRAW,"R",*xco, *yco-60,20,18,&(data->orglength),0.0,0,0,0,"Recalculate RLenght"); + uiDefButF(block,NUM,B_CONSTRAINT_REDRAW,"Rest Length:",*xco+20, *yco-60,237,18,&(data->orglength),0.0,100,0.5,0.5,"Lenght at Rest Position"); + uiBlockEndAlign(block); + + uiDefButF(block,NUM,B_CONSTRAINT_REDRAW,"Volume Variation:",*xco+20, *yco-82,237,18,&(data->bulge),0.0,100,0.5,0.5,"Factor between volume variation and stretching"); + + uiBlockBeginAlign(block); + uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Vol:",*xco+12, *yco-104,30,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); + uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"XZ", *xco+42, *yco-104,30,18, &data->volmode, 12.0, 0.0, 0, 0, "Keep Volume: Scaling X & Z"); + uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"X", *xco+72, *yco-104,20,18, &data->volmode, 12.0, 1.0, 0, 0, "Keep Volume: Scaling X"); + uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Z", *xco+92, *yco-104,20,18, &data->volmode, 12.0, 2.0, 0, 0, "Keep Volume: Scaling Z"); + uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"NONE", *xco+112, *yco-104,50,18, &data->volmode, 12.0, 3.0, 0, 0, "Ignore Volume"); + uiBlockEndAlign(block); + + + uiBlockBeginAlign(block); + uiDefBut(block, LABEL, B_CONSTRAINT_TEST,"Plane:",*xco+170, *yco-104,40,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); + uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"X", *xco+210, *yco-104,20,18, &data->plane, 12.0, 0.0, 0, 0, "Keep X axis"); + uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Z", *xco+230, *yco-104,20,18, &data->plane, 12.0, 2.0, 0, 0, "Keep Z axis"); + uiBlockEndAlign(block); + } + break; case CONSTRAINT_TYPE_NULL: { height = 17; @@ -711,6 +764,10 @@ static uiBlock *add_constraintmenu(void *arg_unused) uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCKTRACK,"Locked Track", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); uiDefBut(block, BUTM, B_CONSTRAINT_ADD_FOLLOWPATH,"Follow Path", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); + + uiDefBut(block, BUTM, B_CONSTRAINT_ADD_STRETCHTO,"Stretch To", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); + if (type==TARGET_BONE) { uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); @@ -719,9 +776,8 @@ static uiBlock *add_constraintmenu(void *arg_unused) uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ACTION,"Action", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); } - uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); - + uiDefBut(block, BUTM, B_CONSTRAINT_ADD_NULL,"Null", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); uiTextBoundsBlock(block, 50); @@ -851,6 +907,18 @@ void do_constraintbuts(unsigned short event) allqueue (REDRAWBUTSOBJECT, 0); } break; + case B_CONSTRAINT_ADD_STRETCHTO: + { + bConstraint *con; + con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO); + add_constraint_to_client(con); + + test_scene_constraints(); + allqueue(REDRAWVIEW3D,0); + allqueue(REDRAWBUTSOBJECT,0); + } + break; + case B_CONSTRAINT_DEL: test_scene_constraints(); allqueue (REDRAWVIEW3D, 0); @@ -1400,7 +1468,7 @@ void object_panel_effects(Object *ob) uiBlockBeginAlign(block); uiDefButS(block, ROW, B_CALCEFFECT, "RGB", 911,31,45,20, &paf->texmap, 14.0, 1.0, 0, 0, "Use RGB values as a factor for particle speed"); uiDefButS(block, ROW, B_CALCEFFECT, "Grad", 958,31,44,20, &paf->texmap, 14.0, 2.0, 0, 0, "Use texture gradient as a factor for particle speed"); - uiDefButF(block, NUM, B_CALCEFFECT, "Nabla:", 911,9,91,20, &paf->nabla, 0.0001, 1.0, 1, 0, "Specify the dimension of the area for gradient calculation"); + uiDefButF(block, NUM, B_CALCEFFECT, "Nabla:", 911,9,91,20, &paf->nabla, 0.0001f, 1.0, 1, 0, "Specify the dimension of the area for gradient calculation"); } } diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c index c06a11a6b7d..6123da0062b 100644 --- a/source/blender/src/editconstraint.c +++ b/source/blender/src/editconstraint.c @@ -578,6 +578,23 @@ static short detect_constraint_loop (Object *owner, const char* substring, int d } } break; + case CONSTRAINT_TYPE_STRETCHTO: + { + bStretchToConstraint *data = curcon->data; + + if (!exist_object(data->tar)){ + data->tar = NULL; + break; + } + + if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_LOCKTRACK)){ + curcon->flag |= CONSTRAINT_DISABLE; + result = 1; + break; + // return 1; + } + } + break; case CONSTRAINT_TYPE_FOLLOWPATH: { bFollowPathConstraint *data = curcon->data; @@ -827,6 +844,12 @@ char *get_con_subtarget_name(bConstraint *constraint, Object *target) if (data->tar==target) return data->subtarget; } break; + case CONSTRAINT_TYPE_STRETCHTO: + { + bStretchToConstraint *data = constraint->data; + if (data->tar==target) return data->subtarget; + } + break; case CONSTRAINT_TYPE_FOLLOWPATH: /* wonder if this is relevent, since this constraint * cannot have a subtarget - theeth |