diff options
author | Ton Roosendaal <ton@blender.org> | 2008-12-18 20:38:21 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2008-12-18 20:38:21 +0300 |
commit | c7f6f25a9d20464fe58b2b3b7e1de3300369d085 (patch) | |
tree | fdea0563369d99ce6ee96637ded723a41f4ef07b | |
parent | e8e903cd534e8c644dd8e2ceeadab0236fa94f00 (diff) |
2.5
Drawing and viewing code for view3d back (no not objects :).
Quick test: converted 2250 ugly lines of code in 2.5 hours.
With about 300k lines todo, this will be 333 hours = 30 days? Whoa!
-rw-r--r-- | source/blender/editors/include/ED_util.h | 5 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/Makefile | 3 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/SConscript | 1 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 13 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 1454 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_intern.h | 31 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_view.c | 714 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_view3d_types.h | 4 |
8 files changed, 2212 insertions, 13 deletions
diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index d0a4b93bfae..885c4d3317e 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -33,6 +33,11 @@ #define XIC 20 #define YIC 20 +/* proposal = put scene pointers on function calls? */ +#define BASACT (scene->basact) +#define OBACT (BASACT? BASACT->object: 0) + + void apply_keyb_grid(float *val, float fac1, float fac2, float fac3, int invert); int GetButStringLength(char *str); diff --git a/source/blender/editors/space_view3d/Makefile b/source/blender/editors/space_view3d/Makefile index 45b6ca648d2..e097d041a37 100644 --- a/source/blender/editors/space_view3d/Makefile +++ b/source/blender/editors/space_view3d/Makefile @@ -38,6 +38,8 @@ CFLAGS += $(LEVEL_1_C_WARNINGS) CPPFLAGS += -I$(NAN_GLEW)/include CPPFLAGS += -I$(OPENGL_HEADERS) +CPPFLAGS += -I$(NAN_BMFONT)/include + # not very neat.... CPPFLAGS += -I../../windowmanager CPPFLAGS += -I../../blenloader @@ -46,6 +48,7 @@ CPPFLAGS += -I../../blenlib CPPFLAGS += -I../../makesdna CPPFLAGS += -I../../imbuf CPPFLAGS += -I../../python +CPPFLAGS += -I../../render/extern/include CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include # own include diff --git a/source/blender/editors/space_view3d/SConscript b/source/blender/editors/space_view3d/SConscript index 01ee5bd4a06..5d30ae91deb 100644 --- a/source/blender/editors/space_view3d/SConscript +++ b/source/blender/editors/space_view3d/SConscript @@ -5,5 +5,6 @@ sources = env.Glob('*.c') incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' +incs += ' ../../render/extern/include #/intern/guardedalloc #intern/bmfont' env.BlenderLib ( 'bf_editors_space_view3d', sources, Split(incs), [], libtype=['core','intern'], priority=[35, 40] ) diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 3f30d1cbd79..218c55edd53 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -189,17 +189,10 @@ void view3d_keymap(struct wmWindowManager *wm) static void view3d_main_area_draw(const bContext *C, ARegion *ar) { /* draw entirely, view changes should be handled here */ - float col[3], fac; + ScrArea *sa= CTX_wm_area(C); + View3D *v3d= sa->spacedata.first; /* XXX get from region */ - /* clear and setup matrix */ - UI_GetThemeColor3fv(TH_BACK, col); - glClearColor(col[0], col[1], col[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - /* swapbuffers indicator */ - fac= BLI_frand(); - glColor3f(fac, fac, fac); - glRecti(20, 2, 30, 12); + drawview3dspace(C, ar, v3d); } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c new file mode 100644 index 00000000000..712a69be77b --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -0,0 +1,1454 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <string.h> +#include <stdio.h> +#include <math.h> + +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_camera_types.h" +#include "DNA_key_types.h" +#include "DNA_object_types.h" +#include "DNA_space_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_userdef_types.h" +#include "DNA_view3d_types.h" +#include "DNA_world_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_rand.h" + +#include "BKE_anim.h" +#include "BKE_context.h" +#include "BKE_image.h" +#include "BKE_ipo.h" +#include "BKE_key.h" +#include "BKE_object.h" +#include "BKE_global.h" +#include "BKE_scene.h" +#include "BKE_screen.h" +#include "BKE_utildefines.h" + +#include "RE_pipeline.h" // make_stars + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" +#include "BMF_Api.h" + +#include "WM_api.h" + +#include "ED_screen.h" +#include "ED_util.h" + +#include "UI_interface.h" +#include "UI_interface_icons.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "view3d_intern.h" // own include + + + +static void star_stuff_init_func(void) +{ + cpack(-1); + glPointSize(1.0); + glBegin(GL_POINTS); +} +static void star_stuff_vertex_func(float* i) +{ + glVertex3fv(i); +} +static void star_stuff_term_func(void) +{ + glEnd(); +} + +void circf(float x, float y, float rad) +{ + GLUquadricObj *qobj = gluNewQuadric(); + + gluQuadricDrawStyle(qobj, GLU_FILL); + + glPushMatrix(); + + glTranslatef(x, y, 0.); + + gluDisk( qobj, 0.0, rad, 32, 1); + + glPopMatrix(); + + gluDeleteQuadric(qobj); +} + +void circ(float x, float y, float rad) +{ + GLUquadricObj *qobj = gluNewQuadric(); + + gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); + + glPushMatrix(); + + glTranslatef(x, y, 0.); + + gluDisk( qobj, 0.0, rad, 32, 1); + + glPopMatrix(); + + gluDeleteQuadric(qobj); +} + + +/* ********* custom clipping *********** */ + +static void view3d_draw_clipping(View3D *v3d) +{ + BoundBox *bb= v3d->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(); +} + +void view3d_set_clipping(View3D *v3d) +{ + double plane[4]; + int a; + + for(a=0; a<4; a++) { + QUATCOPY(plane, v3d->clip[a]); + glClipPlane(GL_CLIP_PLANE0+a, plane); + glEnable(GL_CLIP_PLANE0+a); + } +} + +void view3d_clr_clipping(void) +{ + int a; + + for(a=0; a<4; a++) { + glDisable(GL_CLIP_PLANE0+a); + } +} + +int view3d_test_clipping(View3D *v3d, float *vec) +{ + /* vec in world coordinates, returns 1 if clipped */ + float view[3]; + + VECCOPY(view, vec); + + if(0.0f < v3d->clip[0][3] + INPR(view, v3d->clip[0])) + if(0.0f < v3d->clip[1][3] + INPR(view, v3d->clip[1])) + if(0.0f < v3d->clip[2][3] + INPR(view, v3d->clip[2])) + if(0.0f < v3d->clip[3][3] + INPR(view, v3d->clip[3])) + return 0; + + return 1; +} + +/* ********* end custom clipping *********** */ + + +static void drawgrid_draw(ARegion *ar, float wx, float wy, float x, float y, float dx) +{ + float fx, fy; + + x+= (wx); + y+= (wy); + fx= x/dx; + fx= x-dx*floor(fx); + + while(fx< ar->winx) { + fdrawline(fx, 0.0, fx, (float)ar->winy); + fx+= dx; + } + + fy= y/dx; + fy= y-dx*floor(fy); + + + while(fy< ar->winy) { + fdrawline(0.0, fy, (float)ar->winx, fy); + fy+= dx; + } + +} + +// not intern, called in editobject for constraint axis too +void make_axis_color(char *col, char *col2, char axis) +{ + if(axis=='x') { + col2[0]= col[0]>219?255:col[0]+36; + col2[1]= col[1]<26?0:col[1]-26; + col2[2]= col[2]<26?0:col[2]-26; + } + else if(axis=='y') { + col2[0]= col[0]<46?0:col[0]-36; + col2[1]= col[1]>189?255:col[1]+66; + col2[2]= col[2]<46?0:col[2]-36; + } + else { + col2[0]= col[0]<26?0:col[0]-26; + col2[1]= col[1]<26?0:col[1]-26; + col2[2]= col[2]>209?255:col[2]+46; + } + +} + +static void drawgrid(ARegion *ar, View3D *v3d) +{ + /* extern short bgpicmode; */ + float wx, wy, x, y, fw, fx, fy, dx; + float vec4[4]; + char col[3], col2[3]; + short sublines = v3d->gridsubdiv; + + vec4[0]=vec4[1]=vec4[2]=0.0; + vec4[3]= 1.0; + Mat4MulVec4fl(v3d->persmat, vec4); + fx= vec4[0]; + fy= vec4[1]; + fw= vec4[3]; + + wx= (ar->winx/2.0); /* because of rounding errors, grid at wrong location */ + wy= (ar->winy/2.0); + + x= (wx)*fx/fw; + y= (wy)*fy/fw; + + vec4[0]=vec4[1]=v3d->grid; + vec4[2]= 0.0; + vec4[3]= 1.0; + Mat4MulVec4fl(v3d->persmat, vec4); + fx= vec4[0]; + fy= vec4[1]; + fw= vec4[3]; + + dx= fabs(x-(wx)*fx/fw); + if(dx==0) dx= fabs(y-(wy)*fy/fw); + + glDepthMask(0); // disable write in zbuffer + + /* check zoom out */ + UI_ThemeColor(TH_GRID); + + if(dx<6.0) { + v3d->gridview*= sublines; + dx*= sublines; + + if(dx<6.0) { + v3d->gridview*= sublines; + dx*= sublines; + + if(dx<6.0) { + v3d->gridview*= sublines; + dx*=sublines; + if(dx<6.0); + else { + UI_ThemeColor(TH_GRID); + drawgrid_draw(ar, wx, wy, x, y, dx); + } + } + else { // start blending out + UI_ThemeColorBlend(TH_BACK, TH_GRID, dx/60.0); + drawgrid_draw(ar, wx, wy, x, y, dx); + + UI_ThemeColor(TH_GRID); + drawgrid_draw(ar, wx, wy, x, y, sublines*dx); + } + } + else { // start blending out (6 < dx < 60) + UI_ThemeColorBlend(TH_BACK, TH_GRID, dx/60.0); + drawgrid_draw(ar, wx, wy, x, y, dx); + + UI_ThemeColor(TH_GRID); + drawgrid_draw(ar, wx, wy, x, y, sublines*dx); + } + } + else { + if(dx>60.0) { // start blending in + v3d->gridview/= sublines; + dx/= sublines; + if(dx>60.0) { // start blending in + v3d->gridview/= sublines; + dx/= sublines; + if(dx>60.0) { + UI_ThemeColor(TH_GRID); + drawgrid_draw(ar, wx, wy, x, y, dx); + } + else { + UI_ThemeColorBlend(TH_BACK, TH_GRID, dx/60.0); + drawgrid_draw(ar, wx, wy, x, y, dx); + UI_ThemeColor(TH_GRID); + drawgrid_draw(ar, wx, wy, x, y, dx*sublines); + } + } + else { + UI_ThemeColorBlend(TH_BACK, TH_GRID, dx/60.0); + drawgrid_draw(ar, wx, wy, x, y, dx); + UI_ThemeColor(TH_GRID); + drawgrid_draw(ar, wx, wy, x, y, dx*sublines); + } + } + else { + UI_ThemeColorBlend(TH_BACK, TH_GRID, dx/60.0); + drawgrid_draw(ar, wx, wy, x, y, dx); + UI_ThemeColor(TH_GRID); + drawgrid_draw(ar, wx, wy, x, y, dx*sublines); + } + } + + x+= (wx); + y+= (wy); + UI_GetThemeColor3ubv(TH_GRID, col); + + setlinestyle(0); + + /* center cross */ + if(v3d->view==3) make_axis_color(col, col2, 'y'); + else make_axis_color(col, col2, 'x'); + glColor3ubv((GLubyte *)col2); + + fdrawline(0.0, y, (float)ar->winx, y); + + if(v3d->view==7) make_axis_color(col, col2, 'y'); + else make_axis_color(col, col2, 'z'); + glColor3ubv((GLubyte *)col2); + + fdrawline(x, 0.0, x, (float)ar->winy); + + glDepthMask(1); // enable write in zbuffer +} + + +static void drawfloor(View3D *v3d) +{ + float vert[3], grid; + int a, gridlines, emphasise; + char col[3], col2[3]; + short draw_line = 0; + + vert[2]= 0.0; + + if(v3d->gridlines<3) return; + + if(v3d->zbuf && G.obedit) glDepthMask(0); // for zbuffer-select + + gridlines= v3d->gridlines/2; + grid= gridlines*v3d->grid; + + UI_GetThemeColor3ubv(TH_GRID, col); + UI_GetThemeColor3ubv(TH_BACK, col2); + + /* emphasise division lines lighter instead of darker, if background is darker than grid */ + if ( ((col[0]+col[1]+col[2])/3+10) > (col2[0]+col2[1]+col2[2])/3 ) + emphasise = 20; + else + emphasise = -10; + + /* draw the Y axis and/or grid lines */ + for(a= -gridlines;a<=gridlines;a++) { + if(a==0) { + /* check for the 'show Y axis' preference */ + if (v3d->gridflag & V3D_SHOW_Y) { + make_axis_color(col, col2, 'y'); + glColor3ubv((GLubyte *)col2); + + draw_line = 1; + } else if (v3d->gridflag & V3D_SHOW_FLOOR) { + UI_ThemeColorShade(TH_GRID, emphasise); + } else { + draw_line = 0; + } + } else { + /* check for the 'show grid floor' preference */ + if (v3d->gridflag & V3D_SHOW_FLOOR) { + if( (a % 10)==0) { + UI_ThemeColorShade(TH_GRID, emphasise); + } + else UI_ThemeColorShade(TH_GRID, 10); + + draw_line = 1; + } else { + draw_line = 0; + } + } + + if (draw_line) { + glBegin(GL_LINE_STRIP); + vert[0]= a*v3d->grid; + vert[1]= grid; + glVertex3fv(vert); + vert[1]= -grid; + glVertex3fv(vert); + glEnd(); + } + } + + /* draw the X axis and/or grid lines */ + for(a= -gridlines;a<=gridlines;a++) { + if(a==0) { + /* check for the 'show X axis' preference */ + if (v3d->gridflag & V3D_SHOW_X) { + make_axis_color(col, col2, 'x'); + glColor3ubv((GLubyte *)col2); + + draw_line = 1; + } else if (v3d->gridflag & V3D_SHOW_FLOOR) { + UI_ThemeColorShade(TH_GRID, emphasise); + } else { + draw_line = 0; + } + } else { + /* check for the 'show grid floor' preference */ + if (v3d->gridflag & V3D_SHOW_FLOOR) { + if( (a % 10)==0) { + UI_ThemeColorShade(TH_GRID, emphasise); + } + else UI_ThemeColorShade(TH_GRID, 10); + + draw_line = 1; + } else { + draw_line = 0; + } + } + + if (draw_line) { + glBegin(GL_LINE_STRIP); + vert[1]= a*v3d->grid; + vert[0]= grid; + glVertex3fv(vert ); + vert[0]= -grid; + glVertex3fv(vert); + glEnd(); + } + } + + /* draw the Z axis line */ + /* check for the 'show Z axis' preference */ + if (v3d->gridflag & V3D_SHOW_Z) { + make_axis_color(col, col2, 'z'); + glColor3ubv((GLubyte *)col2); + + glBegin(GL_LINE_STRIP); + vert[0]= 0; + vert[1]= 0; + vert[2]= grid; + glVertex3fv(vert ); + vert[2]= -grid; + glVertex3fv(vert); + glEnd(); + } + + if(v3d->zbuf && G.obedit) glDepthMask(1); + +} + +static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) +{ + short mx,my,co[2]; + int flag; + + /* we dont want the clipping for cursor */ + flag= v3d->flag; + v3d->flag= 0; + project_short(ar, v3d, give_cursor(scene, v3d), co); + v3d->flag= flag; + + mx = co[0]; + my = co[1]; + + if(mx!=IS_CLIPPED) { + setlinestyle(0); + cpack(0xFF); + circ((float)mx, (float)my, 10.0); + setlinestyle(4); + cpack(0xFFFFFF); + circ((float)mx, (float)my, 10.0); + setlinestyle(0); + cpack(0x0); + + sdrawline(mx-20, my, mx-5, my); + sdrawline(mx+5, my, mx+20, my); + sdrawline(mx, my-20, mx, my-5); + sdrawline(mx, my+5, mx, my+20); + } +} + +/* Draw a live substitute of the view icon, which is always shown */ +static void draw_view_axis(View3D *v3d) +{ + const float k = U.rvisize; /* axis size */ + const float toll = 0.5; /* used to see when view is quasi-orthogonal */ + const float start = k + 1.0; /* axis center in screen coordinates, x=y */ + float ydisp = 0.0; /* vertical displacement to allow obj info text */ + + /* rvibright ranges approx. from original axis icon color to gizmo color */ + float bright = U.rvibright / 15.0f; + + unsigned char col[3]; + unsigned char gridcol[3]; + float colf[3]; + + float vec[4]; + float dx, dy; + float h, s, v; + + /* thickness of lines is proportional to k */ + /* (log(k)-1) gives a more suitable thickness, but fps decreased by about 3 fps */ + glLineWidth(k / 10); + //glLineWidth(log(k)-1); // a bit slow + + UI_GetThemeColor3ubv(TH_GRID, (char *)gridcol); + + /* X */ + vec[0] = vec[3] = 1; + vec[1] = vec[2] = 0; + QuatMulVecf(v3d->viewquat, vec); + + make_axis_color((char *)gridcol, (char *)col, 'x'); + rgb_to_hsv(col[0]/255.0f, col[1]/255.0f, col[2]/255.0f, &h, &s, &v); + s = s<0.5 ? s+0.5 : 1.0; + v = 0.3; + v = (v<1.0-(bright) ? v+bright : 1.0); + hsv_to_rgb(h, s, v, colf, colf+1, colf+2); + glColor3fv(colf); + + dx = vec[0] * k; + dy = vec[1] * k; + fdrawline(start, start + ydisp, start + dx, start + dy + ydisp); + if (fabs(dx) > toll || fabs(dy) > toll) { + glRasterPos2i(start + dx + 2, start + dy + ydisp + 2); + BMF_DrawString(G.fonts, "x"); + } + + /* Y */ + vec[1] = vec[3] = 1; + vec[0] = vec[2] = 0; + QuatMulVecf(v3d->viewquat, vec); + + make_axis_color((char *)gridcol, (char *)col, 'y'); + rgb_to_hsv(col[0]/255.0f, col[1]/255.0f, col[2]/255.0f, &h, &s, &v); + s = s<0.5 ? s+0.5 : 1.0; + v = 0.3; + v = (v<1.0-(bright) ? v+bright : 1.0); + hsv_to_rgb(h, s, v, colf, colf+1, colf+2); + glColor3fv(colf); + + dx = vec[0] * k; + dy = vec[1] * k; + fdrawline(start, start + ydisp, start + dx, start + dy + ydisp); + if (fabs(dx) > toll || fabs(dy) > toll) { + glRasterPos2i(start + dx + 2, start + dy + ydisp + 2); + BMF_DrawString(G.fonts, "y"); + } + + /* Z */ + vec[2] = vec[3] = 1; + vec[1] = vec[0] = 0; + QuatMulVecf(v3d->viewquat, vec); + + make_axis_color((char *)gridcol, (char *)col, 'z'); + rgb_to_hsv(col[0]/255.0f, col[1]/255.0f, col[2]/255.0f, &h, &s, &v); + s = s<0.5 ? s+0.5 : 1.0; + v = 0.5; + v = (v<1.0-(bright) ? v+bright : 1.0); + hsv_to_rgb(h, s, v, colf, colf+1, colf+2); + glColor3fv(colf); + + dx = vec[0] * k; + dy = vec[1] * k; + fdrawline(start, start + ydisp, start + dx, start + dy + ydisp); + if (fabs(dx) > toll || fabs(dy) > toll) { + glRasterPos2i(start + dx + 2, start + dy + ydisp + 2); + BMF_DrawString(G.fonts, "z"); + } + + /* restore line-width */ + glLineWidth(1.0); +} + + +static void draw_view_icon(View3D *v3d) +{ + BIFIconID icon; + + if(v3d->view==7) icon= ICON_AXIS_TOP; + else if(v3d->view==1) icon= ICON_AXIS_FRONT; + else if(v3d->view==3) icon= ICON_AXIS_SIDE; + else return ; + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + UI_icon_draw(5.0, 5.0, icon); + + glDisable(GL_BLEND); +} + +char *view3d_get_name(View3D *v3d) +{ + char *name = NULL; + + switch (v3d->view) { + case 1: + if (v3d->persp == V3D_ORTHO) + name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Back Ortho" : "Front Ortho"; + else + name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Back Persp" : "Front Persp"; + break; + case 3: + if (v3d->persp == V3D_ORTHO) + name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Left Ortho" : "Right Ortho"; + else + name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Left Persp" : "Right Persp"; + break; + case 7: + if (v3d->persp == V3D_ORTHO) + name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Bottom Ortho" : "Top Ortho"; + else + name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Bottom Persp" : "Top Persp"; + break; + default: + if (v3d->persp==V3D_CAMOB) { + if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) { + Camera *cam; + cam = v3d->camera->data; + name = (cam->type != CAM_ORTHO) ? "Camera Persp" : "Camera Ortho"; + } else { + name = "Object as Camera"; + } + } else { + name = (v3d->persp == V3D_ORTHO) ? "User Ortho" : "User Persp"; + } + break; + } + + return name; +} + +static void draw_viewport_name(ARegion *ar, View3D *v3d) +{ + char *name = view3d_get_name(v3d); + char *printable = NULL; + + if (v3d->localview) { + printable = malloc(strlen(name) + strlen(" (Local)_")); /* '_' gives space for '\0' */ + strcpy(printable, name); + strcat(printable, " (Local)"); + } else { + printable = name; + } + + if (printable) { + UI_ThemeColor(TH_TEXT_HI); + glRasterPos2i(10, ar->winy-20); + BMF_DrawString(G.fonts, printable); + } + + if (v3d->localview) { + free(printable); + } +} + + +static char *get_cfra_marker_name(Scene *scene) +{ + ListBase *markers= &scene->markers; + TimeMarker *m1, *m2; + + /* search through markers for match */ + for (m1=markers->first, m2=markers->last; m1 && m2; m1=m1->next, m2=m2->prev) { + if (m1->frame==CFRA) + return m1->name; + + if (m1 == m2) + break; + + if (m2->frame==CFRA) + return m2->name; + } + + return NULL; +} + +/* draw info beside axes in bottom left-corner: +* framenum, object name, bone name (if available), marker name (if available) +*/ +static void draw_selected_name(Scene *scene, Object *ob, View3D *v3d) +{ + char info[256], *markern; + short offset=30; + + /* get name of marker on current frame (if available) */ + markern= get_cfra_marker_name(scene); + + /* check if there is an object */ + if(ob) { + /* name(s) to display depends on type of object */ + if(ob->type==OB_ARMATURE) { + bArmature *arm= ob->data; + char *name= NULL; + + /* show name of active bone too (if possible) */ + if(ob==G.obedit) { +// XXX EditBone *ebo; +// for (ebo=G.edbo.first; ebo; ebo=ebo->next){ +// if ((ebo->flag & BONE_ACTIVE) && (ebo->layer & arm->layer)) { +// name= ebo->name; +// break; +// } +// } + } + else if(ob->pose && (ob->flag & OB_POSEMODE)) { + bPoseChannel *pchan; + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if((pchan->bone->flag & BONE_ACTIVE) && (pchan->bone->layer & arm->layer)) { + name= pchan->name; + break; + } + } + } + if(name && markern) + sprintf(info, "(%d) %s %s <%s>", CFRA, ob->id.name+2, name, markern); + else if(name) + sprintf(info, "(%d) %s %s", CFRA, ob->id.name+2, name); + else + sprintf(info, "(%d) %s", CFRA, ob->id.name+2); + } + else if(ELEM3(ob->type, OB_MESH, OB_LATTICE, OB_CURVE)) { + Key *key= NULL; + KeyBlock *kb = NULL; + char shapes[75]; + + /* try to display active shapekey too */ + shapes[0] = 0; + key = ob_get_key(ob); + if(key){ + kb = BLI_findlink(&key->block, ob->shapenr-1); + if(kb){ + sprintf(shapes, ": %s ", kb->name); + if(ob->shapeflag == OB_SHAPE_LOCK){ + sprintf(shapes, "%s (Pinned)",shapes); + } + } + } + + if(markern) + sprintf(info, "(%d) %s %s <%s>", CFRA, ob->id.name+2, shapes, markern); + else + sprintf(info, "(%d) %s %s", CFRA, ob->id.name+2, shapes); + } + else { + /* standard object */ + if (markern) + sprintf(info, "(%d) %s <%s>", CFRA, ob->id.name+2, markern); + else + sprintf(info, "(%d) %s", CFRA, ob->id.name+2); + } + + /* colour depends on whether there is a keyframe */ +// XXX if (id_frame_has_keyframe((ID *)ob, frame_to_float(CFRA), v3d->keyflags)) +// UI_ThemeColor(TH_VERTEX_SELECT); +// else + UI_ThemeColor(TH_TEXT_HI); + } + else { + /* no object */ + if (markern) + sprintf(info, "(%d) <%s>", CFRA, markern); + else + sprintf(info, "(%d)", CFRA); + + /* colour is always white */ + UI_ThemeColor(TH_TEXT_HI); + } + + if (U.uiflag & USER_SHOW_ROTVIEWICON) + offset = 14 + (U.rvisize * 2); + + glRasterPos2i(offset, 10); + BMF_DrawString(G.fonts, info); +} + +static void view3d_get_viewborder_size(Scene *scene, ARegion *ar, float size_r[2]) +{ + float winmax= MAX2(ar->winx, ar->winy); + float aspect= (float) (scene->r.xsch*scene->r.xasp)/(scene->r.ysch*scene->r.yasp); + + if(aspect>1.0) { + size_r[0]= winmax; + size_r[1]= winmax/aspect; + } else { + size_r[0]= winmax*aspect; + size_r[1]= winmax; + } +} + +void calc_viewborder(Scene *scene, ARegion *ar, View3D *v3d, rctf *viewborder_r) +{ + float zoomfac, size[2]; + float dx= 0.0f, dy= 0.0f; + + view3d_get_viewborder_size(scene, ar, size); + + /* magic zoom calculation, no idea what + * it signifies, if you find out, tell me! -zr + */ + /* simple, its magic dude! + * well, to be honest, this gives a natural feeling zooming + * with multiple keypad presses (ton) + */ + + zoomfac= (M_SQRT2 + v3d->camzoom/50.0); + zoomfac= (zoomfac*zoomfac)*0.25; + + size[0]= size[0]*zoomfac; + size[1]= size[1]*zoomfac; + + /* center in window */ + viewborder_r->xmin= 0.5*ar->winx - 0.5*size[0]; + viewborder_r->ymin= 0.5*ar->winy - 0.5*size[1]; + viewborder_r->xmax= viewborder_r->xmin + size[0]; + viewborder_r->ymax= viewborder_r->ymin + size[1]; + + dx= ar->winx*v3d->camdx*zoomfac*2.0f; + dy= ar->winy*v3d->camdy*zoomfac*2.0f; + + /* apply offset */ + viewborder_r->xmin-= dx; + viewborder_r->ymin-= dy; + viewborder_r->xmax-= dx; + viewborder_r->ymax-= dy; + + if(v3d->camera && v3d->camera->type==OB_CAMERA) { + Camera *cam= v3d->camera->data; + float w = viewborder_r->xmax - viewborder_r->xmin; + float h = viewborder_r->ymax - viewborder_r->ymin; + float side = MAX2(w, h); + + viewborder_r->xmin+= cam->shiftx*side; + viewborder_r->xmax+= cam->shiftx*side; + viewborder_r->ymin+= cam->shifty*side; + viewborder_r->ymax+= cam->shifty*side; + } +} + +void view3d_set_1_to_1_viewborder(Scene *scene, ARegion *ar, View3D *v3d) +{ + float size[2]; + int im_width= (scene->r.size*scene->r.xsch)/100; + + view3d_get_viewborder_size(scene, ar, size); + + v3d->camzoom= (sqrt(4.0*im_width/size[0]) - M_SQRT2)*50.0; + v3d->camzoom= CLAMPIS(v3d->camzoom, -30, 300); +} + + +static void drawviewborder_flymode(ARegion *ar) +{ + /* draws 4 edge brackets that frame the safe area where the + mouse can move during fly mode without spinning the view */ + float x1, x2, y1, y2; + + x1= 0.45*(float)ar->winx; + y1= 0.45*(float)ar->winy; + x2= 0.55*(float)ar->winx; + y2= 0.55*(float)ar->winy; + cpack(0); + + + glBegin(GL_LINES); + /* bottom left */ + glVertex2f(x1,y1); + glVertex2f(x1,y1+5); + + glVertex2f(x1,y1); + glVertex2f(x1+5,y1); + + /* top right */ + glVertex2f(x2,y2); + glVertex2f(x2,y2-5); + + glVertex2f(x2,y2); + glVertex2f(x2-5,y2); + + /* top left */ + glVertex2f(x1,y2); + glVertex2f(x1,y2-5); + + glVertex2f(x1,y2); + glVertex2f(x1+5,y2); + + /* bottom right */ + glVertex2f(x2,y1); + glVertex2f(x2,y1+5); + + glVertex2f(x2,y1); + glVertex2f(x2-5,y1); + glEnd(); +} + + +static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) +{ + extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad); // interface_panel.c + float fac, a; + float x1, x2, y1, y2; + float x3, y3, x4, y4; + rctf viewborder; + Camera *ca= NULL; + + if(v3d->camera==NULL) + return; + if(v3d->camera->type==OB_CAMERA) + ca = v3d->camera->data; + + calc_viewborder(scene, ar, v3d, &viewborder); + x1= viewborder.xmin; + y1= viewborder.ymin; + x2= viewborder.xmax; + y2= viewborder.ymax; + + /* passepartout, specified in camera edit buttons */ + if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT) && ca->passepartalpha > 0.000001) { + if (ca->passepartalpha == 1.0) { + glColor3f(0, 0, 0); + } else { + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + glEnable(GL_BLEND); + glColor4f(0, 0, 0, ca->passepartalpha); + } + if (x1 > 0.0) + glRectf(0.0, (float)ar->winy, x1, 0.0); + if (x2 < (float)ar->winx) + glRectf(x2, (float)ar->winy, (float)ar->winx, 0.0); + if (y2 < (float)ar->winy) + glRectf(x1, (float)ar->winy, x2, y2); + if (y2 > 0.0) + glRectf(x1, y1, x2, 0.0); + + glDisable(GL_BLEND); + } + + /* edge */ + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + setlinestyle(0); + UI_ThemeColor(TH_BACK); + glRectf(x1, y1, x2, y2); + + setlinestyle(3); + UI_ThemeColor(TH_WIRE); + glRectf(x1, y1, x2, y2); + + /* camera name - draw in highlighted text color */ + if (ca && (ca->flag & CAM_SHOWNAME)) { + UI_ThemeColor(TH_TEXT_HI); + glRasterPos2f(x1, y1-15); + + BMF_DrawString(G.font, v3d->camera->id.name+2); + UI_ThemeColor(TH_WIRE); + } + + + /* border */ + if(scene->r.mode & R_BORDER) { + + cpack(0); + x3= x1+ scene->r.border.xmin*(x2-x1); + y3= y1+ scene->r.border.ymin*(y2-y1); + x4= x1+ scene->r.border.xmax*(x2-x1); + y4= y1+ scene->r.border.ymax*(y2-y1); + + cpack(0x4040FF); + glRectf(x3, y3, x4, y4); + } + + /* safety border */ + if (ca && (ca->flag & CAM_SHOWTITLESAFE)) { + fac= 0.1; + + a= fac*(x2-x1); + x1+= a; + x2-= a; + + a= fac*(y2-y1); + y1+= a; + y2-= a; + + UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0); + + uiSetRoundBox(15); + gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 12.0); + } + + setlinestyle(0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + +} + +static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d) +{ + BGpic *bgpic; + Image *ima; + ImBuf *ibuf= NULL; + float vec[4], fac, asp, zoomx, zoomy; + float x1, y1, x2, y2, cx, cy; + + bgpic= v3d->bgpic; + if(bgpic==NULL) return; + + ima= bgpic->ima; + + if(ima) + ibuf= BKE_image_get_ibuf(ima, &bgpic->iuser); + if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL) ) + return; + if(ibuf->channels!=4) + return; + if(ibuf->rect==NULL) + IMB_rect_from_float(ibuf); + + if(v3d->persp==2) { + rctf vb; + + calc_viewborder(scene, ar, v3d, &vb); + + x1= vb.xmin; + y1= vb.ymin; + x2= vb.xmax; + y2= vb.ymax; + } + else { + float sco[2]; + + /* calc window coord */ + initgrabz(v3d, 0.0, 0.0, 0.0); + window_to_3d(ar, v3d, vec, 1, 0); + fac= MAX3( fabs(vec[0]), fabs(vec[1]), fabs(vec[1]) ); + fac= 1.0/fac; + + asp= ( (float)ibuf->y)/(float)ibuf->x; + + vec[0] = vec[1] = vec[2] = 0.0; + view3d_project_float(ar, vec, sco, v3d->persmat); + cx = sco[0]; + cy = sco[1]; + + x1= cx+ fac*(bgpic->xof-bgpic->size); + y1= cy+ asp*fac*(bgpic->yof-bgpic->size); + x2= cx+ fac*(bgpic->xof+bgpic->size); + y2= cy+ asp*fac*(bgpic->yof+bgpic->size); + } + + /* complete clip? */ + + if(x2 < 0 ) return; + if(y2 < 0 ) return; + if(x1 > ar->winx ) return; + if(y1 > ar->winy ) return; + + zoomx= (x2-x1)/ibuf->x; + zoomy= (y2-y1)/ibuf->y; + + /* for some reason; zoomlevels down refuses to use GL_ALPHA_SCALE */ + if(zoomx < 1.0f || zoomy < 1.0f) { + float tzoom= MIN2(zoomx, zoomy); + int mip= 0; + + if(ibuf->mipmap[0]==NULL) + IMB_makemipmap(ibuf, 0); + + while(tzoom < 1.0f && mip<8 && ibuf->mipmap[mip]) { + tzoom*= 2.0f; + zoomx*= 2.0f; + zoomy*= 2.0f; + mip++; + } + if(mip>0) + ibuf= ibuf->mipmap[mip-1]; + } + + if(v3d->zbuf) glDisable(GL_DEPTH_TEST); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + glaDefine2DArea(&ar->winrct); + + glEnable(GL_BLEND); + + glPixelZoom(zoomx, zoomy); + glColor4f(1.0, 1.0, 1.0, 1.0-bgpic->blend); + glaDrawPixelsTex(x1, y1, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect); + + glPixelZoom(1.0, 1.0); + glPixelTransferf(GL_ALPHA_SCALE, 1.0f); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glDisable(GL_BLEND); + if(v3d->zbuf) glEnable(GL_DEPTH_TEST); + + // XXX areawinset(ar->win); // restore viewport / scissor +} + +void view3d_update_depths(ARegion *ar, View3D *v3d) +{ + /* Create storage for, and, if necessary, copy depth buffer */ + if(!v3d->depths) v3d->depths= MEM_callocN(sizeof(ViewDepths),"ViewDepths"); + if(v3d->depths) { + ViewDepths *d= v3d->depths; + if(d->w != ar->winx || + d->h != ar->winy || + !d->depths) { + d->w= ar->winx; + d->h= ar->winy; + if(d->depths) + MEM_freeN(d->depths); + d->depths= MEM_mallocN(sizeof(float)*d->w*d->h,"View depths"); + d->damaged= 1; + } + + if(d->damaged) { + glReadPixels(ar->winrct.xmin,ar->winrct.ymin,d->w,d->h, + GL_DEPTH_COMPONENT,GL_FLOAT, d->depths); + + glGetDoublev(GL_DEPTH_RANGE,d->depth_range); + + d->damaged= 0; + } + } +} + +/* Enable sculpting in wireframe mode by drawing sculpt object only to the depth buffer */ +static void draw_sculpt_depths(Scene *scene, View3D *v3d) +{ + Object *ob = OBACT; + + int dt= MIN2(v3d->drawtype, ob->dt); + if(v3d->zbuf==0 && dt>OB_WIRE) + dt= OB_WIRE; + if(dt == OB_WIRE) { + GLboolean depth_on; + int orig_vdt = v3d->drawtype; + int orig_zbuf = v3d->zbuf; + int orig_odt = ob->dt; + + glGetBooleanv(GL_DEPTH_TEST, &depth_on); + v3d->drawtype = ob->dt = OB_SOLID; + v3d->zbuf = 1; + + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glEnable(GL_DEPTH_TEST); +// XXX draw_object(BASACT, 0); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + if(!depth_on) + glDisable(GL_DEPTH_TEST); + + v3d->drawtype = orig_vdt; + v3d->zbuf = orig_zbuf; + ob->dt = orig_odt; + } +} + + +void drawview3dspace(const bContext *C, ARegion *ar, View3D *v3d) +{ + Base *base; + Object *ob; + Scene *scene= CTX_data_scene(C), *sce; + char retopo= 0, sculptparticle= 0; + Object *obact = OBACT; + + /* update all objects, ipos, matrices, displists, etc. Flags set by depgraph or manual, + no layer check here, gets correct flushed */ + /* sets first, we allow per definition current scene to have dependencies on sets */ + if(scene->set) { + for(SETLOOPER(scene->set, base)) + object_handle_update(base->object); // bke_object.h + } + + v3d->lay_used = 0; + for(base= scene->base.first; base; base= base->next) { + object_handle_update(base->object); // bke_object.h + v3d->lay_used |= base->lay; + } + + /* shadow buffers, before we setup matrices */ +// if(draw_glsl_material(NULL, v3d->drawtype)) +// gpu_update_lamps_shadows(scene, v3d); + + setwinmatrixview3d(CTX_wm_window(C), v3d, ar->winx, ar->winy, NULL); /* 0= no pick rect */ + setviewmatrixview3d(v3d); /* note: calls where_is_object for camera... */ + + Mat4MulMat4(v3d->persmat, v3d->viewmat, v3d->winmat); + Mat4Invert(v3d->persinv, v3d->persmat); + Mat4Invert(v3d->viewinv, v3d->viewmat); + + /* calculate pixelsize factor once, is used for lamps and obcenters */ + { + float len1, len2, vec[3]; + + VECCOPY(vec, v3d->persinv[0]); + len1= Normalize(vec); + VECCOPY(vec, v3d->persinv[1]); + len2= Normalize(vec); + + v3d->pixsize= 2.0f*(len1>len2?len1:len2); + + /* correct for window size */ + if(ar->winx > ar->winy) v3d->pixsize/= (float)ar->winx; + else v3d->pixsize/= (float)ar->winy; + } + + if(v3d->drawtype > OB_WIRE) { + float col[3]; + UI_GetThemeColor3fv(TH_BACK, col); + glClearColor(col[0], col[1], col[2], 0.0); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glLoadIdentity(); + } + else { + float col[3]; + UI_GetThemeColor3fv(TH_BACK, col); + glClearColor(col[0], col[1], col[2], 0.0); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + } + + wmLoadMatrix(CTX_wm_window(C), v3d->viewmat); + + if(v3d->flag & V3D_CLIPPING) + view3d_draw_clipping(v3d); + + /* set zbuffer after we draw clipping region */ + if(v3d->drawtype > OB_WIRE) { + v3d->zbuf= TRUE; + glEnable(GL_DEPTH_TEST); + } + + // needs to be done always, gridview is adjusted in drawgrid() now + v3d->gridview= v3d->grid; + + if(v3d->view==0 || v3d->persp!=0) { + drawfloor(v3d); + if(v3d->persp==2) { + if(scene->world) { + if(scene->world->mode & WO_STARS) { + RE_make_stars(NULL, star_stuff_init_func, star_stuff_vertex_func, + star_stuff_term_func); + } + } + if(v3d->flag & V3D_DISPBGPIC) draw_bgpic(scene, ar, v3d); + } + } + else { + ED_region_pixelspace(C, ar); + drawgrid(ar, v3d); + /* XXX make function? replaces persp(1) */ + glMatrixMode(GL_PROJECTION); + wmLoadMatrix(CTX_wm_window(C), v3d->winmat); + glMatrixMode(GL_MODELVIEW); + wmLoadMatrix(CTX_wm_window(C), v3d->viewmat); + + if(v3d->flag & V3D_DISPBGPIC) { + draw_bgpic(scene, ar, v3d); + } + } + + if(v3d->flag & V3D_CLIPPING) + view3d_set_clipping(v3d); + + /* draw set first */ + if(scene->set) { + for(SETLOOPER(scene->set, base)) { + + if(v3d->lay & base->lay) { + + UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f); +// XXX draw_object(base, DRAW_CONSTCOLOR|DRAW_SCENESET); + + if(base->object->transflag & OB_DUPLI) { +// XXX draw_dupli_objects_color(v3d, base, TH_WIRE); + } + } + } + + /* Transp and X-ray afterdraw stuff for sets is done later */ + } + + /* then draw not selected and the duplis, but skip editmode object */ + for(base= scene->base.first; base; base= base->next) { + if(v3d->lay & base->lay) { + + /* dupli drawing */ + if(base->object->transflag & OB_DUPLI) { +// XXX draw_dupli_objects(v3d, base); + } + if((base->flag & SELECT)==0) { +// XXX if(base->object!=G.obedit) draw_object(base, 0); + } + } + } + +// retopo= retopo_mesh_check() || retopo_curve_check(); +// sculptparticle= (G.f & (G_SCULPTMODE|G_PARTICLEEDIT)) && !G.obedit; + if(retopo) + view3d_update_depths(ar, v3d); + + /* draw selected and editmode */ + for(base= scene->base.first; base; base= base->next) { + if(v3d->lay & base->lay) { +// if (base->object==G.obedit || ( base->flag & SELECT) ) +// XXX draw_object(base, 0); + } + } + + if(!retopo && sculptparticle && !(obact && (obact->dtx & OB_DRAWXRAY))) { + if(G.f & G_SCULPTMODE) + draw_sculpt_depths(scene, v3d); + view3d_update_depths(ar, v3d); + } + + if(G.moving) { +// BIF_drawConstraint(); +// if(G.obedit || (G.f & G_PARTICLEEDIT)) +// BIF_drawPropCircle(); // only editmode and particles have proportional edit +// BIF_drawSnap(); + } + +// REEB_draw(); + +// if(scene->radio) RAD_drawall(v3d->drawtype>=OB_SOLID); + + /* Transp and X-ray afterdraw stuff */ +// view3d_draw_transp(v3d); +// view3d_draw_xray(v3d, 1); // clears zbuffer if it is used! + + if(!retopo && sculptparticle && (obact && (OBACT->dtx & OB_DRAWXRAY))) { + if(G.f & G_SCULPTMODE) + draw_sculpt_depths(scene, v3d); + view3d_update_depths(ar, v3d); + } + + if(v3d->flag & V3D_CLIPPING) + view3d_clr_clipping(); + +// BIF_draw_manipulator(ar); + + if(v3d->zbuf) { + v3d->zbuf= FALSE; + glDisable(GL_DEPTH_TEST); + } + + /* draw grease-pencil stuff */ +// if (v3d->flag2 & V3D_DISPGP) +// draw_gpencil_3dview(ar, 1); + + ED_region_pixelspace(C, ar); + + /* Draw Sculpt Mode brush XXX (removed) */ + +// retopo_paint_view_update(v3d); +// retopo_draw_paint_lines(); + + /* Draw particle edit brush XXX (removed) */ + + if(v3d->persp>1) drawviewborder(scene, ar, v3d); + if(v3d->flag2 & V3D_FLYMODE) drawviewborder_flymode(ar); + + /* draw grease-pencil stuff */ +// if (v3d->flag2 & V3D_DISPGP) +// draw_gpencil_3dview(ar, 0); + + if(!(G.f & G_PLAYANIM)) drawcursor(scene, ar, v3d); + if(U.uiflag & USER_SHOW_ROTVIEWICON) + draw_view_axis(v3d); + else + draw_view_icon(v3d); + + /* XXX removed viewport fps */ + if(U.uiflag & USER_SHOW_VIEWPORTNAME) { + draw_viewport_name(ar, v3d); + } + + ob= OBACT; + if(U.uiflag & USER_DRAWVIEWINFO) + draw_selected_name(scene, ob, v3d); + +// draw_area_emboss(ar); + + /* XXX here was the blockhandlers for floating panels */ + + if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT || G.f & G_TEXTUREPAINT) { + v3d->flag |= V3D_NEEDBACKBUFDRAW; + // XXX addafterqueue(ar->win, BACKBUFDRAW, 1); + } + // test for backbuf select + if(G.obedit && v3d->drawtype>OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT)) { + + v3d->flag |= V3D_NEEDBACKBUFDRAW; + // XXX if(afterqtest(ar->win, BACKBUFDRAW)==0) { + // addafterqueue(ar->win, BACKBUFDRAW, 1); + //} + } + +#ifndef DISABLE_PYTHON + /* XXX here was scriptlink */ +#endif +} + + diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 40c30269d87..d0e49373562 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -38,9 +38,40 @@ typedef struct ViewDepths { char damaged; } ViewDepths; +/* drawing flags: */ +#define DRAW_PICKING 1 +#define DRAW_CONSTCOLOR 2 +#define DRAW_SCENESET 4 + +/* project short */ +#define IS_CLIPPED 12000 + /* view3d_header.c */ void view3d_header_buttons(const bContext *C, ARegion *ar); +/* view3d_draw.c */ +void drawview3dspace(const bContext *C, ARegion *ar, View3D *v3d); +int view3d_test_clipping(View3D *v3d, float *vec); +void circf(float x, float y, float rad); +void circ(float x, float y, float rad); +void view3d_update_depths(ARegion *ar, View3D *v3d); + +/* view3d_view.c */ +float *give_cursor(Scene *scene, View3D *v3d); +void initgrabz(View3D *v3d, float x, float y, float z); +void window_to_3d(ARegion *ar, View3D *v3d, float *vec, short mx, short my); +void view3d_project_float(ARegion *a, float *vec, float *adr, float mat[4][4]); +void project_short(ARegion *ar, View3D *v3d, float *vec, short *adr); +void project_int(ARegion *ar, View3D *v3d, float *vec, int *adr); +void project_int_noclip(ARegion *ar, View3D *v3d, float *vec, int *adr); +void project_short_noclip(ARegion *ar, View3D *v3d, float *vec, short *adr); +void project_float(ARegion *ar, View3D *v3d, float *vec, float *adr); +void project_float_noclip(ARegion *ar, View3D *v3d, float *vec, float *adr); +int get_view3d_viewplane(View3D *v3d, int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize); + + +void setwinmatrixview3d(wmWindow *win, View3D *v3d, int winx, int winy, rctf *rect); /* rect: for picking */ +void setviewmatrixview3d(View3D *v3d); #endif /* ED_VIEW3D_INTERN_H */ diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c new file mode 100644 index 00000000000..26566ec7b8a --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -0,0 +1,714 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <string.h> +#include <stdio.h> +#include <math.h> +#include <float.h> + +#include "DNA_action_types.h" +#include "DNA_camera_types.h" +#include "DNA_lamp_types.h" +#include "DNA_object_types.h" +#include "DNA_space_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_userdef_types.h" +#include "DNA_view3d_types.h" +#include "DNA_world_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_rand.h" + +#include "BKE_action.h" +#include "BKE_context.h" +#include "BKE_object.h" +#include "BKE_global.h" +#include "BKE_scene.h" +#include "BKE_screen.h" +#include "BKE_utildefines.h" + +#include "RE_pipeline.h" // make_stars + +#include "BIF_gl.h" + +#include "WM_api.h" + +#include "ED_screen.h" + +#include "UI_interface.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "PIL_time.h" /* smoothview */ + +#include "view3d_intern.h" // own include + + +float *give_cursor(Scene *scene, View3D *v3d) +{ + if(v3d && v3d->localview) return v3d->cursor; + else return scene->cursor; +} + + + +void initgrabz(View3D *v3d, float x, float y, float z) +{ + if(v3d==NULL) return; + v3d->zfac= v3d->persmat[0][3]*x+ v3d->persmat[1][3]*y+ v3d->persmat[2][3]*z+ v3d->persmat[3][3]; + + /* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that + * (accounting for near zero values) + * */ + if (v3d->zfac < 1.e-6f && v3d->zfac > -1.e-6f) v3d->zfac = 1.0f; + + /* Negative zfac means x, y, z was behind the camera (in perspective). + * This gives flipped directions, so revert back to ok default case. + */ + if (v3d->zfac < 0.0f) v3d->zfac = 1.0f; +} + +void window_to_3d(ARegion *ar, View3D *v3d, float *vec, short mx, short my) +{ + /* always call initgrabz */ + float dx, dy; + + dx= 2.0f*mx*v3d->zfac/ar->winx; + dy= 2.0f*my*v3d->zfac/ar->winy; + + vec[0]= (v3d->persinv[0][0]*dx + v3d->persinv[1][0]*dy); + vec[1]= (v3d->persinv[0][1]*dx + v3d->persinv[1][1]*dy); + vec[2]= (v3d->persinv[0][2]*dx + v3d->persinv[1][2]*dy); +} + +void view3d_project_float(ARegion *ar, float *vec, float *adr, float mat[4][4]) +{ + float vec4[4]; + + adr[0]= IS_CLIPPED; + VECCOPY(vec4, vec); + vec4[3]= 1.0; + + Mat4MulVec4fl(mat, vec4); + + if( vec4[3]>FLT_EPSILON ) { + adr[0] = (float)(ar->winx/2.0f)+(ar->winx/2.0f)*vec4[0]/vec4[3]; + adr[1] = (float)(ar->winy/2.0f)+(ar->winy/2.0f)*vec4[1]/vec4[3]; + } else { + adr[0] = adr[1] = 0.0f; + } +} + + +#define BL_NEAR_CLIP 0.001 + +void project_short(ARegion *ar, View3D *v3d, float *vec, short *adr) /* clips */ +{ + float fx, fy, vec4[4]; + + adr[0]= IS_CLIPPED; + + if(v3d->flag & V3D_CLIPPING) { + if(view3d_test_clipping(v3d, vec)) + return; + } + + VECCOPY(vec4, vec); + vec4[3]= 1.0; + Mat4MulVec4fl(v3d->persmat, vec4); + + if( vec4[3]>BL_NEAR_CLIP ) { /* 0.001 is the NEAR clipping cutoff for picking */ + fx= (ar->winx/2)*(1 + vec4[0]/vec4[3]); + + if( fx>0 && fx<ar->winx) { + + fy= (ar->winy/2)*(1 + vec4[1]/vec4[3]); + + if(fy>0.0 && fy< (float)ar->winy) { + adr[0]= (short)floor(fx); + adr[1]= (short)floor(fy); + } + } + } +} + +void project_int(ARegion *ar, View3D *v3d, float *vec, int *adr) +{ + float fx, fy, vec4[4]; + + adr[0]= (int)2140000000.0f; + VECCOPY(vec4, vec); + vec4[3]= 1.0; + + Mat4MulVec4fl(v3d->persmat, vec4); + + if( vec4[3]>BL_NEAR_CLIP ) { /* 0.001 is the NEAR clipping cutoff for picking */ + fx= (ar->winx/2)*(1 + vec4[0]/vec4[3]); + + if( fx>-2140000000.0f && fx<2140000000.0f) { + fy= (ar->winy/2)*(1 + vec4[1]/vec4[3]); + + if(fy>-2140000000.0f && fy<2140000000.0f) { + adr[0]= (int)floor(fx); + adr[1]= (int)floor(fy); + } + } + } +} + +void project_int_noclip(ARegion *ar, View3D *v3d, float *vec, int *adr) +{ + float fx, fy, vec4[4]; + + VECCOPY(vec4, vec); + vec4[3]= 1.0; + + Mat4MulVec4fl(v3d->persmat, vec4); + + if( fabs(vec4[3]) > BL_NEAR_CLIP ) { + fx = (ar->winx/2)*(1 + vec4[0]/vec4[3]); + fy = (ar->winy/2)*(1 + vec4[1]/vec4[3]); + + adr[0] = (int)floor(fx); + adr[1] = (int)floor(fy); + } + else + { + adr[0] = ar->winx / 2; + adr[1] = ar->winy / 2; + } +} + +void project_short_noclip(ARegion *ar, View3D *v3d, float *vec, short *adr) +{ + float fx, fy, vec4[4]; + + adr[0]= IS_CLIPPED; + VECCOPY(vec4, vec); + vec4[3]= 1.0; + + Mat4MulVec4fl(v3d->persmat, vec4); + + if( vec4[3]>BL_NEAR_CLIP ) { /* 0.001 is the NEAR clipping cutoff for picking */ + fx= (ar->winx/2)*(1 + vec4[0]/vec4[3]); + + if( fx>-32700 && fx<32700) { + + fy= (ar->winy/2)*(1 + vec4[1]/vec4[3]); + + if(fy>-32700.0 && fy<32700.0) { + adr[0]= (short)floor(fx); + adr[1]= (short)floor(fy); + } + } + } +} + +void project_float(ARegion *ar, View3D *v3d, float *vec, float *adr) +{ + float vec4[4]; + + adr[0]= IS_CLIPPED; + VECCOPY(vec4, vec); + vec4[3]= 1.0; + + Mat4MulVec4fl(v3d->persmat, vec4); + + if( vec4[3]>BL_NEAR_CLIP ) { + adr[0] = (float)(ar->winx/2.0)+(ar->winx/2.0)*vec4[0]/vec4[3]; + adr[1] = (float)(ar->winy/2.0)+(ar->winy/2.0)*vec4[1]/vec4[3]; + } +} + +void project_float_noclip(ARegion *ar, View3D *v3d, float *vec, float *adr) +{ + float vec4[4]; + + VECCOPY(vec4, vec); + vec4[3]= 1.0; + + Mat4MulVec4fl(v3d->persmat, vec4); + + if( fabs(vec4[3]) > BL_NEAR_CLIP ) { + adr[0] = (float)(ar->winx/2.0)+(ar->winx/2.0)*vec4[0]/vec4[3]; + adr[1] = (float)(ar->winy/2.0)+(ar->winy/2.0)*vec4[1]/vec4[3]; + } + else + { + adr[0] = ar->winx / 2.0f; + adr[1] = ar->winy / 2.0f; + } +} + + + +/* also exposed in previewrender.c */ +int get_view3d_viewplane(View3D *v3d, int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize) +{ + Camera *cam=NULL; + float lens, fac, x1, y1, x2, y2; + float winx= (float)winxi, winy= (float)winyi; + int orth= 0; + + lens= v3d->lens; + + *clipsta= v3d->near; + *clipend= v3d->far; + + if(v3d->persp==V3D_CAMOB) { + if(v3d->camera) { + if(v3d->camera->type==OB_LAMP ) { + Lamp *la; + + la= v3d->camera->data; + fac= cos( M_PI*la->spotsize/360.0); + + x1= saacos(fac); + lens= 16.0*fac/sin(x1); + + *clipsta= la->clipsta; + *clipend= la->clipend; + } + else if(v3d->camera->type==OB_CAMERA) { + cam= v3d->camera->data; + lens= cam->lens; + *clipsta= cam->clipsta; + *clipend= cam->clipend; + } + } + } + + if(v3d->persp==V3D_ORTHO) { + if(winx>winy) x1= -v3d->dist; + else x1= -winx*v3d->dist/winy; + x2= -x1; + + if(winx>winy) y1= -winy*v3d->dist/winx; + else y1= -v3d->dist; + y2= -y1; + + *clipend *= 0.5; // otherwise too extreme low zbuffer quality + *clipsta= - *clipend; + orth= 1; + } + else { + /* fac for zoom, also used for camdx */ + if(v3d->persp==V3D_CAMOB) { + fac= (1.41421+( (float)v3d->camzoom )/50.0); + fac*= fac; + } + else fac= 2.0; + + /* viewplane size depends... */ + if(cam && cam->type==CAM_ORTHO) { + /* ortho_scale == 1 means exact 1 to 1 mapping */ + float dfac= 2.0*cam->ortho_scale/fac; + + if(winx>winy) x1= -dfac; + else x1= -winx*dfac/winy; + x2= -x1; + + if(winx>winy) y1= -winy*dfac/winx; + else y1= -dfac; + y2= -y1; + orth= 1; + } + else { + float dfac; + + if(winx>winy) dfac= 64.0/(fac*winx*lens); + else dfac= 64.0/(fac*winy*lens); + + x1= - *clipsta * winx*dfac; + x2= -x1; + y1= - *clipsta * winy*dfac; + y2= -y1; + orth= 0; + } + /* cam view offset */ + if(cam) { + float dx= 0.5*fac*v3d->camdx*(x2-x1); + float dy= 0.5*fac*v3d->camdy*(y2-y1); + x1+= dx; + x2+= dx; + y1+= dy; + y2+= dy; + } + } + + if(pixsize) { + float viewfac; + + if(orth) { + viewfac= (winx >= winy)? winx: winy; + *pixsize= 1.0f/viewfac; + } + else { + viewfac= (((winx >= winy)? winx: winy)*lens)/32.0; + *pixsize= *clipsta/viewfac; + } + } + + viewplane->xmin= x1; + viewplane->ymin= y1; + viewplane->xmax= x2; + viewplane->ymax= y2; + + return orth; +} + + +/* important to not set windows active in here, can be renderwin for example */ +void setwinmatrixview3d(wmWindow *win, View3D *v3d, int winx, int winy, rctf *rect) /* rect: for picking */ +{ + rctf viewplane; + float clipsta, clipend, x1, y1, x2, y2; + int orth; + + orth= get_view3d_viewplane(v3d, winx, winy, &viewplane, &clipsta, &clipend, NULL); + // printf("%d %d %f %f %f %f %f %f\n", winx, winy, viewplane.xmin, viewplane.ymin, viewplane.xmax, viewplane.ymax, clipsta, clipend); + x1= viewplane.xmin; + y1= viewplane.ymin; + x2= viewplane.xmax; + y2= viewplane.ymax; + + if(rect) { /* picking */ + rect->xmin/= (float)winx; + rect->xmin= x1+rect->xmin*(x2-x1); + rect->ymin/= (float)winy; + rect->ymin= y1+rect->ymin*(y2-y1); + rect->xmax/= (float)winx; + rect->xmax= x1+rect->xmax*(x2-x1); + rect->ymax/= (float)winy; + rect->ymax= y1+rect->ymax*(y2-y1); + + if(orth) wmOrtho(win, rect->xmin, rect->xmax, rect->ymin, rect->ymax, -clipend, clipend); + else wmFrustum(win, rect->xmin, rect->xmax, rect->ymin, rect->ymax, clipsta, clipend); + + } + else { + if(orth) wmOrtho(win, x1, x2, y1, y2, clipsta, clipend); + else wmFrustum(win, x1, x2, y1, y2, clipsta, clipend); + } + + /* not sure what this was for? (ton) */ + glMatrixMode(GL_PROJECTION); + wmGetMatrix(win, v3d->winmat); + glMatrixMode(GL_MODELVIEW); +} + + +/* SMOOTHVIEW */ +void smooth_view(View3D *v3d, float *ofs, float *quat, float *dist, float *lens) +{ + /* View Animation enabled */ + if (U.smooth_viewtx) { + int i; + char changed = 0; + float step = 0.0, step_inv; + float orig_dist; + float orig_lens; + 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 (lens) { + if ((*lens) != v3d->lens) + 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 the 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; + orig_lens = v3d->lens; + + 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 = (float)pow(step*2, 2)/2; + else step = (float)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); + + if (lens) + v3d->lens = ((*lens)*step) + (orig_lens*step_inv); + + /*redraw the view*/ +// scrarea_do_windraw(ar); +// 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; + if (lens) + v3d->lens = *lens; + +} + + + +/* Gets the lens and clipping values from a camera of lamp type object */ +void object_view_settings(Object *ob, float *lens, float *clipsta, float *clipend) +{ + if (!ob) return; + + if(ob->type==OB_LAMP ) { + Lamp *la = ob->data; + if (lens) { + float x1, fac; + fac= cos( M_PI*la->spotsize/360.0); + x1= saacos(fac); + *lens= 16.0*fac/sin(x1); + } + if (clipsta) *clipsta= la->clipsta; + if (clipend) *clipend= la->clipend; + } + else if(ob->type==OB_CAMERA) { + Camera *cam= ob->data; + if (lens) *lens= cam->lens; + if (clipsta) *clipsta= cam->clipsta; + if (clipend) *clipend= cam->clipend; + } +} + + +/* Gets the view trasnformation from a camera +* currently dosnt take camzoom into account +* +* The dist is not modified for this function, if NULL its assimed zero +* */ +void view_settings_from_ob(Object *ob, float *ofs, float *quat, float *dist, float *lens) +{ + float bmat[4][4]; + float imat[4][4]; + float tmat[3][3]; + + if (!ob) return; + + /* Offset */ + if (ofs) { + where_is_object(ob); + VECCOPY(ofs, ob->obmat[3]); + VecMulf(ofs, -1.0f); /*flip the vector*/ + } + + /* Quat */ + if (quat) { + Mat4CpyMat4(bmat, ob->obmat); + Mat4Ortho(bmat); + Mat4Invert(imat, bmat); + Mat3CpyMat4(tmat, imat); + Mat3ToQuat(tmat, quat); + } + + if (dist) { + float vec[3]; + Mat3CpyMat4(tmat, ob->obmat); + + vec[0]= vec[1] = 0.0; + vec[2]= -(*dist); + Mat3MulVecfl(tmat, vec); + VecSubf(ofs, ofs, vec); + } + + /* Lens */ + if (lens) + object_view_settings(ob, lens, NULL, NULL); +} + + +void obmat_to_viewmat(View3D *v3d, Object *ob, short smooth) +{ + float bmat[4][4]; + float tmat[3][3]; + + v3d->view= 0; /* dont show the grid */ + + Mat4CpyMat4(bmat, ob->obmat); + Mat4Ortho(bmat); + Mat4Invert(v3d->viewmat, bmat); + + /* view quat calculation, needed for add object */ + Mat3CpyMat4(tmat, v3d->viewmat); + if (smooth) { + float new_quat[4]; + if (v3d->persp==V3D_CAMOB && v3d->camera) { + /* were from a camera view */ + + float orig_ofs[3]; + float orig_dist= v3d->dist; + float orig_lens= v3d->lens; + VECCOPY(orig_ofs, v3d->ofs); + + /* Switch from camera view */ + Mat3ToQuat(tmat, new_quat); + + v3d->persp=V3D_PERSP; + v3d->dist= 0.0; + + view_settings_from_ob(v3d->camera, v3d->ofs, NULL, NULL, &v3d->lens); + smooth_view(v3d, orig_ofs, new_quat, &orig_dist, &orig_lens); + + v3d->persp=V3D_CAMOB; /* just to be polite, not needed */ + + } else { + Mat3ToQuat(tmat, new_quat); + smooth_view(v3d, NULL, new_quat, NULL, NULL); + } + } else { + Mat3ToQuat(tmat, v3d->viewquat); + } +} + +/* dont set windows active in in here, is used by renderwin too */ +void setviewmatrixview3d(View3D *v3d) +{ + if(v3d->persp==V3D_CAMOB) { /* obs/camera */ + if(v3d->camera) { + where_is_object(v3d->camera); + obmat_to_viewmat(v3d, v3d->camera, 0); + } + else { + QuatToMat4(v3d->viewquat, v3d->viewmat); + v3d->viewmat[3][2]-= v3d->dist; + } + } + else { + + QuatToMat4(v3d->viewquat, v3d->viewmat); + if(v3d->persp==V3D_PERSP) v3d->viewmat[3][2]-= v3d->dist; + if(v3d->ob_centre) { + Object *ob= v3d->ob_centre; + float vec[3]; + + VECCOPY(vec, ob->obmat[3]); + if(ob->type==OB_ARMATURE && v3d->ob_centre_bone[0]) { + bPoseChannel *pchan= get_pose_channel(ob->pose, v3d->ob_centre_bone); + if(pchan) { + VECCOPY(vec, pchan->pose_mat[3]); + Mat4MulVecfl(ob->obmat, vec); + } + } + i_translate(-vec[0], -vec[1], -vec[2], v3d->viewmat); + } + else i_translate(v3d->ofs[0], v3d->ofs[1], v3d->ofs[2], v3d->viewmat); + } +} + +void setcameratoview3d(View3D *v3d) +{ + Object *ob; + float dvec[3]; + + ob= v3d->camera; + dvec[0]= v3d->dist*v3d->viewinv[2][0]; + dvec[1]= v3d->dist*v3d->viewinv[2][1]; + dvec[2]= v3d->dist*v3d->viewinv[2][2]; + VECCOPY(ob->loc, dvec); + VecSubf(ob->loc, ob->loc, v3d->ofs); + v3d->viewquat[0]= -v3d->viewquat[0]; + /* */ + /*if (ob->transflag & OB_QUAT) { + QUATCOPY(ob->quat, v3d->viewquat); + } else {*/ + QuatToEul(v3d->viewquat, ob->rot); + /*}*/ + v3d->viewquat[0]= -v3d->viewquat[0]; +} diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index d281c1e5213..d28a74a9f5c 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -78,14 +78,12 @@ typedef struct View3D { short blockhandler[8]; + float winmat[4][4]; float viewmat[4][4]; float viewinv[4][4]; float persmat[4][4]; float persinv[4][4]; - float winmat1[4][4]; // persp(1) storage, for swap matrices - float viewmat1[4][4]; - float viewquat[4], dist, zfac; /* zfac is initgrabz() result */ int lay_used; /* used while drawing */ |