From 1dba65e296276ed78222f19a127c90773a1f0416 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 7 Sep 2005 00:11:39 +0000 Subject: Roland Hess' Floor Constraint patch: https://projects.blender.org/tracker/?func=detail&aid=2993&group_id=9&atid=127 Minor modifications to simplify the code in evaluate_constraint. The "Stick" feature will need more work as it gives bad results when skipping frames, jumping around on the timeline and when going backward in time. Suggestion: Would be nice if it could use the local space too, not just global space planes. --- source/blender/blenkernel/intern/constraint.c | 110 ++++++++++++++++++++++++- source/blender/blenloader/intern/readfile.c | 13 +++ source/blender/blenloader/intern/writefile.c | 3 + source/blender/include/butspace.h | 1 + source/blender/makesdna/DNA_constraint_types.h | 11 +++ source/blender/src/buttons_object.c | 54 ++++++++++++ source/blender/src/editconstraint.c | 24 ++++++ 7 files changed, 215 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 5940c16eccb..f4d9cd67dd9 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -137,6 +137,14 @@ void relink_constraints (struct ListBase *list) bTrackToConstraint *data; data = con->data; + ID_NEW(data->tar); + } + break; + case CONSTRAINT_TYPE_MINMAX: + { + bMinMaxConstraint *data; + data = con->data; + ID_NEW(data->tar); } break; @@ -272,6 +280,13 @@ char constraint_has_target (bConstraint *con) return 1; } break; + case CONSTRAINT_TYPE_MINMAX: + { + bMinMaxConstraint *data = con->data; + if (data->tar) + return 1; + } + break; case CONSTRAINT_TYPE_ACTION: { bActionConstraint *data = con->data; @@ -339,6 +354,13 @@ Object *get_constraint_target(bConstraint *con, char **subtarget) return data->tar; } break; + case CONSTRAINT_TYPE_MINMAX: + { + bMinMaxConstraint *data = con->data; + *subtarget= data->subtarget; + return data->tar; + } + break; case CONSTRAINT_TYPE_LOCKTRACK: { bLockTrackConstraint *data = con->data; @@ -508,6 +530,22 @@ void *new_constraint_data (short type) result = data; + } + break; + case CONSTRAINT_TYPE_MINMAX: + { + bMinMaxConstraint *data; + data = MEM_callocN(sizeof(bMinMaxConstraint), "minmaxConstraint"); + + + data->minmaxflag = TRACK_Z; + data->offset = 0.0f; + data->cache[0] = data->cache[1] = data->cache[2] = 0.0f; + data->sticky = 0; + data->stuck = 0; + + result = data; + } break; case CONSTRAINT_TYPE_ROTLIKE: @@ -801,6 +839,18 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own Mat4One (mat); } break; + case CONSTRAINT_TYPE_MINMAX: + { + bMinMaxConstraint *data = (bMinMaxConstraint*)con->data; + + if (data->tar){ + constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime); + valid=1; + } + else + Mat4One (mat); + } + break; case CONSTRAINT_TYPE_ROTLIKE: { bRotateLikeConstraint *data; @@ -993,6 +1043,64 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, { } break; + case CONSTRAINT_TYPE_MINMAX: + { + float val1, val2; + int index; + bMinMaxConstraint *data; + + data = constraint->data; + + switch (data->minmaxflag){ + case TRACK_Z: + val1 = targetmat[3][2]; + val2 = ob->obmat[3][2]-data->offset; + index = 2; + break; + case TRACK_Y: + val1 = targetmat[3][1]; + val2 = ob->obmat[3][1]-data->offset; + index = 1; + break; + case TRACK_X: + val1 = targetmat[3][0]; + val2 = ob->obmat[3][0]-data->offset; + index = 0; + break; + case TRACK_nZ: + val2 = targetmat[3][2]; + val1 = ob->obmat[3][2]-data->offset; + index = 2; + break; + case TRACK_nY: + val2 = targetmat[3][1]; + val1 = ob->obmat[3][1]-data->offset; + index = 1; + break; + case TRACK_nX: + val2 = targetmat[3][0]; + val1 = ob->obmat[3][0]-data->offset; + index = 0; + break; + default: + return; + } + + if (val1 > val2) { + ob->obmat[3][index] = targetmat[3][index] + data->offset; + if (data->sticky==1) { + if (data->stuck==1) { + VECCOPY(ob->obmat[3], data->cache); + } else { + VECCOPY(data->cache, ob->obmat[3]); + data->stuck = 1; + } + } + } else { + data->stuck=0; + } + } + break; case CONSTRAINT_TYPE_TRACKTO: { bTrackToConstraint *data; @@ -1502,4 +1610,4 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, printf ("Error: Unknown constraint type\n"); break; } -} +} \ No newline at end of file diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 4d696fe9753..06e0f38ec0f 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1320,6 +1320,13 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist) data->tar = newlibadr(fd, id->lib, data->tar); } break; + case CONSTRAINT_TYPE_MINMAX: + { + bMinMaxConstraint *data; + data = ((bMinMaxConstraint*)con->data); + data->tar = newlibadr(fd, id->lib, data->tar); + } + break; case CONSTRAINT_TYPE_LOCKTRACK: { bLockTrackConstraint *data; @@ -5278,6 +5285,12 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb) expand_doit(fd, mainvar, data->tar); break; } + case CONSTRAINT_TYPE_MINMAX: + { + bMinMaxConstraint *data = (bMinMaxConstraint*)curcon->data; + expand_doit(fd, mainvar, data->tar); + break; + } case CONSTRAINT_TYPE_LOCKTRACK: { bLockTrackConstraint *data = (bLockTrackConstraint*)curcon->data; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index ade29114907..57c5c90555e 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -612,6 +612,9 @@ static void write_constraints(WriteData *wd, ListBase *conlist) case CONSTRAINT_TYPE_STRETCHTO: writestruct(wd, DATA, "bStretchToConstraint", 1, con->data); break; + case CONSTRAINT_TYPE_MINMAX: + writestruct(wd, DATA, "bMinMaxConstraint", 1, con->data); + break; default: break; } diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 78254a10f81..eff682e4116 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -552,6 +552,7 @@ enum { B_CONSTRAINT_ADD_NULL, B_CONSTRAINT_ADD_KINEMATIC, B_CONSTRAINT_ADD_TRACKTO, + B_CONSTRAINT_ADD_MINMAX, B_CONSTRAINT_ADD_ROTLIKE, B_CONSTRAINT_ADD_LOCLIKE, B_CONSTRAINT_ADD_ACTION, diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 70e1bc3f3bc..3b30613015a 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -93,6 +93,16 @@ typedef struct bLocateLikeConstraint{ char subtarget[32]; } bLocateLikeConstraint; +typedef struct bMinMaxConstraint{ + Object *tar; + int minmaxflag; + float offset; + short sticky; + short stuck; + float cache[3]; + char subtarget[32]; +} bMinMaxConstraint; + typedef struct bActionConstraint{ Object *tar; short type; @@ -168,6 +178,7 @@ typedef struct bStretchToConstraint{ #define CONSTRAINT_TYPE_LOCKTRACK 13 /* New Tracking constraint that locks an axis in place - theeth */ #define CONSTRAINT_TYPE_DISTANCELIMIT 14 #define CONSTRAINT_TYPE_STRETCHTO 15 /* claiming this to be mine :) is in tuhopuu bjornmose */ +#define CONSTRAINT_TYPE_MINMAX 16 /* floor constraint */ /* bConstraint.flag */ diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index fb13564eb4a..63916adc431 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -313,6 +313,9 @@ static void get_constraint_typestring (char *str, bConstraint *con) case CONSTRAINT_TYPE_TRACKTO: strcpy (str, "Track To"); return; + case CONSTRAINT_TYPE_MINMAX: + strcpy (str, "Floor"); + return; case CONSTRAINT_TYPE_KINEMATIC: strcpy (str, "IK Solver"); return; @@ -353,6 +356,8 @@ static int get_constraint_col(bConstraint *con) return TH_BUT_SETTING1; case CONSTRAINT_TYPE_LOCLIKE: return TH_BUT_POPUP; + case CONSTRAINT_TYPE_MINMAX: + return TH_BUT_POPUP; case CONSTRAINT_TYPE_ACTION: return TH_BUT_ACTION; case CONSTRAINT_TYPE_LOCKTRACK: @@ -656,6 +661,44 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s uiBlockEndAlign(block); } break; + case CONSTRAINT_TYPE_MINMAX: + { + bMinMaxConstraint *data = con->data; + bArmature *arm; + + height = 66; + uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); + + uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); + + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Offset:", *xco, *yco-44, 100, 18, &data->offset, -100, 100, 100.0, 0.0, "Offset from the position of the object center"); + + /* 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); + + but=uiDefButBitI(block, TOG, 1, B_CONSTRAINT_TEST, "Sticky", *xco, *yco-24, 54, 18, &data->sticky, 0, 24, 0, 0, "Immobilize object while constrained"); + + uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Max/Min:", *xco-8, *yco-64, 54, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); + + uiBlockBeginAlign(block); + uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X", *xco+51, *yco-64,17,18, &data->minmaxflag, 12.0, 0.0, 0, 0, "Will not pass below X of target"); + uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y", *xco+67, *yco-64,17,18, &data->minmaxflag, 12.0, 1.0, 0, 0, "Will not pass below Y of target"); + uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z", *xco+85, *yco-64,17,18, &data->minmaxflag, 12.0, 2.0, 0, 0, "Will not pass below Z of target"); + uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-X", *xco+102, *yco-64,24,18, &data->minmaxflag, 12.0, 3.0, 0, 0, "Will not pass above X of target"); + uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Y", *xco+126, *yco-64,24,18, &data->minmaxflag, 12.0, 4.0, 0, 0, "Will not pass above Y of target"); + uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Z", *xco+150, *yco-64,24,18, &data->minmaxflag, 12.0, 5.0, 0, 0, "Will not pass above Z of target"); + uiBlockEndAlign(block); + } + break; case CONSTRAINT_TYPE_LOCKTRACK: { bLockTrackConstraint *data = con->data; @@ -831,6 +874,7 @@ static uiBlock *add_constraintmenu(void *arg_unused) uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefBut(block, BUTM, B_CONSTRAINT_ADD_TRACKTO,"Track To", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, BUTM, B_CONSTRAINT_ADD_MINMAX,"Floor", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); 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, ""); @@ -898,6 +942,16 @@ void do_constraintbuts(unsigned short event) BIF_undo_push("Add constraint"); } break; + case B_CONSTRAINT_ADD_MINMAX: + { + bConstraint *con; + + con = add_new_constraint(CONSTRAINT_TYPE_MINMAX); + add_constraint_to_active(ob, con); + + BIF_undo_push("Add constraint"); + } + break; case B_CONSTRAINT_ADD_ROTLIKE: { bConstraint *con; diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c index e6dbd21c990..5b48986c8fb 100644 --- a/source/blender/src/editconstraint.c +++ b/source/blender/src/editconstraint.c @@ -260,6 +260,12 @@ char *get_con_subtarget_name(bConstraint *con, Object *target) if (data->tar==target) return data->subtarget; } break; + case CONSTRAINT_TYPE_MINMAX: + { + bMinMaxConstraint *data = con->data; + if (data->tar==target) return data->subtarget; + } + break; case CONSTRAINT_TYPE_LOCKTRACK: { bLockTrackConstraint *data = con->data; @@ -368,6 +374,24 @@ static void test_constraints (Object *owner, const char* substring) break; } + if ( (data->tar == owner) && + (!get_named_bone(get_armature(owner), + data->subtarget))) { + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + } + break; + case CONSTRAINT_TYPE_MINMAX: + { + bMinMaxConstraint *data = curcon->data; + + if (!exist_object(data->tar)){ + data->tar = NULL; + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + if ( (data->tar == owner) && (!get_named_bone(get_armature(owner), data->subtarget))) { -- cgit v1.2.3