View3D four-split: added box-clip for the three ortho
windows. Is all on by default, waiting for headers and
buttons to come back.

Also: hotkey for foursplit now also removes it (toggle)

Also: window_to_3d() function only did delta's, 
renamed it to window_to_3d_delta  and coded a 
real window_to_3d()
This commit is contained in:
Ton Roosendaal 2009-01-20 18:31:11 +00:00
parent 81763d8cf0
commit bd9e896e96
11 changed files with 161 additions and 34 deletions

@ -790,7 +790,7 @@ static void gp_strokepoint_convertcoords (bGPDstroke *gps, bGPDspoint *pt, float
* - method taken from editview.c - mouse_cursor()
*/
project_short_noclip(ar, fp, mval);
window_to_3d(ar, dvec, mval[0]-mx, mval[1]-my);
window_to_3d_delta(ar, dvec, mval[0]-mx, mval[1]-my);
VecSubf(p3d, fp, dvec);
}
}
@ -1215,7 +1215,7 @@ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[])
/* method taken from editview.c - mouse_cursor() */
project_short_noclip(p->ar, fp, mval);
window_to_3d(p->ar, dvec, mval[0]-mx, mval[1]-my);
window_to_3d_delta(p->ar, dvec, mval[0]-mx, mval[1]-my);
VecSubf(out, fp, dvec);
}

@ -60,6 +60,7 @@ float *give_cursor(struct Scene *scene, struct View3D *v3d);
void initgrabz(struct RegionView3D *rv3d, float x, float y, float z);
void window_to_3d(struct ARegion *ar, float *vec, short mx, short my);
void window_to_3d_delta(struct ARegion *ar, float *vec, short mx, short my);
/* Depth buffer */
float read_cached_depth(struct ViewContext *vc, int x, int y);

@ -132,7 +132,7 @@ static void get_view_aligned_coordinate(float *fp, short mval[2])
// XXX initgrabz(fp[0], fp[1], fp[2]);
// if(mval[0]!=IS_CLIPPED) {
// window_to_3d(dvec, mval[0]-mx, mval[1]-my);
// window_to_3d_delta(dvec, mval[0]-mx, mval[1]-my);
// VecSubf(fp, fp, dvec);
// }
}

