From 216f9af08e88398b7e2f805d241734ec80879180 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 6 Feb 2011 17:36:42 +0000 Subject: [PATCH] Two in one: - Bugfix #25937 Child-of constraint now behaves like regular parent-child relationship when all options are set. This prevents the errors that can happen when decomposing non-uniform matrices. - Todo item The area corner hotspots for splitting/merging were far too narrow. Now it uses a circular distance to detect whether the hotspot is active. Also cleaned up drawing code for it. --- source/blender/blenkernel/intern/constraint.c | 109 ++++++++++-------- source/blender/editors/screen/area.c | 32 +++-- source/blender/editors/screen/screen_intern.h | 2 + source/blender/editors/screen/screen_ops.c | 5 +- .../blender/makesdna/DNA_constraint_types.h | 3 +- 5 files changed, 84 insertions(+), 67 deletions(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index c61f3ba3683..e653a6198ca 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -834,54 +834,71 @@ static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta /* only evaluate if there is a target */ if (VALID_CONS_TARGET(ct)) { - float parmat[4][4], invmat[4][4], tempmat[4][4]; - float loc[3], eul[3], size[3]; - float loco[3], eulo[3], sizo[3]; + float parmat[4][4]; - /* get offset (parent-inverse) matrix */ - copy_m4_m4(invmat, data->invmat); - - /* extract components of both matrices */ - copy_v3_v3(loc, ct->matrix[3]); - mat4_to_eulO(eul, ct->rotOrder, ct->matrix); - mat4_to_size(size, ct->matrix); - - copy_v3_v3(loco, invmat[3]); - mat4_to_eulO(eulo, cob->rotOrder, invmat); - mat4_to_size(sizo, invmat); - - /* disable channels not enabled */ - if (!(data->flag & CHILDOF_LOCX)) loc[0]= loco[0]= 0.0f; - if (!(data->flag & CHILDOF_LOCY)) loc[1]= loco[1]= 0.0f; - if (!(data->flag & CHILDOF_LOCZ)) loc[2]= loco[2]= 0.0f; - if (!(data->flag & CHILDOF_ROTX)) eul[0]= eulo[0]= 0.0f; - if (!(data->flag & CHILDOF_ROTY)) eul[1]= eulo[1]= 0.0f; - if (!(data->flag & CHILDOF_ROTZ)) eul[2]= eulo[2]= 0.0f; - if (!(data->flag & CHILDOF_SIZEX)) size[0]= sizo[0]= 1.0f; - if (!(data->flag & CHILDOF_SIZEY)) size[1]= sizo[1]= 1.0f; - if (!(data->flag & CHILDOF_SIZEZ)) size[2]= sizo[2]= 1.0f; - - /* make new target mat and offset mat */ - loc_eulO_size_to_mat4(ct->matrix, loc, eul, size, ct->rotOrder); - loc_eulO_size_to_mat4(invmat, loco, eulo, sizo, cob->rotOrder); - - /* multiply target (parent matrix) by offset (parent inverse) to get - * the effect of the parent that will be exherted on the owner - */ - mul_m4_m4m4(parmat, invmat, ct->matrix); - - /* now multiply the parent matrix by the owner matrix to get the - * the effect of this constraint (i.e. owner is 'parented' to parent) - */ - copy_m4_m4(tempmat, cob->matrix); - mul_m4_m4m4(cob->matrix, tempmat, parmat); + /* simple matrix parenting */ + if(data->flag == CHILDOF_ALL) { + + /* multiply target (parent matrix) by offset (parent inverse) to get + * the effect of the parent that will be exherted on the owner + */ + mul_m4_m4m4(parmat, data->invmat, ct->matrix); + + /* now multiply the parent matrix by the owner matrix to get the + * the effect of this constraint (i.e. owner is 'parented' to parent) + */ + mul_m4_m4m4(cob->matrix, cob->matrix, parmat); + } + else { + float invmat[4][4], tempmat[4][4]; + float loc[3], eul[3], size[3]; + float loco[3], eulo[3], sizo[3]; + + /* get offset (parent-inverse) matrix */ + copy_m4_m4(invmat, data->invmat); + + /* extract components of both matrices */ + copy_v3_v3(loc, ct->matrix[3]); + mat4_to_eulO(eul, ct->rotOrder, ct->matrix); + mat4_to_size(size, ct->matrix); + + copy_v3_v3(loco, invmat[3]); + mat4_to_eulO(eulo, cob->rotOrder, invmat); + mat4_to_size(sizo, invmat); + + /* disable channels not enabled */ + if (!(data->flag & CHILDOF_LOCX)) loc[0]= loco[0]= 0.0f; + if (!(data->flag & CHILDOF_LOCY)) loc[1]= loco[1]= 0.0f; + if (!(data->flag & CHILDOF_LOCZ)) loc[2]= loco[2]= 0.0f; + if (!(data->flag & CHILDOF_ROTX)) eul[0]= eulo[0]= 0.0f; + if (!(data->flag & CHILDOF_ROTY)) eul[1]= eulo[1]= 0.0f; + if (!(data->flag & CHILDOF_ROTZ)) eul[2]= eulo[2]= 0.0f; + if (!(data->flag & CHILDOF_SIZEX)) size[0]= sizo[0]= 1.0f; + if (!(data->flag & CHILDOF_SIZEY)) size[1]= sizo[1]= 1.0f; + if (!(data->flag & CHILDOF_SIZEZ)) size[2]= sizo[2]= 1.0f; + + /* make new target mat and offset mat */ + loc_eulO_size_to_mat4(ct->matrix, loc, eul, size, ct->rotOrder); + loc_eulO_size_to_mat4(invmat, loco, eulo, sizo, cob->rotOrder); + + /* multiply target (parent matrix) by offset (parent inverse) to get + * the effect of the parent that will be exherted on the owner + */ + mul_m4_m4m4(parmat, invmat, ct->matrix); + + /* now multiply the parent matrix by the owner matrix to get the + * the effect of this constraint (i.e. owner is 'parented' to parent) + */ + copy_m4_m4(tempmat, cob->matrix); + mul_m4_m4m4(cob->matrix, tempmat, parmat); - /* without this, changes to scale and rotation can change location - * of a parentless bone or a disconnected bone. Even though its set - * to zero above. */ - if (!(data->flag & CHILDOF_LOCX)) cob->matrix[3][0]= tempmat[3][0]; - if (!(data->flag & CHILDOF_LOCY)) cob->matrix[3][1]= tempmat[3][1]; - if (!(data->flag & CHILDOF_LOCZ)) cob->matrix[3][2]= tempmat[3][2]; + /* without this, changes to scale and rotation can change location + * of a parentless bone or a disconnected bone. Even though its set + * to zero above. */ + if (!(data->flag & CHILDOF_LOCX)) cob->matrix[3][0]= tempmat[3][0]; + if (!(data->flag & CHILDOF_LOCY)) cob->matrix[3][1]= tempmat[3][1]; + if (!(data->flag & CHILDOF_LOCZ)) cob->matrix[3][2]= tempmat[3][2]; + } } } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 5ea5fe06c46..4784f19012e 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -164,27 +164,22 @@ void ED_area_overdraw_flush(ScrArea *sa, ARegion *ar) static void area_draw_azone(short x1, short y1, short x2, short y2) { - float xmin = x1; - float xmax = x2-2; - float ymin = y1-1; - float ymax = y2-3; - - float dx= 0.3f*(xmax-xmin); - float dy= 0.3f*(ymax-ymin); + int dx= floor(0.3f*(x2-x1)); + int dy= floor(0.3f*(y2-y1)); glColor4ub(255, 255, 255, 180); - fdrawline(xmin, ymax, xmax, ymin); + fdrawline(x1, y2, x2, y1); glColor4ub(255, 255, 255, 130); - fdrawline(xmin, ymax-dy, xmax-dx, ymin); + fdrawline(x1, y2-dy, x2-dx, y1); glColor4ub(255, 255, 255, 80); - fdrawline(xmin, ymax-2*dy, xmax-2*dx, ymin); + fdrawline(x1, y2-2*dy, x2-2*dx, y1); glColor4ub(0, 0, 0, 210); - fdrawline(xmin, ymax+1, xmax+1, ymin); + fdrawline(x1, y2+1, x2+1, y1); glColor4ub(0, 0, 0, 180); - fdrawline(xmin, ymax-dy+1, xmax-dx+1, ymin); + fdrawline(x1, y2-dy+1, x2-dx+1, y1); glColor4ub(0, 0, 0, 150); - fdrawline(xmin, ymax-2*dy+1, xmax-2*dx+1, ymin); + fdrawline(x1, y2-2*dy+1, x2-2*dx+1, y1); } @@ -451,7 +446,6 @@ void ED_area_headerprint(ScrArea *sa, const char *str) /* ************************************************************ */ -#define AZONESPOT 12 static void area_azone_initialize(ScrArea *sa) { AZone *az; @@ -465,8 +459,8 @@ static void area_azone_initialize(ScrArea *sa) az->type= AZONE_AREA; az->x1= sa->totrct.xmin; az->y1= sa->totrct.ymin; - az->x2= sa->totrct.xmin + AZONESPOT-1; - az->y2= sa->totrct.ymin + AZONESPOT-1; + az->x2= sa->totrct.xmin + AZONESPOT; + az->y2= sa->totrct.ymin + AZONESPOT; BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2); az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone"); @@ -474,13 +468,13 @@ static void area_azone_initialize(ScrArea *sa) az->type= AZONE_AREA; az->x1= sa->totrct.xmax+1; az->y1= sa->totrct.ymax+1; - az->x2= sa->totrct.xmax-AZONESPOT+1; - az->y2= sa->totrct.ymax-AZONESPOT+1; + az->x2= sa->totrct.xmax-AZONESPOT; + az->y2= sa->totrct.ymax-AZONESPOT; BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2); } #define AZONEPAD_EDGE 4 -#define AZONEPAD_ICON 8 +#define AZONEPAD_ICON 9 static void region_azone_edge(AZone *az, ARegion *ar) { switch(az->edge) { diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index 87b397382a3..ee448e70779 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -32,6 +32,8 @@ struct wmWindow; struct Scene; +#define AZONESPOT 12 + /* area.c */ void area_copy_data (ScrArea *sa1, ScrArea *sa2, int swap_space); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index b6c92982560..9267f4d4e80 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -474,7 +474,10 @@ AZone *is_in_area_actionzone(ScrArea *sa, int x, int y) for(az= sa->actionzones.first; az; az= az->next) { if(BLI_in_rcti(&az->rect, x, y)) { if(az->type == AZONE_AREA) { - if(isect_point_tri_v2_int(az->x1, az->y1, az->x2, az->y2, x, y)) + /* no triangle intersect but a hotspot circle based on corner */ + int radius= (x-az->x1)*(x-az->x1) + (y-az->y1)*(y-az->y1); + + if(radius <= AZONESPOT*AZONESPOT) break; } else if(az->type == AZONE_REGION) { diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index f9d6a70db48..275ffd93ae5 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -699,7 +699,8 @@ typedef enum eChildOf_Flags { CHILDOF_ROTZ = (1<<5), CHILDOF_SIZEX = (1<<6), CHILDOF_SIZEY = (1<<7), - CHILDOF_SIZEZ = (1<<8) + CHILDOF_SIZEZ = (1<<8), + CHILDOF_ALL = 511 } eChildOf_Flags; /* Pivot Constraint */