void make_axis_color(char *col, char *col2, char axis);
+/* SMOOTHVIEW */
+void smooth_view(struct View3D *v3d, float *ofs, float *quat, float *dist);
+
#endif /* BSE_DRAWVIEW_H */
char versemaster[160];
char verseuser[160];
short recent_files; /* maximum number of recently used files to remember */
+ short smooth_viewtx; /* miliseconds to spend spinning the view */
+ char pad[6];
} UserDef;
extern UserDef U; /* from usiblender.c !!!! */
short val;
float dvec[3], vb[2], xscale, yscale, scale;
+ /* SMOOTHVIEW */
+ float new_dist;
+ float new_ofs[3];
+
/* doesn't work fine for perspective */
if(G.vd->persp==1)
return;
vb[0] = G.vd->area->winx;
vb[1] = G.vd->area->winy;
+ new_dist = G.vd->dist;
+ new_ofs[0] = G.vd->ofs[0];
+ new_ofs[1] = G.vd->ofs[1];
+ new_ofs[2] = G.vd->ofs[2];
+
/* convert the drawn rectangle into 3d space */
- initgrabz(-G.vd->ofs[0], -G.vd->ofs[1], -G.vd->ofs[2]);
+ initgrabz(-new_ofs[0], -new_ofs[1], -new_ofs[2]);
+
window_to_3d(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(G.vd->ofs, G.vd->ofs, dvec);
+ VecSubf(new_ofs, new_ofs, dvec);
/* work out the ratios, so that everything selected fits when we zoom */
xscale = ((rect.xmax-rect.xmin)/vb[0]);
scale = (xscale >= yscale)?xscale:yscale;
/* zoom in as required, or as far as we can go */
- G.vd->dist = ((G.vd->dist*scale) >= 0.001*G.vd->grid)? G.vd->dist*scale:0.001*G.vd->grid;
+ new_dist = ((new_dist*scale) >= 0.001*G.vd->grid)? new_dist*scale:0.001*G.vd->grid;
+
+ smooth_view(G.vd, new_ofs, NULL, &new_dist);
+
}
}
G.vd->camdx= G.vd->camdy= 0.0;
else {
/*non camera center*/
+ float new_ofs[3];
curs= give_cursor();
- G.vd->ofs[0]= -curs[0];
- G.vd->ofs[1]= -curs[1];
- G.vd->ofs[2]= -curs[2];
+ new_ofs[0]= -curs[0];
+ new_ofs[1]= -curs[1];
+ new_ofs[2]= -curs[2];
+ smooth_view(G.vd, new_ofs, NULL, NULL);
}
}
doredraw= 1;
G.vd->camdx= G.vd->camdy= 0.0;
else {
/*non camera center*/
+ float new_ofs[3];
curs= give_cursor();
- G.vd->ofs[0]= -curs[0];
- G.vd->ofs[1]= -curs[1];
- G.vd->ofs[2]= -curs[2];
+ new_ofs[0]= -curs[0];
+ new_ofs[1]= -curs[1];
+ new_ofs[2]= -curs[2];
+ smooth_view(G.vd, new_ofs, NULL, NULL);
}
scrarea_queue_winredraw(curarea);
}
(xpos+edgsp+(3*mpref)+(4*midsp)),y1,(mpref),buth,
&U.pad_rot_angle, 0, 90, 0, 0,
"The rotation step for numerical pad keys (2 4 6 8)");
-
+
+ uiDefButS(block, NUM, B_DRAWINFO, "Smooth View:",
+ (xpos+edgsp+(4*mpref)+(5*midsp)),y1,(mpref),buth,
+ &U.smooth_viewtx, 0, 1000, 0, 0,
+ "The time to animate the view in miliseconds, zero to disable");
+
uiDefBut(block, LABEL,0,"Select with:",
(xpos+(2*edgsp)+(3*mpref)+(3*midsp)),y6label,mpref,buth,
0, 0, 0, 0, 0, "");
static int perspo=1;
int preview3d_event= 1;
+ float new_quat[4], new_dist;
+
if(event==PADENTER) {
if (G.qual == LR_SHIFTKEY) {
view3d_set_1_to_1_viewborder(G.vd);
if (G.vd->persp==2) {
G.vd->camzoom= 0;
} else {
- G.vd->dist= 10.0;
+ new_dist = 10.0;
+ smooth_view(G.vd, NULL, NULL, &new_dist);
}
}
}
/* G.vd->persp= 3; */
}
else if(event==PAD7) {
- G.vd->viewquat[0]= 0.0;
- G.vd->viewquat[1]= -1.0;
- G.vd->viewquat[2]= 0.0;
- G.vd->viewquat[3]= 0.0;
+ new_quat[0]=0.0;
+ new_quat[1]=-1.0;
+ new_quat[2]=0.0;
+ new_quat[3]=0.0;
+ G.vd->view= 0;
+ smooth_view(G.vd, NULL, new_quat, NULL);
G.vd->view= 7;
+
if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
else if(G.vd->persp>=2) G.vd->persp= perspo;
}
else if(event==PAD1) {
- G.vd->viewquat[0]= 0.0;
- G.vd->viewquat[1]= 0.0;
- G.vd->viewquat[2]= (float)-cos(M_PI/4.0);
- G.vd->viewquat[3]= (float)-cos(M_PI/4.0);
+ new_quat[0]=0.0;
+ new_quat[1]=0.0;
+ new_quat[2]=(float)-cos(M_PI/4.0);
+ new_quat[3]=(float)-cos(M_PI/4.0);
+ G.vd->view=0;
+ smooth_view(G.vd, NULL, new_quat, NULL);
G.vd->view=1;
if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
else if(G.vd->persp>=2) G.vd->persp= perspo;
}
else if(event==PAD3) {
- G.vd->viewquat[0]= 0.5;
- G.vd->viewquat[1]= -0.5;
- G.vd->viewquat[2]= 0.5;
- G.vd->viewquat[3]= 0.5;
+ new_quat[0]= 0.5;
+ new_quat[1]=-0.5;
+ new_quat[2]= 0.5;
+ new_quat[3]= 0.5;
+ G.vd->view=0;
+ smooth_view(G.vd, NULL, new_quat, NULL);
G.vd->view=3;
if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
else if(G.vd->persp>=2) G.vd->persp= perspo;
if(event==PAD7) {
- G.vd->viewquat[0]= 1.0;
- G.vd->viewquat[1]= 0.0;
- G.vd->viewquat[2]= 0.0;
- G.vd->viewquat[3]= 0.0;
+ new_quat[0]=1.0;
+ new_quat[1]=0.0;
+ new_quat[2]=0.0;
+ new_quat[3]=0.0;
+ G.vd->view=0;
+ smooth_view(G.vd, NULL, new_quat, NULL);
G.vd->view=7;
if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
else if(G.vd->persp>=2) G.vd->persp= perspo;
}
else if(event==PAD1) {
- G.vd->viewquat[0]= (float)cos(M_PI/4.0);
- G.vd->viewquat[1]= (float)-sin(M_PI/4.0);
- G.vd->viewquat[2]= 0.0;
- G.vd->viewquat[3]= 0.0;
+ new_quat[0]= (float)cos(M_PI/4.0);
+ new_quat[1]= (float)-sin(M_PI/4.0);
+ new_quat[2]= 0.0;
+ new_quat[3]= 0.0;
+ G.vd->view=0;
+ smooth_view(G.vd, NULL, new_quat, NULL);
G.vd->view=1;
if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
else if(G.vd->persp>=2) G.vd->persp= perspo;
}
else if(event==PAD3) {
- G.vd->viewquat[0]= 0.5;
- G.vd->viewquat[1]= -0.5;
- G.vd->viewquat[2]= -0.5;
- G.vd->viewquat[3]= -0.5;
+ new_quat[0]= 0.5;
+ new_quat[1]= -0.5;
+ new_quat[2]= -0.5;
+ new_quat[3]= -0.5;
+ G.vd->view=0;
+ smooth_view(G.vd, NULL, new_quat, NULL);
G.vd->view=3;
if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
else if(G.vd->persp>=2) G.vd->persp= perspo;
#include "mydevice.h"
#include "blendef.h"
+#include "PIL_time.h" /* smoothview */
+
#define TRACKBALLSIZE (1.1)
#define BL_NEAR_CLIP 0.001
scrarea_queue_winredraw(curarea);
}
else {
- /* clear flags */
+ /* clear flags */
base= FIRSTBASE;
while(base) {
if( base->lay & locallay ) {
Object *ob= OBACT;
float size, min[3], max[3], afm[3];
int ok=0;
-
+
+ /* SMOOTHVIEW */
+ float new_ofs[3];
+ float new_dist;
+
+
min[0]= min[1]= min[2]= 1.0e10;
max[0]= max[1]= max[2]= -1.0e10;
if(size<=0.01) size= 0.01;
- G.vd->ofs[0]= -(min[0]+max[0])/2.0;
- G.vd->ofs[1]= -(min[1]+max[1])/2.0;
- G.vd->ofs[2]= -(min[2]+max[2])/2.0;
-
- G.vd->dist= size;
+ new_ofs[0]= -(min[0]+max[0])/2.0;
+ new_ofs[1]= -(min[1]+max[1])/2.0;
+ new_ofs[2]= -(min[2]+max[2])/2.0;
+
+ new_dist = size;
// correction for window aspect ratio
if(curarea->winy>2 && curarea->winx>2) {
size= (float)curarea->winx/(float)curarea->winy;
if(size<1.0) size= 1.0/size;
- G.vd->dist*= size;
+ new_dist*= size;
}
if(G.vd->persp>1) {
G.vd->persp= 1;
}
-
- G.vd->cursor[0]= -G.vd->ofs[0];
- G.vd->cursor[1]= -G.vd->ofs[1];
- G.vd->cursor[2]= -G.vd->ofs[2];
-
+
+ G.vd->cursor[0]= -new_ofs[0];
+ G.vd->cursor[1]= -new_ofs[1];
+ G.vd->cursor[2]= -new_ofs[2];
+
+ smooth_view(G.vd, new_ofs, NULL, &new_dist);
+
scrarea_queue_winredraw(curarea);
BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
allqueue(REDRAWVIEW3D, 0); /* because of select */
allqueue(REDRAWOOPS, 0); /* because of select */
BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
- }
+ }
}
void view3d_home(int center)
if(size==0.0) ok= 0;
if(ok) {
-
- G.vd->ofs[0]= -(min[0]+max[0])/2.0;
- G.vd->ofs[1]= -(min[1]+max[1])/2.0;
- G.vd->ofs[2]= -(min[2]+max[2])/2.0;
-
- G.vd->dist= size;
+ float new_dist;
+ float new_ofs[3];
+
+ new_dist = size;
+ new_ofs[0]= -(min[0]+max[0])/2.0;
+ new_ofs[1]= -(min[1]+max[1])/2.0;
+ new_ofs[2]= -(min[2]+max[2])/2.0;
// correction for window aspect ratio
if(curarea->winy>2 && curarea->winx>2) {
size= (float)curarea->winx/(float)curarea->winy;
if(size<1.0) size= 1.0/size;
- G.vd->dist*= size;
+ new_dist*= size;
}
if(G.vd->persp==2) G.vd->persp= 1;
+
+ smooth_view(G.vd, new_ofs, NULL, &new_dist);
scrarea_queue_winredraw(curarea);
}
if (v3d->persp>=2) v3d->persp= 0; /* switch out of camera mode */
}
+
+
+/* SMOOTHVIEW */
+void smooth_view(View3D *v3d, float *ofs, float *quat, float *dist)
+{
+ /* View Animation enabled */
+ if (U.smooth_viewtx) {
+ int i;
+ char changed = 0;
+ float step = 0.0, step_inv;
+ float orig_dist;
+ float orig_quat[4];
+ float orig_ofs[3];
+
+ double time_allowed, time_current, time_start;
+
+ /* if there is no difference, return */
+ changed = 0; /* zero means no difference */
+ if (dist) {
+ if ((*dist) != v3d->dist)
+ changed = 1;
+ }
+
+ if (!changed && ofs) {
+ if ((ofs[0]!=v3d->ofs[0]) ||
+ (ofs[1]!=v3d->ofs[1]) ||
+ (ofs[2]!=v3d->ofs[2]) )
+ changed = 1;
+ }
+
+ if (!changed && quat ) {
+ if ((quat[0]!=v3d->viewquat[0]) ||
+ (quat[1]!=v3d->viewquat[1]) ||
+ (quat[2]!=v3d->viewquat[2]) ||
+ (quat[3]!=v3d->viewquat[3]) )
+ changed = 1;
+ }
+
+ /* The new view is different from teh old one
+ * so animate the view */
+ if (changed) {
+
+ /* store original values */
+ VECCOPY(orig_ofs, v3d->ofs);
+ QUATCOPY(orig_quat, v3d->viewquat);
+ orig_dist = v3d->dist;
+
+ time_allowed= (float)U.smooth_viewtx / 1000.0;
+ time_current = time_start = PIL_check_seconds_timer();
+
+ /* if this is view rotation only
+ * we can decrease the time allowed by
+ * the angle between quats
+ * this means small rotations wont lag */
+ if (quat && !ofs && !dist) {
+ float vec1[3], vec2[3];
+ VECCOPY(vec1, quat);
+ VECCOPY(vec2, v3d->viewquat);
+ Normalize(vec1);
+ Normalize(vec2);
+ /* scale the time allowed by the rotation */
+ time_allowed *= NormalizedVecAngle2(vec1, vec2)/(M_PI/2);
+ }
+
+ while (time_start + time_allowed > time_current) {
+
+ step = (float)((time_current-time_start) / time_allowed);
+
+ /* ease in/out */
+ if (step < 0.5) step = pow(step*2, 2)/2;
+ else step = 1-(pow(2*(1-step) ,2)/2);
+
+ step_inv = 1-step;
+
+ if (ofs)
+ for (i=0; i<3; i++)
+ v3d->ofs[i] = ofs[i]*step + orig_ofs[i]*step_inv;
+
+ if (quat)
+ QuatInterpol(v3d->viewquat, orig_quat, quat, step);
+
+ if (dist) {
+ v3d->dist = ((*dist)*step) + (orig_dist*step_inv);
+ }
+
+ /*redraw the view*/
+ scrarea_do_windraw(curarea);
+ screen_swapbuffers();
+
+ time_current= PIL_check_seconds_timer();
+ }
+ }
+ }
+
+ /* set these values even if animation is enabled because flaot
+ * error will make then not quite accurate */
+ if (ofs)
+ VECCOPY(v3d->ofs, ofs);
+ if (quat)
+ QUATCOPY(v3d->viewquat, quat);
+ if (dist)
+ v3d->dist = *dist;
+
+}
+