@ -1453,10 +1453,31 @@ static int region_foursplit_exec(bContext *C, wmOperator *op)
/* some rules... */
if(ar->regiontype!=RGN_TYPE_WINDOW)
BKE_report(op->reports, RPT_ERROR, "Only window region can be 4-splitted");
else if(ar->alignment==RGN_ALIGN_QSPLIT) {
ScrArea *sa= CTX_wm_area(C);
ARegion *arn;
/* keep current region */
ar->alignment= 0;
if(sa->spacetype==SPACE_VIEW3D) {
RegionView3D *rv3d= ar->regiondata;
rv3d->viewlock= 0;
}
for(ar= sa->regionbase.first; ar; ar= arn) {
arn= ar->next;
if(ar->alignment==RGN_ALIGN_QSPLIT) {
ED_region_exit(C, ar);
BKE_area_region_free(sa->type, ar);
BLI_remlink(&sa->regionbase, ar);
MEM_freeN(ar);
}
}
WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
}
else if(ar->next)
BKE_report(op->reports, RPT_ERROR, "Only last region can be 4-splitted");
else if(ar->alignment==RGN_ALIGN_QSPLIT)
BKE_report(op->reports, RPT_ERROR, "Cannot split further");
else {
ScrArea *sa= CTX_wm_area(C);
ARegion *newar;

@ -149,26 +149,30 @@ static void view3d_draw_clipping(RegionView3D *rv3d)
{
BoundBox *bb= rv3d->clipbb;
UI_ThemeColorShade(TH_BACK, -8);
glBegin(GL_QUADS);
glVertex3fv(bb->vec[0]); glVertex3fv(bb->vec[1]); glVertex3fv(bb->vec[2]); glVertex3fv(bb->vec[3]);
glVertex3fv(bb->vec[0]); glVertex3fv(bb->vec[4]); glVertex3fv(bb->vec[5]); glVertex3fv(bb->vec[1]);
glVertex3fv(bb->vec[4]); glVertex3fv(bb->vec[7]); glVertex3fv(bb->vec[6]); glVertex3fv(bb->vec[5]);
glVertex3fv(bb->vec[7]); glVertex3fv(bb->vec[3]); glVertex3fv(bb->vec[2]); glVertex3fv(bb->vec[6]);
glVertex3fv(bb->vec[1]); glVertex3fv(bb->vec[5]); glVertex3fv(bb->vec[6]); glVertex3fv(bb->vec[2]);
glVertex3fv(bb->vec[7]); glVertex3fv(bb->vec[4]); glVertex3fv(bb->vec[0]); glVertex3fv(bb->vec[3]);
glEnd();
if(bb) {
UI_ThemeColorShade(TH_BACK, -8);
glBegin(GL_QUADS);
glVertex3fv(bb->vec[0]); glVertex3fv(bb->vec[1]); glVertex3fv(bb->vec[2]); glVertex3fv(bb->vec[3]);
glVertex3fv(bb->vec[0]); glVertex3fv(bb->vec[4]); glVertex3fv(bb->vec[5]); glVertex3fv(bb->vec[1]);
glVertex3fv(bb->vec[4]); glVertex3fv(bb->vec[7]); glVertex3fv(bb->vec[6]); glVertex3fv(bb->vec[5]);
glVertex3fv(bb->vec[7]); glVertex3fv(bb->vec[3]); glVertex3fv(bb->vec[2]); glVertex3fv(bb->vec[6]);
glVertex3fv(bb->vec[1]); glVertex3fv(bb->vec[5]); glVertex3fv(bb->vec[6]); glVertex3fv(bb->vec[2]);
glVertex3fv(bb->vec[7]); glVertex3fv(bb->vec[4]); glVertex3fv(bb->vec[0]); glVertex3fv(bb->vec[3]);
glEnd();
}
}
void view3d_set_clipping(RegionView3D *rv3d)
{
double plane[4];
int a;
int a, tot=4;
for(a=0; a<4; a++) {
if(rv3d->viewlock) tot= 6;
for(a=0; a<tot; a++) {
QUATCOPY(plane, rv3d->clip[a]);
glClipPlane(GL_CLIP_PLANE0+a, plane);
glEnable(GL_CLIP_PLANE0+a);
@ -179,7 +183,7 @@ void view3d_clr_clipping(void)
{
int a;
for(a=0; a<4; a++) {
for(a=0; a<6; a++) {
glDisable(GL_CLIP_PLANE0+a);
}
}
@ -1327,7 +1331,7 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d)
/* calc window coord */
initgrabz(rv3d, 0.0, 0.0, 0.0);
window_to_3d(ar, vec, 1, 0);
window_to_3d_delta(ar, vec, 1, 0);
fac= MAX3( fabs(vec[0]), fabs(vec[1]), fabs(vec[1]) );
fac= 1.0/fac;

@ -83,6 +83,87 @@
/* ********************** view3d_edit: view manipulations ********************* */
/* ********************* box view support ***************** */
static void view3d_boxview_clip(ScrArea *sa)
{
ARegion *ar;
BoundBox *bb = MEM_callocN(sizeof(BoundBox), "clipbb");
float clip[6][4];
float x1, y1, z1, ofs[3];
int val;
/* create bounding box */
for(ar= sa->regionbase.first; ar; ar= ar->next) {
if(ar->regiontype==RGN_TYPE_WINDOW) {
RegionView3D *rv3d= ar->regiondata;
if(rv3d->viewlock) {
if(ELEM(rv3d->view, V3D_VIEW_TOP, V3D_VIEW_BOTTOM)) {
if(ar->winx>ar->winy) x1= rv3d->dist;
else x1= ar->winx*rv3d->dist/ar->winy;
if(ar->winx>ar->winy) y1= ar->winy*rv3d->dist/ar->winx;
else y1= rv3d->dist;
ofs[0]= rv3d->ofs[0];
ofs[1]= rv3d->ofs[1];
}
else if(ELEM(rv3d->view, V3D_VIEW_FRONT, V3D_VIEW_BACK)) {
ofs[2]= rv3d->ofs[2];
if(ar->winx>ar->winy) z1= ar->winy*rv3d->dist/ar->winx;
else z1= rv3d->dist;
}
}
}
}
for(val=0; val<8; val++) {
if(ELEM4(val, 0, 3, 4, 7))
bb->vec[val][0]= -x1 - ofs[0];
else
bb->vec[val][0]= x1 - ofs[0];
if(ELEM4(val, 0, 1, 4, 5))
bb->vec[val][1]= -y1 - ofs[1];
else
bb->vec[val][1]= y1 - ofs[1];
if(val > 3)
bb->vec[val][2]= -z1 - ofs[2];
else
bb->vec[val][2]= z1 - ofs[2];
}
/* normals for plane equations */
CalcNormFloat(bb->vec[0], bb->vec[1], bb->vec[4], clip[0]);
CalcNormFloat(bb->vec[1], bb->vec[2], bb->vec[5], clip[1]);
CalcNormFloat(bb->vec[2], bb->vec[3], bb->vec[6], clip[2]);
CalcNormFloat(bb->vec[3], bb->vec[0], bb->vec[7], clip[3]);
CalcNormFloat(bb->vec[4], bb->vec[5], bb->vec[6], clip[4]);
CalcNormFloat(bb->vec[0], bb->vec[2], bb->vec[1], clip[5]);
/* then plane equations */
for(val=0; val<5; val++) {
clip[val][3]= - clip[val][0]*bb->vec[val][0] - clip[val][1]*bb->vec[val][1] - clip[val][2]*bb->vec[val][2];
}
clip[5][3]= - clip[5][0]*bb->vec[0][0] - clip[5][1]*bb->vec[0][1] - clip[5][2]*bb->vec[0][2];
/* create bounding box */
for(ar= sa->regionbase.first; ar; ar= ar->next) {
if(ar->regiontype==RGN_TYPE_WINDOW) {
RegionView3D *rv3d= ar->regiondata;
if(rv3d->viewlock) {
rv3d->rflag |= RV3D_CLIPPING;
memcpy(rv3d->clip, clip, sizeof(clip));
}
}
}
MEM_freeN(bb);
}
/* sync ortho view of region to others, for view transforms */
static void view3d_boxview_sync(ScrArea *sa, ARegion *ar)
{
@ -119,6 +200,7 @@ static void view3d_boxview_sync(ScrArea *sa, ARegion *ar)
}
}
}
view3d_boxview_clip(sa);
}
/* for home, center etc */
@ -138,6 +220,7 @@ static void view3d_boxview_copy(ScrArea *sa, ARegion *ar)
}
}
}
view3d_boxview_clip(sa);
}
/* ************************** init for view ops **********************************/
@ -487,7 +570,7 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y)
else {
float dvec[3];
window_to_3d(vod->ar, dvec, x-vod->oldx, y-vod->oldy);
window_to_3d_delta(vod->ar, dvec, x-vod->oldx, y-vod->oldy);
VecAddf(vod->rv3d->ofs, vod->rv3d->ofs, dvec);
if(vod->rv3d->viewlock)
@ -575,7 +658,7 @@ static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
/* Project cursor position into 3D space */
initgrabz(rv3d, tpos[0], tpos[1], tpos[2]);
window_to_3d(ar, dvec, mouseloc[0]-vb[0]/2, mouseloc[1]-vb[1]/2);
window_to_3d_delta(ar, dvec, mouseloc[0]-vb[0]/2, mouseloc[1]-vb[1]/2);
/* Calculate view target position for dolly */
tvec[0] = -(tpos[0] + dvec[0]);
@ -1141,7 +1224,7 @@ static int view3d_border_zoom_exec(bContext *C, wmOperator *op)
initgrabz(rv3d, -new_ofs[0], -new_ofs[1], -new_ofs[2]);
window_to_3d(ar, dvec, (rect.xmin+rect.xmax-vb[0])/2, (rect.ymin+rect.ymax-vb[1])/2);
window_to_3d_delta(ar, dvec, (rect.xmin+rect.xmax-vb[0])/2, (rect.ymin+rect.ymax-vb[1])/2);
/* center the view to the center of the rectangle */
VecSubf(new_ofs, new_ofs, dvec);
}
@ -1398,10 +1481,10 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
initgrabz(rv3d, 0.0, 0.0, 0.0);
if(viewnum == V3D_VIEW_PANRIGHT) window_to_3d(ar, vec, -32, 0);
else if(viewnum == V3D_VIEW_PANLEFT) window_to_3d(ar, vec, 32, 0);
else if(viewnum == V3D_VIEW_PANUP) window_to_3d(ar, vec, 0, -25);
else if(viewnum == V3D_VIEW_PANDOWN) window_to_3d(ar, vec, 0, 25);
if(viewnum == V3D_VIEW_PANRIGHT) window_to_3d_delta(ar, vec, -32, 0);
else if(viewnum == V3D_VIEW_PANLEFT) window_to_3d_delta(ar, vec, 32, 0);
else if(viewnum == V3D_VIEW_PANUP) window_to_3d_delta(ar, vec, 0, -25);
else if(viewnum == V3D_VIEW_PANDOWN) window_to_3d_delta(ar, vec, 0, 25);
rv3d->ofs[0]+= vec[0];
rv3d->ofs[1]+= vec[1];
rv3d->ofs[2]+= vec[2];
@ -1612,7 +1695,7 @@ static int set_3dcursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
if(mval[0]!=IS_CLIPPED) {
window_to_3d(ar, dvec, mval[0]-mx, mval[1]-my);
window_to_3d_delta(ar, dvec, mval[0]-mx, mval[1]-my);
VecSubf(fp, fp, dvec);
}
else {

@ -481,11 +481,28 @@ void initgrabz(RegionView3D *rv3d, float x, float y, float z)
if (rv3d->zfac < 0.0f) rv3d->zfac = 1.0f;
}
/* always call initgrabz */
void window_to_3d(ARegion *ar, float *vec, short mx, short my)
{
RegionView3D *rv3d= ar->regiondata;
/* always call initgrabz */
float dx= ((float)(mx-(ar->winx/2)))*rv3d->zfac/(ar->winx/2);
float dy= ((float)(my-(ar->winy/2)))*rv3d->zfac/(ar->winy/2);
float fz= rv3d->persmat[0][3]*vec[0]+ rv3d->persmat[1][3]*vec[1]+ rv3d->persmat[2][3]*vec[2]+ rv3d->persmat[3][3];
fz= fz/rv3d->zfac;
vec[0]= (rv3d->persinv[0][0]*dx + rv3d->persinv[1][0]*dy+ rv3d->persinv[2][0]*fz)-rv3d->ofs[0];
vec[1]= (rv3d->persinv[0][1]*dx + rv3d->persinv[1][1]*dy+ rv3d->persinv[2][1]*fz)-rv3d->ofs[1];
vec[2]= (rv3d->persinv[0][2]*dx + rv3d->persinv[1][2]*dy+ rv3d->persinv[2][2]*fz)-rv3d->ofs[2];
}
/* always call initgrabz */
/* only to detect delta motion */
void window_to_3d_delta(ARegion *ar, float *vec, short mx, short my)
{
RegionView3D *rv3d= ar->regiondata;
float dx, dy;
dx= 2.0f*mx*rv3d->zfac/ar->winx;
@ -1028,6 +1045,7 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d)
}
}
else {
/* should be moved to better initialize later on XXX */
if(rv3d->viewlock)
view3d_viewlock(rv3d);

@ -186,7 +186,7 @@ void setTransformViewMatrices(TransInfo *t)
void convertViewVec(TransInfo *t, float *vec, short dx, short dy)
{
if (t->spacetype==SPACE_VIEW3D) {
window_to_3d(t->ar, vec, dx, dy);
window_to_3d_delta(t->ar, vec, dx, dy);
}
else if(t->spacetype==SPACE_IMAGE) {
View2D *v2d = t->view;

@ -930,7 +930,7 @@ static void setNearestAxis3d(TransInfo *t)
and to overflow the short integers.
The formula used is a bit stupid, just a simplification of the substraction
of two 2D points 30 pixels apart (that's the last factor in the formula) after
projecting them with window_to_3d and then get the length of that vector.
projecting them with window_to_3d_delta and then get the length of that vector.
*/
zfac= t->persmat[0][3]*t->center[0]+ t->persmat[1][3]*t->center[1]+ t->persmat[2][3]*t->center[2]+ t->persmat[3][3];
zfac = VecLength(t->persinv[0]) * 2.0f/t->ar->winx * zfac * 30.0f;

@ -1081,7 +1081,7 @@ void calculateCenter(TransInfo *t)
if(t->spacetype==SPACE_VIEW3D)
{
/* initgrabz() defines a factor for perspective depth correction, used in window_to_3d() */
/* initgrabz() defines a factor for perspective depth correction, used in window_to_3d_delta() */
if(t->flag & (T_EDIT|T_POSE)) {
Object *ob= t->obedit?t->obedit:t->poseobj;
float vec[3];

@ -92,7 +92,7 @@ typedef struct RegionView3D {
short view;
/* user defined clipping planes */
float clip[4][4];
float clip[6][4];
struct BoundBox *clipbb;
struct bGPdata *gpd; /* Grease-Pencil Data (annotation layers) */