Page MenuHome

editview_c_fly_func.txt

File Metadata

Author
Campbell Barton (campbellbarton)
Created
Nov 13 2013, 1:00 PM

editview_c_fly_func.txt

void fly(void)
{
float speed=0.0, dvec[3]={0,0,0}, mat[3][3], angle;
float upvec[3]={0,0,0}, tmpvec[3], dist_backup, tmp_quat[4];
int loop=1;
short val, cent[2], mval[2], moffset[2];
unsigned short toets;
unsigned char apply_rotation=1, correct_vroll=0;
if(curarea->spacetype!=SPACE_VIEW3D) return;
if(G.vd->persp!=1) return;
/* the dist defines a vector that is infront of the offset
to rotate the view about.
this is no good for fly mode because we
want to rotate about the viewers centre.
but to correct the dist removal we must
alter offset so the view dosent jump. */
dist_backup= G.vd->dist;
G.vd->dist= 0.0;
upvec[2]=dist_backup; /*x and y are 0*/
Mat3CpyMat4(mat, G.vd->viewinv);
Mat3MulVecfl(mat, upvec);
G.vd->ofs[0]-= upvec[0];
G.vd->ofs[1]-= upvec[1];
G.vd->ofs[2]-= upvec[2];
/*Done with correcting for the dist/*/
cent[0]= curarea->winrct.xmin+(curarea->winx)/2;
cent[1]= curarea->winrct.ymin+(curarea->winy)/2;
warp_pointer(cent[0], cent[1]);
/* we have to rely on events to give proper mousecoords after a warp_pointer */
mval[0]= cent[0]= (curarea->winx)/2;
mval[1]= cent[1]= (curarea->winy)/2;
while(loop) {
while(qtest()) {
toets= extern_qread(&val);
if(val) {
if(toets==MOUSEY) getmouseco_areawin(mval);
else if(toets==ESCKEY || toets==LEFTMOUSE || toets==RIGHTMOUSE) {
loop= 0;
break;
} else if(toets==PADPLUSKEY) {
if (speed<0) speed=0;
else speed+= G.vd->grid;
} else if(toets==PADMINUS) {
if (speed>0) speed=0;
else speed-= G.vd->grid;
}
}
}
if(loop==0) break;
/* make it so the camera direction dosent follow the view
good for flying backwards! */
if (G.qual & LR_SHIFTKEY) apply_rotation=0;
else apply_rotation=1;
/* correct the view rolling */
if (G.qual & LR_CTRLKEY) correct_vroll=1;
else correct_vroll=0;
moffset[0]= mval[0]-cent[0];
moffset[1]= mval[1]-cent[1];
/* enforce a view margin */
if (moffset[0]>100) moffset[0]-=100;
else if (moffset[0]<100)moffset[0]+=100;
else moffset[0]=0;
if (moffset[1]>100) moffset[1]-=100;
else if (moffset[1]<100)moffset[1]+=100;
else moffset[1]=0;
/* define dvec, view direction vector */
if (apply_rotation) {
dvec[0]= 0;
dvec[1]= 0;
dvec[2]= 1.0;
}
if(speed!=0.0 || moffset[0] || moffset[1] || correct_vroll) {
Mat3CpyMat4(mat, G.vd->viewinv);
if (apply_rotation) {
Normalise(dvec);
Mat3MulVecfl(mat, dvec);
}
/* rotate about the X axis- look up/down */
if (moffset[1]) {
upvec[0]=1;
upvec[1]=0;
upvec[2]=0;
Mat3MulVecfl(mat, upvec);
VecRotToQuat( upvec, (float)moffset[1]*-0.00005, tmp_quat); /* Rotate about the relative up vec */
QuatMul(G.vd->viewquat, G.vd->viewquat, tmp_quat);
}
/* rotate about the Y axis- look left/right */
if (moffset[0]) {
upvec[0]=0;
upvec[1]=1;
upvec[2]=0;
Mat3MulVecfl(mat, upvec);
VecRotToQuat( upvec, (float)moffset[0]*0.00005, tmp_quat); /* Rotate about the relative up vec */
QuatMul(G.vd->viewquat, G.vd->viewquat, tmp_quat);
}
if (correct_vroll) {
upvec[0]=1;
upvec[1]=0;
upvec[2]=0;
Mat3MulVecfl(mat, upvec);
tmpvec[0]= upvec[0];
upvec[1]= tmpvec[1]= 0;
tmpvec[2]= 0;
angle= VecAngle2(tmpvec, upvec);
if (upvec[2]<0)
angle=-angle;
// now correct the angle
upvec[0]=0;
upvec[1]=0;
upvec[2]=1;
Mat3MulVecfl(mat, upvec);
VecRotToQuat( upvec, angle*0.001, tmp_quat); /* Rotate about the relative up vec */
QuatMul(G.vd->viewquat, G.vd->viewquat, tmp_quat);
}
if (apply_rotation)
VecMulf(dvec, speed*0.01);
G.vd->ofs[0]+= dvec[0];
G.vd->ofs[1]+= dvec[1];
G.vd->ofs[2]+= dvec[2];
headerprint("FlyModeKeys Speed(+/-), MouseLook: Shift, RollCorrect: Ctrl, Exit:LMB");
scrarea_do_windraw(curarea);
screen_swapbuffers();
}
}
/*restore the dist*/
upvec[0]= upvec[1]= 0;
upvec[2]=dist_backup; /*x and y are 0*/
Mat3CpyMat4(mat, G.vd->viewinv);
Mat3MulVecfl(mat, upvec);
G.vd->ofs[0]+= upvec[0];
G.vd->ofs[1]+= upvec[1];
G.vd->ofs[2]+= upvec[2];
G.vd->dist= dist_backup;
/*Done with correcting for the dist */
allqueue(REDRAWVIEW3D, 0);
scrarea_queue_headredraw(curarea);
}

Event Timeline