diff options
Diffstat (limited to 'source/blender/editors/space_view3d')
-rw-r--r-- | source/blender/editors/space_view3d/Makefile | 5 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawarmature.c | 121 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawmesh.c | 101 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 1288 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawvolume.c | 1 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 189 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_buttons.c | 139 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 9 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_edit.c | 305 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_header.c | 72 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_intern.h | 20 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_ops.c | 108 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_select.c | 13 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_toolbar.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_view.c | 874 |
15 files changed, 2432 insertions, 817 deletions
diff --git a/source/blender/editors/space_view3d/Makefile b/source/blender/editors/space_view3d/Makefile index 07102157854..9204f2482c6 100644 --- a/source/blender/editors/space_view3d/Makefile +++ b/source/blender/editors/space_view3d/Makefile @@ -53,6 +53,9 @@ CPPFLAGS += -I../../render/extern/include CPPFLAGS += -I../../blenfont CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I$(NAN_SMOKE)/include -# own include +ifneq ($(NAN_NO_KETSJI),true) + CPPFLAGS += -I../../../kernel/gen_system +endif +# own include CPPFLAGS += -I../include diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index fa810677fe8..26135cd8d31 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -639,7 +639,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag /* figure out the sizes of spheres */ if (ebone) { - /* this routine doesn't call set_matrix_editbone() that calculates it */ + /* this routine doesn't call get_matrix_editbone() that calculates it */ ebone->length = VecLenf(ebone->head, ebone->tail); length= ebone->length; @@ -749,7 +749,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag, /* figure out the sizes of spheres */ if (ebone) { - /* this routine doesn't call set_matrix_editbone() that calculates it */ + /* this routine doesn't call get_matrix_editbone() that calculates it */ ebone->length = VecLenf(ebone->head, ebone->tail); length= ebone->length; @@ -1516,15 +1516,25 @@ static void draw_pose_dofs(Object *ob) } } +static void bone_matrix_translate_y(float mat[][4], float y) +{ + float trans[3]; + + VECCOPY(trans, mat[1]); + VecMulf(trans, y); + VecAddf(mat[3], mat[3], trans); +} + /* assumes object is Armature with pose */ -static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt) +static void draw_pose_channels(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt) { + RegionView3D *rv3d= ar->regiondata; Object *ob= base->object; bArmature *arm= ob->data; bPoseChannel *pchan; Bone *bone; GLfloat tmp; - float smat[4][4], imat[4][4]; + float smat[4][4], imat[4][4], bmat[4][4]; int index= -1; short do_dashed= 3, draw_wire= 0; short flag, constflag; @@ -1644,6 +1654,7 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba /* prepare colors */ if (arm->flag & ARM_POSEMODE) set_pchan_colorset(ob, pchan); +#if 0 // XXX - 13 October 2009, Disabled this to make ghosting show the right colors (Aligorith) else { if ((scene->basact)==base) { if (base->flag & (SELECT+BA_WAS_SEL)) UI_ThemeColor(TH_ACTIVE); @@ -1654,6 +1665,7 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba else UI_ThemeColor(TH_WIRE); } } +#endif /* catch exception for bone with hidden parent */ flag= bone->flag; @@ -1745,7 +1757,7 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba /* extra draw service for pose mode */ constflag= pchan->constflag; - if (pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) // XXX this is useless crap + if (pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) constflag |= PCHAN_HAS_ACTION; if (pchan->flag & POSE_STRIDE) constflag |= PCHAN_HAS_STRIDE; @@ -1809,15 +1821,21 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba /* Draw names of bone */ if (arm->flag & ARM_DRAWNAMES) { VecMidf(vec, pchan->pose_head, pchan->pose_tail); - view3d_object_text_draw_add(vec[0], vec[1], vec[2], pchan->name, 10); + view3d_cached_text_draw_add(vec[0], vec[1], vec[2], pchan->name, 10); } /* Draw additional axes on the bone tail */ if ( (arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE) ) { glPushMatrix(); - glMultMatrixf(pchan->pose_mat); - glTranslatef(0.0f, pchan->bone->length, 0.0f); - drawaxes(0.25f*pchan->bone->length, 0, OB_ARROWS); + Mat4CpyMat4(bmat, pchan->pose_mat); + bone_matrix_translate_y(bmat, pchan->bone->length); + glMultMatrixf(bmat); + + /* do cached text draw immediate to include transform */ + view3d_cached_text_draw_begin(); + drawaxes(pchan->bone->length*0.25f, 0, OB_ARROWS); + view3d_cached_text_draw_end(v3d, ar, 1, bmat); + glPopMatrix(); } } @@ -1830,32 +1848,28 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba } /* in editmode, we don't store the bone matrix... */ -static void set_matrix_editbone(EditBone *eBone) +static void get_matrix_editbone(EditBone *eBone, float bmat[][4]) { - float delta[3],offset[3]; - float mat[3][3], bmat[4][4]; + float delta[3]; + float mat[3][3]; /* Compose the parent transforms (i.e. their translations) */ - VECCOPY(offset, eBone->head); - - glTranslatef(offset[0],offset[1],offset[2]); - VecSubf(delta, eBone->tail, eBone->head); eBone->length = (float)sqrt(delta[0]*delta[0] + delta[1]*delta[1] +delta[2]*delta[2]); vec_roll_to_mat3(delta, eBone->roll, mat); Mat4CpyMat3(bmat, mat); - - glMultMatrixf(bmat); - + + VecAddf(bmat[3], bmat[3], eBone->head); } -static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt) +static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt) { + RegionView3D *rv3d= ar->regiondata; EditBone *eBone; bArmature *arm= ob->data; - float smat[4][4], imat[4][4]; + float smat[4][4], imat[4][4], bmat[4][4]; unsigned int index; int flag; @@ -1893,7 +1907,8 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt) if (eBone->layer & arm->layer) { if ((eBone->flag & BONE_HIDDEN_A)==0) { glPushMatrix(); - set_matrix_editbone(eBone); + get_matrix_editbone(eBone, bmat); + glMultMatrixf(bmat); /* catch exception for bone with hidden parent */ flag= eBone->flag; @@ -1941,7 +1956,8 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt) } else { glPushMatrix(); - set_matrix_editbone(eBone); + get_matrix_editbone(eBone, bmat); + glMultMatrixf(bmat); if (arm->drawtype == ARM_LINE) draw_line_bone(arm->flag, flag, 0, index, NULL, eBone); @@ -1994,14 +2010,20 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt) if (arm->flag & ARM_DRAWNAMES) { VecMidf(vec, eBone->head, eBone->tail); glRasterPos3fv(vec); - view3d_object_text_draw_add(vec[0], vec[1], vec[2], eBone->name, 10); + view3d_cached_text_draw_add(vec[0], vec[1], vec[2], eBone->name, 10); } /* Draw additional axes */ if (arm->flag & ARM_DRAWAXES) { glPushMatrix(); - set_matrix_editbone(eBone); - glTranslatef(0.0f, eBone->length, 0.0f); + get_matrix_editbone(eBone, bmat); + bone_matrix_translate_y(bmat, eBone->length); + glMultMatrixf(bmat); + + /* do cached text draw immediate to include transform */ + view3d_cached_text_draw_begin(); drawaxes(eBone->length*0.25f, 0, OB_ARROWS); + view3d_cached_text_draw_end(v3d, ar, 1, bmat); + glPopMatrix(); } @@ -2021,8 +2043,9 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt) /* draw bone paths * - in view space */ -static void draw_pose_paths(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob) +static void draw_pose_paths(Scene *scene, View3D *v3d, ARegion *ar, Object *ob) { + RegionView3D *rv3d= ar->regiondata; AnimData *adt= BKE_animdata_from_id(&ob->id); bArmature *arm= ob->data; bPoseChannel *pchan; @@ -2155,12 +2178,12 @@ static void draw_pose_paths(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec /* only draw framenum if several consecutive highlighted points don't occur on same point */ if (a == 0) { sprintf(str, "%d", (a+sfra)); - view3d_object_text_draw_add(fp[0], fp[1], fp[2], str, 0); + view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0); } else if ((a > stepsize) && (a < len-stepsize)) { if ((VecEqual(fp, fp-(stepsize*3))==0) || (VecEqual(fp, fp+(stepsize*3))==0)) { sprintf(str, "%d", (a+sfra)); - view3d_object_text_draw_add(fp[0], fp[1], fp[2], str, 0); + view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0); } } } @@ -2202,7 +2225,7 @@ static void draw_pose_paths(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec char str[32]; sprintf(str, "%d", (a+sfra)); - view3d_object_text_draw_add(fp[0], fp[1], fp[2], str, 0); + view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0); } } } @@ -2253,7 +2276,7 @@ static void ghost_poses_tag_unselected(Object *ob, short unset) /* draw ghosts that occur within a frame range * note: object should be in posemode */ -static void draw_ghost_poses_range(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base) +static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base *base) { Object *ob= base->object; AnimData *adt= BKE_animdata_from_id(&ob->id); @@ -2295,7 +2318,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, RegionView3D *rv3d BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); where_is_pose(scene, ob); - draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE); + draw_pose_channels(scene, v3d, ar, base, OB_WIRE); } glDisable(GL_BLEND); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); @@ -2315,7 +2338,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, RegionView3D *rv3d /* draw ghosts on keyframes in action within range * - object should be in posemode */ -static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base) +static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *base) { Object *ob= base->object; AnimData *adt= BKE_animdata_from_id(&ob->id); @@ -2374,7 +2397,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, RegionView3D *rv3d, BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); where_is_pose(scene, ob); - draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE); + draw_pose_channels(scene, v3d, ar, base, OB_WIRE); } glDisable(GL_BLEND); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); @@ -2394,7 +2417,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, RegionView3D *rv3d, /* draw ghosts around current frame * - object is supposed to be armature in posemode */ -static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base) +static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base) { Object *ob= base->object; AnimData *adt= BKE_animdata_from_id(&ob->id); @@ -2444,7 +2467,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base if (CFRA != cfrao) { BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); where_is_pose(scene, ob); - draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE); + draw_pose_channels(scene, v3d, ar, base, OB_WIRE); } } @@ -2459,7 +2482,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base if (CFRA != cfrao) { BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); where_is_pose(scene, ob); - draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE); + draw_pose_channels(scene, v3d, ar, base, OB_WIRE); } } } @@ -2480,7 +2503,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base /* ********************************** Armature Drawing - Main ************************* */ /* called from drawobject.c, return 1 if nothing was drawn */ -int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag) +int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag) { Object *ob= base->object; bArmature *arm= ob->data; @@ -2504,7 +2527,7 @@ int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int /* editmode? */ if(arm->edbo) { arm->flag |= ARM_EDITMODE; - draw_ebones(v3d, rv3d, ob, dt); + draw_ebones(v3d, ar, ob, dt); arm->flag &= ~ARM_EDITMODE; } else{ @@ -2513,32 +2536,36 @@ int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int /* drawing posemode selection indices or colors only in these cases */ if(!(base->flag & OB_FROMDUPLI)) { if(G.f & G_PICKSEL) { - if(ob->mode & OB_MODE_POSE) + if(OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) { + if(ob==modifiers_isDeformedByArmature(OBACT)) + arm->flag |= ARM_POSEMODE; + } + else if(ob->mode & OB_MODE_POSE) arm->flag |= ARM_POSEMODE; } else if(ob->mode & OB_MODE_POSE) { if (arm->ghosttype == ARM_GHOST_RANGE) { - draw_ghost_poses_range(scene, v3d, rv3d, base); + draw_ghost_poses_range(scene, v3d, ar, base); } else if (arm->ghosttype == ARM_GHOST_KEYS) { - draw_ghost_poses_keys(scene, v3d, rv3d, base); + draw_ghost_poses_keys(scene, v3d, ar, base); } else if (arm->ghosttype == ARM_GHOST_CUR) { if (arm->ghostep) - draw_ghost_poses(scene, v3d, rv3d, base); + draw_ghost_poses(scene, v3d, ar, base); } if ((flag & DRAW_SCENESET)==0) { if(ob==OBACT) arm->flag |= ARM_POSEMODE; - else if(ob->mode & OB_MODE_WEIGHT_PAINT) { - if(OBACT && ob==modifiers_isDeformedByArmature(OBACT)) + else if(OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) { + if(ob==modifiers_isDeformedByArmature(OBACT)) arm->flag |= ARM_POSEMODE; } - draw_pose_paths(scene, v3d, rv3d, ob); + draw_pose_paths(scene, v3d, ar, ob); } } } - draw_pose_channels(scene, v3d, rv3d, base, dt); + draw_pose_channels(scene, v3d, ar, base, dt); arm->flag &= ~ARM_POSEMODE; if(ob->mode & OB_MODE_POSE) diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 2e47e2d4483..0d8e1381756 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -71,6 +71,7 @@ #include "UI_resources.h" #include "UI_interface_icons.h" +#include "gpu_buffers.h" #include "GPU_extensions.h" #include "GPU_draw.h" @@ -350,7 +351,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O int istex, solidtex= 0; // XXX scene->obedit warning - if(v3d->drawtype==OB_SOLID || (ob==scene->obedit && v3d->drawtype!=OB_TEXTURE)) { + if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) { /* draw with default lights in solid draw mode and edit mode */ solidtex= 1; Gtexdraw.islit= -1; @@ -399,8 +400,7 @@ static void draw_textured_end() glPopMatrix(); } - -static int draw_tface__set_draw(MTFace *tface, int has_vcol, int matnr) +static int draw_tface__set_draw_legacy(MTFace *tface, int has_vcol, int matnr) { if (tface && (tface->mode&TF_INVISIBLE)) return 0; @@ -422,6 +422,87 @@ static int draw_tface__set_draw(MTFace *tface, int has_vcol, int matnr) return 1; /* Set color from mcol */ } } +static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr) +{ + if (tface && (tface->mode&TF_INVISIBLE)) return 0; + + if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) { + return 2; /* Don't set color */ + } else if (tface && tface->mode&TF_OBCOL) { + return 2; /* Don't set color */ + } else if (!mcol) { + return 2; /* Don't set color */ + } else { + return 1; /* Set color from mcol */ + } +} +static void add_tface_color_layer(DerivedMesh *dm) +{ + MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE); + MFace *mface = dm->getTessFaceArray(dm); + MCol *finalCol; + int i,j; + MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL); + if(!mcol) + mcol = dm->getTessFaceDataArray(dm, CD_MCOL); + + finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumTessFaces(dm),"add_tface_color_layer"); + for(i=0;i<dm->getNumTessFaces(dm);i++) { + if (tface && (tface->mode&TF_INVISIBLE)) { + if( mcol ) + memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4); + else + for(j=0;j<4;j++) { + finalCol[i*4+j].b = 255; + finalCol[i*4+j].g = 255; + finalCol[i*4+j].r = 255; + } + } + else if (tface && mface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, mface[i].mat_nr, TF_TWOSIDE)) { + for(j=0;j<4;j++) { + finalCol[i*4+j].b = 255; + finalCol[i*4+j].g = 0; + finalCol[i*4+j].r = 255; + } + } else if (tface && tface->mode&TF_OBCOL) { + for(j=0;j<4;j++) { + finalCol[i*4+j].r = Gtexdraw.obcol[0]; + finalCol[i*4+j].g = Gtexdraw.obcol[1]; + finalCol[i*4+j].b = Gtexdraw.obcol[2]; + } + } else if (!mcol) { + if (tface) { + for(j=0;j<4;j++) { + finalCol[i*4+j].b = 255; + finalCol[i*4+j].g = 255; + finalCol[i*4+j].r = 255; + } + } + else { + Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1); + if(ma) + for(j=0;j<4;j++) { + finalCol[i*4+j].b = ma->b; + finalCol[i*4+j].g = ma->g; + finalCol[i*4+j].r = ma->r; + } + else + for(j=0;j<4;j++) { + finalCol[i*4+j].b = 255; + finalCol[i*4+j].g = 255; + finalCol[i*4+j].r = 255; + } + } + } else { + for(j=0;j<4;j++) { + finalCol[i*4+j].b = mcol[i*4+j].r; + finalCol[i*4+j].g = mcol[i*4+j].g; + finalCol[i*4+j].r = mcol[i*4+j].b; + } + } + } + CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numFaceData ); +} static int draw_tface_mapped__set_draw(void *userData, int index) { @@ -504,7 +585,7 @@ void draw_mesh_text(Scene *scene, Object *ob, int glsl) return; /* don't draw when editing */ - if(ob == scene->obedit) + if(ob->mode & OB_MODE_EDIT) return; else if(ob==OBACT) if(paint_facesel_test(ob)) @@ -584,7 +665,8 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o /* draw the textured mesh */ draw_textured_begin(scene, v3d, rv3d, ob); - if(ob == scene->obedit) { + if(ob->mode & OB_MODE_EDIT) { + glColor4f(1.0f,1.0f,1.0f,1.0f); dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, me->edit_btmesh); } else if(faceselect) { if(ob->mode & OB_MODE_WEIGHT_PAINT) @@ -593,7 +675,14 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o dm->drawMappedFacesTex(dm, draw_tface_mapped__set_draw, me); } else { - dm->drawFacesTex(dm, draw_tface__set_draw); + if( GPU_buffer_legacy(dm) ) + dm->drawFacesTex(dm, draw_tface__set_draw_legacy); + else { + glColor4f(1.0f,1.0f,1.0f,1.0f); + if( !CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL) ) + add_tface_color_layer(dm); + dm->drawFacesTex(dm, draw_tface__set_draw); + } } /* draw game engine text hack */ diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 482b4718504..dfbdce14992 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -104,6 +104,7 @@ #include "GPU_draw.h" #include "GPU_material.h" #include "GPU_extensions.h" +#include "gpu_buffers.h" #include "ED_mesh.h" #include "ED_particle.h" @@ -115,6 +116,7 @@ #include "UI_interface_icons.h" #include "WM_api.h" +#include "wm_subwindow.h" #include "BLF_api.h" #include "view3d_intern.h" // own include @@ -139,7 +141,9 @@ static void draw_empty_sphere(float size); static void draw_empty_cone(float size); -/* ************* only use while object drawing ************** */ +/* ************* only use while object drawing ************** + * or after running ED_view3d_init_mats_rv3d + * */ static void view3d_project_short_clip(ARegion *ar, float *vec, short *adr) { RegionView3D *rv3d= ar->regiondata; @@ -436,11 +440,11 @@ void drawaxes(float size, int flag, char drawtype) // patch for 3d cards crashing on glSelect for text drawing (IBM) if((flag & DRAW_PICKING) == 0) { if (axis==0) - view3d_object_text_draw_add(v2[0], v2[1], v2[2], "x", 0); + view3d_cached_text_draw_add(v2[0], v2[1], v2[2], "x", 0); else if (axis==1) - view3d_object_text_draw_add(v2[0], v2[1], v2[2], "y", 0); + view3d_cached_text_draw_add(v2[0], v2[1], v2[2], "y", 0); else - view3d_object_text_draw_add(v2[0], v2[1], v2[2], "z", 0); + view3d_cached_text_draw_add(v2[0], v2[1], v2[2], "z", 0); } } break; @@ -498,23 +502,32 @@ static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, float *vec, int se if(v3d->zbuf) glDepthFunc(GL_LEQUAL); } -/* *********** text drawing for object ************* */ -static ListBase strings= {NULL, NULL}; +/* *********** text drawing for object/particles/armature ************* */ -typedef struct ViewObjectString { - struct ViewObjectString *next, *prev; +static ListBase CachedText[3]; +static int CachedTextLevel= 0; + +typedef struct ViewCachedString { + struct ViewCachedString *next, *prev; float vec[3], col[4]; char str[128]; short mval[2]; short xoffs; -} ViewObjectString; +} ViewCachedString; +void view3d_cached_text_draw_begin() +{ + ListBase *strings= &CachedText[CachedTextLevel]; + strings->first= strings->last= NULL; + CachedTextLevel++; +} -void view3d_object_text_draw_add(float x, float y, float z, char *str, short xoffs) +void view3d_cached_text_draw_add(float x, float y, float z, char *str, short xoffs) { - ViewObjectString *vos= MEM_callocN(sizeof(ViewObjectString), "ViewObjectString"); + ListBase *strings= &CachedText[CachedTextLevel-1]; + ViewCachedString *vos= MEM_callocN(sizeof(ViewCachedString), "ViewCachedString"); - BLI_addtail(&strings, vos); + BLI_addtail(strings, vos); BLI_strncpy(vos->str, str, 128); vos->vec[0]= x; vos->vec[1]= y; @@ -523,22 +536,23 @@ void view3d_object_text_draw_add(float x, float y, float z, char *str, short xof vos->xoffs= xoffs; } -static void view3d_object_text_draw(View3D *v3d, ARegion *ar) +void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4]) { - ViewObjectString *vos; - int tot= 0; + RegionView3D *rv3d= ar->regiondata; + ListBase *strings= &CachedText[CachedTextLevel-1]; + ViewCachedString *vos; + int a, tot= 0; /* project first and test */ - for(vos= strings.first; vos; vos= vos->next) { + for(vos= strings->first; vos; vos= vos->next) { + if(mat) + Mat4MulVecfl(mat, vos->vec); view3d_project_short_clip(ar, vos->vec, vos->mval); if(vos->mval[0]!=IS_CLIPPED) tot++; } - + if(tot) { - RegionView3D *rv3d= ar->regiondata; - int a; - if(rv3d->rflag & RV3D_CLIPPING) for(a=0; a<6; a++) glDisable(GL_CLIP_PLANE0+a); @@ -546,16 +560,22 @@ static void view3d_object_text_draw(View3D *v3d, ARegion *ar) wmPushMatrix(); ED_region_pixelspace(ar); - if(v3d->zbuf) glDisable(GL_DEPTH_TEST); + if(depth_write) { + if(v3d->zbuf) glDisable(GL_DEPTH_TEST); + } + else glDepthMask(0); - for(vos= strings.first; vos; vos= vos->next) { + for(vos= strings->first; vos; vos= vos->next) { if(vos->mval[0]!=IS_CLIPPED) { glColor3fv(vos->col); - BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], 0.0, vos->str); + BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, vos->str); } } - if(v3d->zbuf) glEnable(GL_DEPTH_TEST); + if(depth_write) { + if(v3d->zbuf) glEnable(GL_DEPTH_TEST); + } + else glDepthMask(1); wmPopMatrix(); @@ -564,10 +584,14 @@ static void view3d_object_text_draw(View3D *v3d, ARegion *ar) glEnable(GL_CLIP_PLANE0+a); } - if(strings.first) - BLI_freelistN(&strings); + if(strings->first) + BLI_freelistN(strings); + + CachedTextLevel--; } +/* ******************** primitive drawing ******************* */ + static void drawcube(void) { @@ -1279,6 +1303,10 @@ static void drawlattice(Scene *scene, View3D *v3d, Object *ob) /* ***************** ******************** */ +/* Note! - foreach funcs should be called while drawing or directly after + * if not, ED_view3d_init_mats_rv3d() can be used for selection tools + * but would not give correct results with dupli's for eg. which dont + * use the object matrix in the useual way */ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) { struct { void (*func)(void *userData, BMVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData; @@ -1613,9 +1641,28 @@ static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float * } } } + +/* disabled because it crashes combined with e.g. subsurf modifier, + * the derivedmesh can't be assumed to be an EditMeshDerivedMesh, + * nor should this struct be copied around, it should be defined in + * a single place only to avoid them getting out of sync */ +#if 0 +/* originally defined in DerivedMesh.c */ +typedef struct { + DerivedMesh dm; + + EditMesh *em; + float (*vertexCos)[3]; + float (*vertexNos)[3]; + float (*faceNos)[3]; +} EditMeshDerivedMesh; +#endif + static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, int sel, BMVert *eve_act) { struct { BMEditMesh *em; int sel; BMVert *eve_act; } data; + //GPUBuffer *buffer; + //float *varray; data.sel = sel; data.eve_act = eve_act; data.em = em; @@ -1623,6 +1670,59 @@ static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, int sel, BMVert *eve_ bglBegin(GL_POINTS); dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data); bglEnd(); + +#if 0 + /* first come the unselected vertices, then the selected */ + buffer = GPU_buffer_legacy(dm)?0:GPU_buffer_alloc( sizeof(float)*3*dm->getNumVerts(dm)*2, 0 ); + + if( (varray = GPU_buffer_lock_stream( buffer )) && bglPointHack() == 0 ) { + EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; + EditVert *eve; + int i; + int numverts = 0, numselected = 0; + int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_END }; + GPU_buffer_unlock( buffer ); + GPU_interleaved_setup( buffer, datatype ); + varray = GPU_buffer_lock_stream( buffer ); + + glBegin(GL_POINTS); + for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) { + if (eve->h==0 && (eve->f&SELECT)==data.sel) { + if (eve==data.eve_act) { + if (emdm->vertexCos) { + VECCOPY(&varray[3*(dm->getNumVerts(dm)+numselected)],emdm->vertexCos[i]); + } + else { + VECCOPY(&varray[3*(dm->getNumVerts(dm)+numselected)],eve->co); + } + numselected++; + } else { + if (emdm->vertexCos) { + VECCOPY(&varray[3*numverts],emdm->vertexCos[i]); + } else { + VECCOPY(&varray[3*numverts],eve->co); + } + numverts++; + } + } + } + glEnd(); + GPU_buffer_unlock( buffer ); + glDrawArrays(GL_POINTS,0,numverts); + UI_ThemeColor4(TH_EDITMESH_ACTIVE); + glDrawArrays(GL_POINTS,dm->getNumVerts(dm),numselected); + UI_ThemeColor4(data.sel?TH_VERTEX_SELECT:TH_VERTEX); + GPU_buffer_unbind(); + } + { +#endif + bglBegin(GL_POINTS); + dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data); + bglEnd(); +#if 0 + } + GPU_buffer_free( buffer, 0 ); +#endif } /* Draw edges with color set based on selection */ @@ -1680,30 +1780,73 @@ static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm) /* Draw edges with color interpolated based on selection */ static int draw_dm_edges_sel_interp__setDrawOptions(void *userData, int index) { - return !BM_TestHFlag(EDBM_get_edge_for_index(((void**)userData)[1], index), BM_HIDDEN); + return !BM_TestHFlag(EDBM_get_edge_for_index(((void**)userData)[0], index), BM_HIDDEN); } static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int index, float t) { - BMEdge *eed = EDBM_get_edge_for_index(((void**)userData)[1], index); - unsigned char **cols = ((void**)userData)[0]; - unsigned char *col0 = cols[(BM_TestHFlag(eed->v1, BM_SELECT))?1:0]; - unsigned char *col1 = cols[(BM_TestHFlag(eed->v2, BM_SELECT))?1:0]; + BMEdge *eed = EDBM_get_edge_for_index(((void**)userData)[0], index); + unsigned char **cols = userData; + unsigned char *col0 = cols[(BM_TestHFlag(eed->v1, BM_SELECT))?2:1]; + unsigned char *col1 = cols[(BM_TestHFlag(eed->v2, BM_SELECT))?2:1]; glColor4ub( col0[0] + (col1[0]-col0[0])*t, col0[1] + (col1[1]-col0[1])*t, col0[2] + (col1[2]-col0[2])*t, col0[3] + (col1[3]-col0[3])*t); } -static void draw_dm_edges_sel_interp(BMEditMesh *em, DerivedMesh *dm, - unsigned char *baseCol, unsigned char *selCol) -{ - unsigned char *cols[2]; - void *ptrs[2] = {cols, em}; - cols[0] = baseCol; - cols[1] = selCol; - dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, - draw_dm_edges_sel_interp__setDrawInterpOptions, ptrs); +static void draw_dm_edges_sel_interp(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol) +{ + unsigned char *cols[3] = {em, baseCol, selCol}; +#if 0 + int elemsize = sizeof(float)*3+sizeof(unsigned char)*4; + EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *)dm; + EditMesh *em= emdm->em; + unsigned char *varray; + int i; + GPUBuffer *buffer; + + buffer = GPU_buffer_legacy(dm)?0:GPU_buffer_alloc( elemsize*em->totedge*2, 0 ); + if( (varray = GPU_buffer_lock_stream( buffer )) ) { + EditEdge *eed; + int numedges = 0; + int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_C4UB, GPU_BUFFER_INTER_END }; + GPU_buffer_unlock( buffer ); + GPU_interleaved_setup( buffer, datatype ); + varray = GPU_buffer_lock_stream( buffer ); + for (i=0,eed= em->edges.first; eed; i++,eed= eed->next) { + if(eed->h==0) { + unsigned char *col0 = cols[(eed->v1->f&SELECT)?1:0]; + unsigned char *col1 = cols[(eed->v2->f&SELECT)?1:0]; + + if( emdm->vertexCos ) { + VECCOPY(((float *)&varray[elemsize*numedges*2]),emdm->vertexCos[(int) eed->v1->tmp.l]); + } + else { + VECCOPY(((float *)&varray[elemsize*numedges*2]),eed->v1->co); + } + QUATCOPY(&varray[elemsize*numedges*2+sizeof(float)*3],col0); + if( emdm->vertexCos ) { + VECCOPY(((float *)&varray[elemsize*numedges*2+elemsize]),emdm->vertexCos[(int) eed->v2->tmp.l]); + } + else { + VECCOPY(((float *)&varray[elemsize*numedges*2+elemsize]),eed->v2->co); + } + QUATCOPY(&varray[elemsize*numedges*2+elemsize+sizeof(float)*3],col1); + numedges++; + } + } + GPU_buffer_unlock( buffer ); + glDrawArrays(GL_LINES,0,numedges*2); + GPU_buffer_unbind(); + } + else { +#endif + dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols); +#if 0 + } + GPU_buffer_free( buffer, 0 ); +#endif } /* Draw only seam edges */ @@ -1826,14 +1969,242 @@ static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *ba { struct { unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} data; + //EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *)dm; + BMFace *efa; + unsigned char *col; + GPUBuffer *buffer; + unsigned char *varray; + unsigned char black[] = { 0, 0, 0, 0 }; + int i, draw=0; + int elemsize = (sizeof(float)*6+sizeof(unsigned char)*4); data.cols[0] = baseCol; data.em = em; data.cols[1] = selCol; data.cols[2] = actCol; data.efa_act = efa_act; data.me = me; - - dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0); + +#if 0 //BMESH_TODO + buffer = GPU_buffer_legacy(dm)?0:GPU_buffer_alloc( elemsize*dm->getNumFaces(dm)*3*2, 0 ); + if( dm->getVertCos == 0 && (varray = GPU_buffer_lock_stream( buffer )) ) { + int prevdraw = 0; + int numfaces = 0; + int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_N3F, GPU_BUFFER_INTER_C4UB, GPU_BUFFER_INTER_END }; + GPU_buffer_unlock( buffer ); + GPU_interleaved_setup( buffer, datatype ); + glShadeModel(GL_SMOOTH); + varray = GPU_buffer_lock_stream( buffer ); + for (i=0,efa= efa_act; efa; i++,efa= efa->next) { + int drawSmooth = (efa->flag & ME_SMOOTH); + if (efa->h==0) { + if (efa == data.efa_act) { + draw = 2; + } else { + col = data.cols[(efa->f&SELECT)?1:0]; + if (col[3]==0) draw = 0; + else draw = 1; + } + } + else { + draw = 0; + } + if( prevdraw != draw && prevdraw != 0 && numfaces > 0) { + if( prevdraw==2 ) { + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + } + GPU_buffer_unlock( buffer ); + glDrawArrays(GL_TRIANGLES,0,numfaces*3); + if( prevdraw==2 ) { + glDisable(GL_POLYGON_STIPPLE); + } + varray = GPU_buffer_lock_stream( buffer ); + numfaces = 0; + } + + if( draw != 0 ) { + if(!drawSmooth) { + /*if (emdm->vertexCos) { + VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v1->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->faceNos[i]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v2->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->faceNos[i]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v3->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->faceNos[i]); + } + else {*/ + VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v1->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->n); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v2->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->n); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v3->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->n); + /*}*/ + if( draw == 2 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]); + } + else if( draw == 1 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + } + else { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black); + } + + numfaces++; + if( efa->v4 ) { + /*if (emdm->vertexCos) { + VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v3->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->faceNos[i]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v4->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->faceNos[i]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v1->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->faceNos[i]); + } + else {*/ + VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v3->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->n); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v4->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->n); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v1->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->n); + /*}*/ + + if( draw == 2 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]); + } + else if( draw == 1 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + } + else { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black); + } + + numfaces++; + } + } + else { + /*if (emdm->vertexCos) { + VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v1->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->vertexNos[(int) efa->v1->tmp.l]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v2->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->vertexNos[(int) efa->v2->tmp.l]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v3->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->vertexNos[(int) efa->v3->tmp.l]); + } + else {*/ + VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v1->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->v1->no); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v2->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->v2->no); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v3->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->v3->no); + /*}*/ + + if( draw == 2 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]); + } + else if( draw == 1 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + } + else { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black); + } + + numfaces++; + if( efa->v4 ) { + /*if (emdm->vertexCos) { + VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v3->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->vertexNos[(int) efa->v1->tmp.l]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v4->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->vertexNos[(int) efa->v2->tmp.l]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v1->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->vertexNos[(int) efa->v3->tmp.l]); + } + else {*/ + VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v3->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->v3->no); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v4->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->v4->no); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v1->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->v1->no); + /*}*/ + + if( draw == 2 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]); + } + else if( draw == 1 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + } + else { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black); + } + + numfaces++; + } + } + } + prevdraw = draw; + } + GPU_buffer_unlock( buffer ); + if( prevdraw != 0 && numfaces > 0) { + if( prevdraw==2 ) { + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + } + glDrawArrays(GL_TRIANGLES,0,numfaces*3); + if( prevdraw==2 ) { + glDisable(GL_POLYGON_STIPPLE); + } + } + GPU_buffer_unbind(); + } else { +#endif + dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0); + +#if 0 + } + GPU_buffer_free( buffer, 0 ); +#endif } static int draw_dm_creases__setDrawOptions(void *userData, int index) @@ -2080,7 +2451,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, else sprintf(val, conv_float, VecLenf(v1, v2)); - view3d_object_text_draw_add(x, y, z, val, 0); + view3d_cached_text_draw_add(x, y, z, val, 0); } } } @@ -2119,7 +2490,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, else sprintf(val, conv_float, area); - view3d_object_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0); + view3d_cached_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0); } } } @@ -2159,31 +2530,31 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, if( (e4->f & e1->f & SELECT) || (G.moving && (efa->v1->f & SELECT)) ) { /* Vec 1 */ - sprintf(val,"%.3f", VecAngle3(v4, v1, v2)); + sprintf(val,"%.3f", RAD2DEG(VecAngle3(v4, v1, v2))); VecLerpf(fvec, efa->cent, efa->v1->co, 0.8f); - view3d_object_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0); + view3d_cached_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0); } if( (e1->f & e2->f & SELECT) || (G.moving && (efa->v2->f & SELECT)) ) { /* Vec 2 */ - sprintf(val,"%.3f", VecAngle3(v1, v2, v3)); + sprintf(val,"%.3f", RAD2DEG(VecAngle3(v1, v2, v3))); VecLerpf(fvec, efa->cent, efa->v2->co, 0.8f); - view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); + view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); } if( (e2->f & e3->f & SELECT) || (G.moving && (efa->v3->f & SELECT)) ) { /* Vec 3 */ if(efa->v4) - sprintf(val,"%.3f", VecAngle3(v2, v3, v4)); + sprintf(val,"%.3f", RAD2DEG(VecAngle3(v2, v3, v4))); else - sprintf(val,"%.3f", VecAngle3(v2, v3, v1)); + sprintf(val,"%.3f", RAD2DEG(VecAngle3(v2, v3, v1))); VecLerpf(fvec, efa->cent, efa->v3->co, 0.8f); - view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); + view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); } /* Vec 4 */ if(efa->v4) { if( (e3->f & e4->f & SELECT) || (G.moving && (efa->v4->f & SELECT)) ) { - sprintf(val,"%.3f", VecAngle3(v3, v4, v1)); + sprintf(val,"%.3f", RAD2DEG(VecAngle3(v3, v4, v1))); VecLerpf(fvec, efa->cent, efa->v4->co, 0.8f); - view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); + view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); } } } @@ -2254,12 +2625,99 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object } } else { + /* 3 floats for position, 3 for normal and times two because the faces may actually be quads instead of triangles */ + GPUBuffer *buffer = GPU_buffer_legacy(em->derivedFinal)?0:GPU_buffer_alloc( sizeof(float)*6*em->tottri*3*2, 0 ); + float *varray; + BMFace *efa; + BMLoop **ls; + int i, curmat = 0, draw = 0; + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED); glEnable(GL_LIGHTING); glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); - finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, em, 0); + if( finalDM->getVertCos == 0 && (varray = GPU_buffer_lock_stream( buffer )) ) { + int prevdraw = 0, prevmat = 0; + int numfaces = 0; + int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_N3F, GPU_BUFFER_INTER_END }; + GPU_buffer_unlock( buffer ); + GPU_interleaved_setup( buffer, datatype ); + glShadeModel(GL_SMOOTH); + varray = GPU_buffer_lock_stream( buffer ); + for (i=0; i<em->tottri; i++) { + int drawSmooth; + + ls = em->looptris[i]; + efa = ls[0]->f; + drawSmooth = BM_TestHFlag(efa, BM_SMOOTH); + + if( !BM_TestHFlag(efa, BM_HIDDEN) ) { + curmat = efa->mat_nr+1; + draw = 1; + } + else { + draw = 0; + } + if( ((prevdraw != draw) || (curmat != prevmat)) && prevdraw != 0 && numfaces > 0) { + if( prevdraw==2 ) { + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + } + GPU_buffer_unlock( buffer ); + GPU_enable_material(prevmat, NULL); + glDrawArrays(GL_TRIANGLES,0,numfaces*3); + if( prevdraw==2 ) { + glDisable(GL_POLYGON_STIPPLE); + } + varray = GPU_buffer_lock_stream( buffer ); + numfaces = 0; + } + if( draw != 0 ) { + if(!drawSmooth) { + VECCOPY(&varray[numfaces*18], ls[0]->v->co); + VECCOPY(&varray[numfaces*18+3], efa->no); + + VECCOPY(&varray[numfaces*18+6], ls[1]->v->co); + VECCOPY(&varray[numfaces*18+9], efa->no); + + VECCOPY(&varray[numfaces*18+12], ls[2]->v->co); + VECCOPY(&varray[numfaces*18+15], efa->no); + numfaces++; + } + else { + VECCOPY(&varray[numfaces*18],ls[0]->v->co); + VECCOPY(&varray[numfaces*18+3],ls[0]->v->no); + + VECCOPY(&varray[numfaces*18+6],ls[1]->v->co); + VECCOPY(&varray[numfaces*18+9],ls[1]->v->no); + + VECCOPY(&varray[numfaces*18+12],ls[2]->v->co); + VECCOPY(&varray[numfaces*18+15],ls[2]->v->no); + numfaces++; + } + } + prevdraw = draw; + prevmat = curmat; + } + GPU_buffer_unlock( buffer ); + if( prevdraw != 0 && numfaces > 0) { + if( prevdraw==2 ) { + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + } + GPU_enable_material(prevmat, NULL); + glDrawArrays(GL_TRIANGLES,0,numfaces*3); + if( prevdraw==2 ) { + glDisable(GL_POLYGON_STIPPLE); + } + } + GPU_buffer_unbind(); + } + else { + finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, 0, 0); + } + GPU_buffer_free(buffer,0); glFrontFace(GL_CCW); glDisable(GL_LIGHTING); @@ -2390,7 +2848,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object GPU_disable_material(); } - EM_free_index_arrays(); + EDBM_free_index_arrays(em); } /* Mesh drawing routines */ @@ -3090,82 +3548,31 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas return retval; } -/* *********** text drawing for particles ************* */ -static ListBase pstrings= {NULL, NULL}; - -typedef struct ViewParticleString { - struct ViewParticleString *next, *prev; - float vec[3], col[4]; - char str[128]; - short mval[2]; - short xoffs; -} ViewParticleString; - - -void view3d_particle_text_draw_add(float x, float y, float z, char *str, short xoffs) -{ - ViewObjectString *vos= MEM_callocN(sizeof(ViewObjectString), "ViewObjectString"); - - BLI_addtail(&pstrings, vos); - BLI_strncpy(vos->str, str, 128); - vos->vec[0]= x; - vos->vec[1]= y; - vos->vec[2]= z; - glGetFloatv(GL_CURRENT_COLOR, vos->col); - vos->xoffs= xoffs; -} - -static void view3d_particle_text_draw(View3D *v3d, ARegion *ar) +/* *********** drawing for particles ************* */ +static void draw_particle_arrays(int draw_as, int totpoint, int ob_dt, int select) { - ViewObjectString *vos; - int tot= 0; - - /* project first and test */ - for(vos= pstrings.first; vos; vos= vos->next) { - project_short(ar, vos->vec, vos->mval); - if(vos->mval[0]!=IS_CLIPPED) - tot++; - } - - if(tot) { - RegionView3D *rv3d= ar->regiondata; - int a; - - if(rv3d->rflag & RV3D_CLIPPING) - for(a=0; a<6; a++) - glDisable(GL_CLIP_PLANE0+a); - - wmPushMatrix(); - ED_region_pixelspace(ar); - - if(v3d->zbuf) glDepthMask(0); - - for(vos= pstrings.first; vos; vos= vos->next) { - if(vos->mval[0]!=IS_CLIPPED) { - glColor3fv(vos->col); - BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], 2.0, vos->str); - } - } - - if(v3d->zbuf) glDepthMask(1); - - wmPopMatrix(); + /* draw created data arrays */ + switch(draw_as){ + case PART_DRAW_AXIS: + case PART_DRAW_CROSS: + glDrawArrays(GL_LINES, 0, 6*totpoint); + break; + case PART_DRAW_LINE: + glDrawArrays(GL_LINES, 0, 2*totpoint); + break; + case PART_DRAW_BB: + if(ob_dt<=OB_WIRE || select) + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + else + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - if(rv3d->rflag & RV3D_CLIPPING) - for(a=0; a<6; a++) - glEnable(GL_CLIP_PLANE0+a); + glDrawArrays(GL_QUADS, 0, 4*totpoint); + break; + default: + glDrawArrays(GL_POINTS, 0, totpoint); + break; } - - if(pstrings.first) - BLI_freelistN(&pstrings); } -typedef struct ParticleDrawData { - float *vdata, *vd; - float *ndata, *nd; - float *cdata, *cd; - float *vedata, *ved; - float *ma_r, *ma_g, *ma_b; -} ParticleDrawData; static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize, float imat[4][4], float *draw_line, ParticleBillboardData *bb, ParticleDrawData *pdd) { float vec[3], vec2[3]; @@ -3208,7 +3615,7 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix cd[7]=cd[10]=1.0; cd[13]=cd[12]=cd[15]=cd[16]=0.0; cd[14]=cd[17]=1.0; - cd+=18; + pdd->cd+=18; VECCOPY(vec2,state->co); } @@ -3330,7 +3737,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv ParticleData *pars, *pa; ParticleKey state, *states=0; ParticleBillboardData bb; - ParticleDrawData pdd; + ParticleSimulationData sim = {scene, ob, psys, NULL}; + ParticleDrawData *pdd = psys->pdd; Material *ma; float vel[3], imat[4][4]; float timestep, pixsize=1.0, pa_size, r_tilt, r_length; @@ -3358,12 +3766,20 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(psys_in_edit_mode(scene, psys) && (pset->flag & PE_DRAW_PART)==0) return; - if(part->draw_as==PART_DRAW_NOT) return; + if(part->draw_as == PART_DRAW_REND) + draw_as = part->ren_as; + else + draw_as = part->draw_as; + + if(draw_as == PART_DRAW_NOT) + return; /* 2. */ + sim.psmd = psmd = psys_get_modifier(ob,psys); + if(part->phystype==PART_PHYS_KEYED){ if(psys->flag&PSYS_KEYED){ - psys_count_keyed_targets(ob,psys); + psys_count_keyed_targets(&sim); if(psys->totkeyed==0) return; } @@ -3381,34 +3797,28 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv totchild=0; else totchild=psys->totchild*part->disp/100; - - memset(&pdd, 0, sizeof(ParticleDrawData)); ma= give_current_material(ob,part->omat); if(v3d->zbuf) glDepthMask(1); - if(select) - cpack(0xFFFFFF); - else if((ma) && (part->draw&PART_DRAW_MAT_COL)) { + if((ma) && (part->draw&PART_DRAW_MAT_COL)) { glColor3f(ma->r,ma->g,ma->b); ma_r = ma->r; ma_g = ma->g; ma_b = ma->b; - - pdd.ma_r = &ma_r; - pdd.ma_g = &ma_g; - pdd.ma_b = &ma_b; - - create_cdata = 1; } else cpack(0); - psmd= psys_get_modifier(ob,psys); + if(pdd) { + pdd->ma_r = &ma_r; + pdd->ma_g = &ma_g; + pdd->ma_b = &ma_b; + } - timestep= psys_get_timestep(part); + timestep= psys_get_timestep(&sim); if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) { float mat[4][4]; @@ -3418,11 +3828,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv totpart=psys->totpart; - if(part->draw_as==PART_DRAW_REND) - draw_as = part->ren_as; - else - draw_as = part->draw_as; - //if(part->flag&PART_GLOB_TIME) cfra=bsystem_time(scene, 0, (float)CFRA, 0.0f); @@ -3452,6 +3857,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv pixsize*=2.0; else pixsize*=part->draw_size; + + if(draw_as==PART_DRAW_AXIS) + create_cdata = 1; break; case PART_DRAW_OB: if(part->dup_ob==0) @@ -3499,57 +3907,73 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv Normalize(imat[1]); } + if(!create_cdata && pdd && pdd->cdata) { + MEM_freeN(pdd->cdata); + pdd->cdata = pdd->cd = NULL; + } + /* 4. */ - if(draw_as && draw_as!=PART_DRAW_PATH) { + if(draw_as && ELEM(draw_as, PART_DRAW_PATH, PART_DRAW_CIRC)==0) { int tot_vec_size = (totpart + totchild) * 3 * sizeof(float); - + int create_ndata = 0; + + if(!pdd) + pdd = psys->pdd = MEM_callocN(sizeof(ParticleDrawData), "ParticlDrawData"); + if(part->draw_as == PART_DRAW_REND && part->trail_count > 1) { tot_vec_size *= part->trail_count; psys_make_temp_pointcache(ob, psys); } - if(draw_as!=PART_DRAW_CIRC) { - switch(draw_as) { - case PART_DRAW_AXIS: - case PART_DRAW_CROSS: - if(draw_as != PART_DRAW_CROSS || create_cdata) - pdd.cdata = MEM_callocN(tot_vec_size * 6, "particle_cdata"); - pdd.vdata = MEM_callocN(tot_vec_size * 6, "particle_vdata"); - break; - case PART_DRAW_LINE: - if(create_cdata) - pdd.cdata = MEM_callocN(tot_vec_size * 2, "particle_cdata"); - pdd.vdata = MEM_callocN(tot_vec_size * 2, "particle_vdata"); - break; - case PART_DRAW_BB: - if(create_cdata) - pdd.cdata = MEM_callocN(tot_vec_size * 4, "particle_cdata"); - pdd.vdata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); - pdd.ndata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); - break; - default: - if(create_cdata) - pdd.cdata=MEM_callocN(tot_vec_size, "particle_cdata"); - pdd.vdata=MEM_callocN(tot_vec_size, "particle_vdata"); - } + switch(draw_as) { + case PART_DRAW_AXIS: + case PART_DRAW_CROSS: + tot_vec_size *= 6; + if(draw_as != PART_DRAW_CROSS) + create_cdata = 1; + break; + case PART_DRAW_LINE: + tot_vec_size *= 2; + break; + case PART_DRAW_BB: + tot_vec_size *= 4; + create_ndata = 1; + break; } + if(pdd->tot_vec_size != tot_vec_size) + psys_free_pdd(psys); + + if(!pdd->vdata) + pdd->vdata = MEM_callocN(tot_vec_size, "particle_vdata"); + if(create_cdata && !pdd->cdata) + pdd->cdata = MEM_callocN(tot_vec_size, "particle_cdata"); + if(create_ndata && !pdd->ndata) + pdd->ndata = MEM_callocN(tot_vec_size, "particle_vdata"); + if(part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) { - pdd.vedata = MEM_callocN(tot_vec_size * 2, "particle_vedata"); + if(!pdd->vedata) + pdd->vedata = MEM_callocN(2 * (totpart + totchild) * 3 * sizeof(float), "particle_vedata"); + need_v = 1; } - pdd.vd= pdd.vdata; - pdd.ved= pdd.vedata; - pdd.cd= pdd.cdata; - pdd.nd= pdd.ndata; - - psys->lattice= psys_get_lattice(scene, ob, psys); + pdd->vd= pdd->vdata; + pdd->ved= pdd->vedata; + pdd->cd= pdd->cdata; + pdd->nd= pdd->ndata; + pdd->tot_vec_size= tot_vec_size; } - if(draw_as){ + psys->lattice= psys_get_lattice(&sim); + + if(pdd && draw_as!=PART_DRAW_PATH){ /* 5. */ - for(a=0,pa=pars; a<totpart+totchild; a++, pa++){ + if((pdd->flag & PARTICLE_DRAW_DATA_UPDATED) + && (pdd->vedata || part->draw & (PART_DRAW_SIZE|PART_DRAW_NUM|PART_DRAW_HEALTH))==0) { + totpoint = pdd->totpoint; /* draw data is up to date */ + } + else for(a=0,pa=pars; a<totpart+totchild; a++, pa++){ /* setup per particle individual stuff */ if(a<totpart){ if(totchild && (part->draw&PART_DRAW_PARENT)==0) continue; @@ -3559,9 +3983,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv pa_birthtime=pa->time; pa_dietime = pa->dietime; pa_size=pa->size; - if(part->phystype==PART_PHYS_BOIDS) { + if(part->phystype==PART_PHYS_BOIDS) pa_health = pa->boid->data.health; - } else pa_health = -1.0; @@ -3596,10 +4019,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv } #endif // XXX old animation system - BLI_srandom(psys->seed+a); - - r_tilt = 2.0f*(BLI_frand() - 0.5f); - r_length = BLI_frand(); + r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f); + r_length = PSYS_FRAND(a + 22); } else{ ChildParticle *cpa= &psys->child[a-totpart]; @@ -3630,160 +4051,143 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv pa_health = -1.0; - r_tilt = 2.0f * cpa->rand[2]; - r_length = cpa->rand[1]; + r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f); + r_length = PSYS_FRAND(a + 22); } - if(draw_as!=PART_DRAW_PATH){ - drawn = 0; - if(part->draw_as == PART_DRAW_REND && part->trail_count > 1) { - float length = part->path_end * (1.0 - part->randlength * r_length); - int trail_count = part->trail_count * (1.0 - part->randlength * r_length); - float ct = ((part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time) - length; - float dt = length / (trail_count ? (float)trail_count : 1.0f); - int i=0; - - ct+=dt; - for(i=0; i < trail_count; i++, ct += dt) { - if(part->draw & PART_ABS_PATH_TIME) { - if(ct < pa_birthtime || ct > pa_dietime) - continue; - } - else if(ct < 0.0f || ct > 1.0f) + drawn = 0; + if(part->draw_as == PART_DRAW_REND && part->trail_count > 1) { + float length = part->path_end * (1.0 - part->randlength * r_length); + int trail_count = part->trail_count * (1.0 - part->randlength * r_length); + float ct = ((part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time) - length; + float dt = length / (trail_count ? (float)trail_count : 1.0f); + int i=0; + + ct+=dt; + for(i=0; i < trail_count; i++, ct += dt) { + if(part->draw & PART_ABS_PATH_TIME) { + if(ct < pa_birthtime || ct > pa_dietime) continue; + } + else if(ct < 0.0f || ct > 1.0f) + continue; - state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime)); - psys_get_particle_on_path(scene,ob,psys,a,&state,need_v); - - if(psys->parent) - Mat4MulVecfl(psys->parent->obmat, state.co); - - /* create actiual particle data */ - if(draw_as == PART_DRAW_BB) { - bb.size = pa_size; - bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); - bb.time = ct; - } + state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime)); + psys_get_particle_on_path(&sim,a,&state,need_v); + + if(psys->parent) + Mat4MulVecfl(psys->parent->obmat, state.co); + + /* create actiual particle data */ + if(draw_as == PART_DRAW_BB) { + bb.size = pa_size; + bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); + bb.time = ct; + } - draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, &pdd); + draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, psys->pdd); - totpoint++; - drawn = 1; - } + totpoint++; + drawn = 1; } - else - { - state.time=cfra; - if(psys_get_particle_state(scene,ob,psys,a,&state,0)){ - if(psys->parent) - Mat4MulVecfl(psys->parent->obmat, state.co); - - /* create actiual particle data */ - if(draw_as == PART_DRAW_BB) { - bb.size = pa_size; - bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); - bb.time = pa_time; - } + } + else + { + state.time=cfra; + if(psys_get_particle_state(&sim,a,&state,0)){ + if(psys->parent) + Mat4MulVecfl(psys->parent->obmat, state.co); + + /* create actiual particle data */ + if(draw_as == PART_DRAW_BB) { + bb.size = pa_size; + bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); + bb.time = pa_time; + } - draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, &pdd); + draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, pdd); - totpoint++; - drawn = 1; - } + totpoint++; + drawn = 1; } + } - if(drawn) { - /* additional things to draw for each particle */ - /* (velocity, size and number) */ - if(pdd.vedata){ - VECCOPY(pdd.ved,state.co); - pdd.ved+=3; - VECCOPY(vel,state.vel); - VecMulf(vel,timestep); - VECADD(pdd.ved,state.co,vel); - pdd.ved+=3; - - totve++; - } + if(drawn) { + /* additional things to draw for each particle */ + /* (velocity, size and number) */ + if(pdd->vedata){ + VECCOPY(pdd->ved,state.co); + pdd->ved+=3; + VECCOPY(vel,state.vel); + VecMulf(vel,timestep); + VECADD(pdd->ved,state.co,vel); + pdd->ved+=3; + + totve++; + } - if(part->draw & PART_DRAW_SIZE){ - setlinestyle(3); - drawcircball(GL_LINE_LOOP, state.co, pa_size, imat); - setlinestyle(0); - } + if(part->draw & PART_DRAW_SIZE){ + setlinestyle(3); + drawcircball(GL_LINE_LOOP, state.co, pa_size, imat); + setlinestyle(0); + } - if((part->draw&PART_DRAW_NUM || part->draw&PART_DRAW_HEALTH) && !(G.f & G_RENDER_SHADOW)){ - val[0]= '\0'; - - if(part->draw&PART_DRAW_NUM) - sprintf(val, " %i", a); + if((part->draw&PART_DRAW_NUM || part->draw&PART_DRAW_HEALTH) && !(G.f & G_RENDER_SHADOW)){ + val[0]= '\0'; + + if(part->draw&PART_DRAW_NUM) + sprintf(val, " %i", a); - if(part->draw&PART_DRAW_NUM && part->draw&PART_DRAW_HEALTH) - sprintf(val, "%s:", val); + if(part->draw&PART_DRAW_NUM && part->draw&PART_DRAW_HEALTH) + sprintf(val, "%s:", val); - if(part->draw&PART_DRAW_HEALTH && a < totpart && part->phystype==PART_PHYS_BOIDS) - sprintf(val, "%s %.2f", val, pa_health); + if(part->draw&PART_DRAW_HEALTH && a < totpart && part->phystype==PART_PHYS_BOIDS) + sprintf(val, "%s %.2f", val, pa_health); - /* in path drawing state.co is the end point */ - view3d_particle_text_draw_add(state.co[0], state.co[1], state.co[2], val, 0); - } + /* in path drawing state.co is the end point */ + view3d_cached_text_draw_add(state.co[0], state.co[1], state.co[2], val, 0); } } } + } /* 6. */ - glGetIntegerv(GL_POLYGON_MODE, polygonmode); - glDisableClientState(GL_NORMAL_ARRAY); - - if(draw_as==PART_DRAW_PATH){ - ParticleCacheKey **cache, *path; - float *cd2=0,*cdata2=0; + glGetIntegerv(GL_POLYGON_MODE, polygonmode); + glDisableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); + if(draw_as==PART_DRAW_PATH){ + ParticleCacheKey **cache, *path; + float *cd2=0,*cdata2=0; - /* setup gl flags */ - if(ob_dt > OB_WIRE) { - glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); - if(part->draw&PART_DRAW_MAT_COL) - glEnableClientState(GL_COLOR_ARRAY); - - glEnable(GL_LIGHTING); - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glEnable(GL_COLOR_MATERIAL); - } - else { - glDisableClientState(GL_NORMAL_ARRAY); + /* setup gl flags */ + if(ob_dt > OB_WIRE) { + glEnableClientState(GL_NORMAL_ARRAY); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_LIGHTING); - UI_ThemeColor(TH_WIRE); - } + if(part->draw&PART_DRAW_MAT_COL) + glEnableClientState(GL_COLOR_ARRAY); - if(totchild && (part->draw&PART_DRAW_PARENT)==0) - totpart=0; + glEnable(GL_LIGHTING); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + } + else { + glDisableClientState(GL_NORMAL_ARRAY); - /* draw actual/parent particles */ - cache=psys->pathcache; - for(a=0, pa=psys->particles; a<totpart; a++, pa++){ - path=cache[a]; - if(path->steps > 0) { - glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_LIGHTING); + UI_ThemeColor(TH_WIRE); + } - if(ob_dt > OB_WIRE) { - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); - if(part->draw&PART_DRAW_MAT_COL) - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); - } + if(totchild && (part->draw&PART_DRAW_PARENT)==0) + totpart=0; - glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); - } - } - - /* draw child particles */ - cache=psys->childcache; - for(a=0; a<totchild; a++){ - path=cache[a]; + /* draw actual/parent particles */ + cache=psys->pathcache; + for(a=0, pa=psys->particles; a<totpart; a++, pa++){ + path=cache[a]; + if(path->steps > 0) { glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); if(ob_dt > OB_WIRE) { @@ -3794,83 +4198,103 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); } + } + + /* draw child particles */ + cache=psys->childcache; + for(a=0; a<totchild; a++){ + path=cache[a]; + glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); - - /* restore & clean up */ if(ob_dt > OB_WIRE) { + glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); if(part->draw&PART_DRAW_MAT_COL) - glDisable(GL_COLOR_ARRAY); - glDisable(GL_COLOR_MATERIAL); + glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); } - if(cdata2) - MEM_freeN(cdata2); - cd2=cdata2=0; + glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); + } + - glLineWidth(1.0f); + /* restore & clean up */ + if(ob_dt > OB_WIRE) { + if(part->draw&PART_DRAW_MAT_COL) + glDisable(GL_COLOR_ARRAY); + glDisable(GL_COLOR_MATERIAL); } - else if(draw_as!=PART_DRAW_CIRC){ - glDisableClientState(GL_COLOR_ARRAY); - /* setup created data arrays */ - if(pdd.vdata){ - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, pdd.vdata); - } + if(cdata2) + MEM_freeN(cdata2); + cd2=cdata2=0; + + glLineWidth(1.0f); + } + else if(pdd && ELEM(draw_as, 0, PART_DRAW_CIRC)==0){ + glDisableClientState(GL_COLOR_ARRAY); + + /* enable point data array */ + if(pdd->vdata){ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, pdd->vdata); + } + else + glDisableClientState(GL_VERTEX_ARRAY); + + if(select) { + UI_ThemeColor(TH_ACTIVE); + + if(part->draw_size) + glPointSize(part->draw_size + 2); else - glDisableClientState(GL_VERTEX_ARRAY); + glPointSize(4.0); - /* billboards are drawn this way */ - if(pdd.ndata && ob_dt>OB_WIRE){ - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, pdd.ndata); - glEnable(GL_LIGHTING); - } - else{ - glDisableClientState(GL_NORMAL_ARRAY); - glDisable(GL_LIGHTING); - } + glLineWidth(3.0); - if(pdd.cdata){ - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(3, GL_FLOAT, 0, pdd.cdata); - } + draw_particle_arrays(draw_as, totpoint, ob_dt, 1); + } - /* draw created data arrays */ - switch(draw_as){ - case PART_DRAW_AXIS: - case PART_DRAW_CROSS: - glDrawArrays(GL_LINES, 0, 6*totpoint); - break; - case PART_DRAW_LINE: - glDrawArrays(GL_LINES, 0, 2*totpoint); - break; - case PART_DRAW_BB: - if(ob_dt<=OB_WIRE) - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - - glDrawArrays(GL_QUADS, 0, 4*totpoint); - break; - default: - glDrawArrays(GL_POINTS, 0, totpoint); - break; - } + /* restore from select */ + glColor3f(ma_r,ma_g,ma_b); + glPointSize(part->draw_size ? part->draw_size : 2.0); + glLineWidth(1.0); + + /* enable other data arrays */ + + /* billboards are drawn this way */ + if(pdd->ndata && ob_dt>OB_WIRE){ + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, pdd->ndata); + glEnable(GL_LIGHTING); + } + else{ + glDisableClientState(GL_NORMAL_ARRAY); + glDisable(GL_LIGHTING); } - if(pdd.vedata){ - glDisableClientState(GL_COLOR_ARRAY); - cpack(0xC0C0C0); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, pdd.vedata); - - glDrawArrays(GL_LINES, 0, 2*totve); + if(pdd->cdata){ + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(3, GL_FLOAT, 0, pdd->cdata); } - glPolygonMode(GL_FRONT, polygonmode[0]); - glPolygonMode(GL_BACK, polygonmode[1]); + draw_particle_arrays(draw_as, totpoint, ob_dt, 0); + + pdd->flag |= PARTICLE_DRAW_DATA_UPDATED; + pdd->totpoint = totpoint; + } + + if(pdd && pdd->vedata){ + glDisableClientState(GL_COLOR_ARRAY); + cpack(0xC0C0C0); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, pdd->vedata); + + glDrawArrays(GL_LINES, 0, 2*totve); } + glPolygonMode(GL_FRONT, polygonmode[0]); + glPolygonMode(GL_BACK, polygonmode[1]); + /* 7. */ glDisable(GL_LIGHTING); @@ -3879,17 +4303,15 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(states) MEM_freeN(states); - if(pdd.vdata) - MEM_freeN(pdd.vdata); - if(pdd.vedata) - MEM_freeN(pdd.vedata); - if(pdd.cdata) - MEM_freeN(pdd.cdata); - if(pdd.ndata) - MEM_freeN(pdd.ndata); psys->flag &= ~PSYS_DRAWING; + /* draw data can't be saved for billboards as they must update to target changes */ + if(draw_as == PART_DRAW_BB) { + psys_free_pdd(psys); + pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED; + } + if(psys->lattice){ end_latt_deform(psys->lattice); psys->lattice= NULL; @@ -3913,10 +4335,8 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj float *pathcol = NULL, *pcol; - if(edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED) { + if(edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED) PE_update_object(scene, ob, 0); - edit->psys->flag &= ~PSYS_HAIR_UPDATED; - } /* create path and child path cache if it doesn't exist already */ if(edit->pathcache==0) @@ -3990,7 +4410,7 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj if(!(point->flag & PEP_HIDE)) totkeys += point->totkey; - if(!(edit->points->keys->flag & PEK_USE_WCO)) + if(edit->points && !(edit->points->keys->flag & PEK_USE_WCO)) pd=pdata=MEM_callocN(totkeys*3*sizeof(float), "particle edit point data"); cd=cdata=MEM_callocN(totkeys*(timed?4:3)*sizeof(float), "particle edit color data"); @@ -4947,8 +5367,9 @@ static void drawtexspace(Object *ob) } /* draws wire outline */ -static void drawSolidSelect(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base) +static void drawSolidSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base) { + RegionView3D *rv3d= ar->regiondata; Object *ob= base->object; glLineWidth(2.0); @@ -4967,7 +5388,7 @@ static void drawSolidSelect(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base } else if(ob->type==OB_ARMATURE) { if(!(ob->mode & OB_MODE_POSE)) - draw_armature(scene, v3d, rv3d, base, OB_WIRE, 0); + draw_armature(scene, v3d, ar, base, OB_WIRE, 0); } glLineWidth(1.0); @@ -5077,11 +5498,11 @@ void drawRBpivot(bRigidBodyJointConstraint *data) glVertex3fv(v); glEnd(); if (axis==0) - view3d_object_text_draw_add(v[0], v[1], v[2], "px", 0); + view3d_cached_text_draw_add(v[0], v[1], v[2], "px", 0); else if (axis==1) - view3d_object_text_draw_add(v[0], v[1], v[2], "py", 0); + view3d_cached_text_draw_add(v[0], v[1], v[2], "py", 0); else - view3d_object_text_draw_add(v[0], v[1], v[2], "pz", 0); + view3d_cached_text_draw_add(v[0], v[1], v[2], "pz", 0); } glLineWidth (1.0f); setlinestyle(0); @@ -5124,6 +5545,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } } + /* no return after this point, otherwise leaks */ + view3d_cached_text_draw_begin(); + /* draw keys? */ #if 0 // XXX old animation system if(base==(scene->basact) || (base->flag & (SELECT+BA_WAS_SEL))) { @@ -5206,11 +5630,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* draw paths... */ // TODO... - /* multiply view with object matrix */ - wmMultMatrix(ob->obmat); - /* local viewmat and persmat, to calculate projections */ - wmGetMatrix(rv3d->viewmatob); - wmGetSingleMatrix(rv3d->persmatob); + /* multiply view with object matrix. + * local viewmat and persmat, to calculate projections */ + ED_view3d_init_mats_rv3d(ob, rv3d); /* which wire color */ if((flag & DRAW_CONSTCOLOR) == 0) { @@ -5267,7 +5689,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if(ob==OBACT && (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))) { if(ob->type==OB_MESH) { - if(ob==scene->obedit); + if(ob->mode & OB_MODE_EDIT); else { if(dt<OB_SOLID) zbufoff= 1; @@ -5289,7 +5711,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if(dt>=OB_BOUNDBOX ) { dtx= ob->dtx; - if(scene->obedit==ob) { + if(ob->mode & OB_MODE_EDIT) { // the only 2 extra drawtypes alowed in editmode dtx= dtx & (OB_DRAWWIRE|OB_TEXSPACE); } @@ -5305,20 +5727,18 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* draw outline for selected solid objects, mesh does itself */ if((v3d->flag & V3D_SELECT_OUTLINE) && ob->type!=OB_MESH) { - if(dt>OB_WIRE && dt<OB_TEXTURE && ob!=scene->obedit && (flag && DRAW_SCENESET)==0) { + if(dt>OB_WIRE && dt<OB_TEXTURE && (ob->mode & OB_MODE_EDIT)==0 && (flag & DRAW_SCENESET)==0) { if (!(ob->dtx&OB_DRAWWIRE) && (ob->flag&SELECT) && !(flag&DRAW_PICKING)) { - drawSolidSelect(scene, v3d, rv3d, base); + drawSolidSelect(scene, v3d, ar, base); } } } switch( ob->type) { case OB_MESH: - if (!(base->flag&OB_RADIO)) { - empty_object= draw_mesh_object(scene, v3d, rv3d, base, dt, flag); - if(flag!=DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE; // mesh draws wire itself - } + empty_object= draw_mesh_object(scene, v3d, rv3d, base, dt, flag); + if(flag!=DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE; // mesh draws wire itself break; case OB_FONT: @@ -5454,7 +5874,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) break; case OB_ARMATURE: if(dt>OB_WIRE) GPU_enable_material(0, NULL); // we use default material - empty_object= draw_armature(scene, v3d, rv3d, base, dt, flag); + empty_object= draw_armature(scene, v3d, ar, base, dt, flag); if(dt>OB_WIRE) GPU_disable_material(); break; default: @@ -5474,10 +5894,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) wmLoadMatrix(rv3d->viewmat); + view3d_cached_text_draw_begin(); + for(psys=ob->particlesystem.first; psys; psys=psys->next) draw_new_particle_system(scene, v3d, rv3d, base, psys, dt); - view3d_particle_text_draw(v3d, ar); + view3d_cached_text_draw_end(v3d, ar, 0, NULL); wmMultMatrix(ob->obmat); @@ -5629,7 +6051,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing */ /* but, we also dont draw names for sets or duplicators */ if(flag == 0) { - view3d_object_text_draw_add(0.0f, 0.0f, 0.0f, ob->id.name+2, 10); + view3d_cached_text_draw_add(0.0f, 0.0f, 0.0f, ob->id.name+2, 10); } } /*if(dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);*/ @@ -5652,14 +6074,14 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } /* return warning, this is cached text draw */ - view3d_object_text_draw(v3d, ar); + view3d_cached_text_draw_end(v3d, ar, 1, NULL); wmLoadMatrix(rv3d->viewmat); if(zbufoff) glDisable(GL_DEPTH_TEST); if(warning_recursive) return; - if(base->flag & (OB_FROMDUPLI|OB_RADIO)) return; + if(base->flag & OB_FROMDUPLI) return; if(G.f & G_RENDER_SHADOW) return; /* object centers, need to be drawn in viewmat space for speed, but OK for picking select */ @@ -5851,6 +6273,16 @@ static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *drawSmoot return 0; if (!(me->mpoly[index].flag&ME_HIDE)) { + return 1; + } else { + return 0; + } +} +static int bbs_mesh_solid__setDrawOpts_legacy(void *userData, int index, int *drawSmooth_r) +{ + Mesh *me = userData; + + if (!(me->mface[index].flag&ME_HIDE)) { WM_set_framebuffer_index_color(index+1); return 1; } else { @@ -5863,9 +6295,41 @@ static void bbs_mesh_solid(Scene *scene, View3D *v3d, Object *ob) { DerivedMesh *dm = mesh_get_derived_final(scene, ob, v3d->customdata_mask); Mesh *me = (Mesh*)ob->data; + MCol *colors; + int i,j; glColor3ub(0, 0, 0); - dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 0); + + if( !GPU_buffer_legacy(dm) ) { + int *index = DM_get_face_data_layer(dm, CD_ORIGINDEX); + int ind; + colors = MEM_mallocN(dm->getNumTessFaces(dm)*sizeof(MCol)*4,"bbs_mesh_solid"); + for(i=0;i<dm->getNumFaces(dm);i++) { + if( index != 0 ) + ind = index[i]; + else + ind = i; + if (!(me->mface[ind].flag&ME_HIDE)) { + unsigned int fbindex = index_to_framebuffer(ind+1); + for(j=0;j<4;j++) { + colors[i*4+j].b = ((fbindex)&0xFF); + colors[i*4+j].g = (((fbindex)>>8)&0xFF); + colors[i*4+j].r = (((fbindex)>>16)&0xFF); + } + } + else { + memset(&colors[i*4],0,sizeof(MCol)*4); + } + } + + CustomData_add_layer( &dm->faceData, CD_ID_MCOL, CD_ASSIGN, colors, dm->numFaceData ); + GPU_buffer_free(dm->drawObject->colors,0); + dm->drawObject->colors = 0; + dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 1); + } + else { + dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts_legacy, me, 0); + } dm->release(dm); } @@ -5882,7 +6346,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec switch( ob->type) { case OB_MESH: { - if(ob == scene->obedit) { + if(ob->mode & OB_MODE_EDIT) { Mesh *me= ob->data; BMEditMesh *em= me->edit_btmesh; @@ -5938,7 +6402,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r DerivedMesh *dm=NULL, *edm=NULL; int glsl; - if(ob == scene->obedit) + if(ob->mode & OB_MODE_EDIT) edm= editbmesh_get_derived_base(ob, me->edit_btmesh); else dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 0bdc65b5461..ef3627e2b12 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -169,7 +169,6 @@ static int larger_pow2(int n) void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture *tex, float *min, float *max, int res[3], float dx, GPUTexture *tex_shadow) { - Object *ob = base->object; RegionView3D *rv3d= ar->regiondata; float viewnormal[3]; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index b5e5de928b5..2cade9bb685 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -158,6 +158,24 @@ RegionView3D *ED_view3d_context_rv3d(bContext *C) return rv3d; } +/* Most of the time this isn't needed since you could assume the view matrix was + * set while drawing, however when functions like mesh_foreachScreenVert are + * called by selection tools, we can't be sure this object was the last. + * + * for example, transparent objects are drawn after editmode and will cause + * the rv3d mat's to change and break selection. + * + * 'ED_view3d_init_mats_rv3d' should be called before + * view3d_project_short_clip and view3d_project_short_noclip in cases where + * these functions are not used during draw_object + */ +void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d) +{ + wmMultMatrix(ob->obmat); + /* local viewmat and persmat, to calculate projections */ + wmGetMatrix(rv3d->viewmatob); + wmGetSingleMatrix(rv3d->persmatob); +} /* ******************** default callbacks for view3d space ***************** */ @@ -259,7 +277,6 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl) if(v3do->localvd) { v3do->localvd= NULL; v3do->properties_storage= NULL; - v3do->localview= 0; v3do->lay= v3dn->localvd->lay; v3do->lay &= 0xFFFFFF; } @@ -275,101 +292,69 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl) return (SpaceLink *)v3dn; } -static void view3d_modal_keymaps(wmWindowManager *wm, ARegion *ar, int stype) -{ - RegionView3D *rv3d= ar->regiondata; - ListBase *keymap; - - /* copy last mode, then we can re-init the region maps */ - rv3d->lastmode= stype; - - keymap= WM_keymap_listbase(wm, "Object Mode", 0, 0); - if(ELEM(stype, 0, NS_MODE_OBJECT)) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - keymap= WM_keymap_listbase(wm, "EditMesh", 0, 0); - if(stype==NS_EDITMODE_MESH) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - keymap= WM_keymap_listbase(wm, "Curve", 0, 0); - if(stype==NS_EDITMODE_CURVE) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - keymap= WM_keymap_listbase(wm, "Armature", 0, 0); - if(stype==NS_EDITMODE_ARMATURE) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - keymap= WM_keymap_listbase(wm, "Pose", 0, 0); - if(stype==NS_MODE_POSE) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - keymap= WM_keymap_listbase(wm, "Metaball", 0, 0); - if(stype==NS_EDITMODE_MBALL) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - keymap= WM_keymap_listbase(wm, "Lattice", 0, 0); - if(stype==NS_EDITMODE_LATTICE) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - /* armature sketching needs to take over mouse */ - keymap= WM_keymap_listbase(wm, "Armature_Sketch", 0, 0); - if(stype==NS_EDITMODE_ARMATURE) - WM_event_add_keymap_handler_priority(&ar->handlers, keymap, 10); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - keymap= WM_keymap_listbase(wm, "Particle", 0, 0); - if(stype==NS_MODE_PARTICLE) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - /* editfont keymap swallows all... */ - keymap= WM_keymap_listbase(wm, "Font", 0, 0); - if(stype==NS_EDITMODE_TEXT) - WM_event_add_keymap_handler_priority(&ar->handlers, keymap, 10); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); -} - /* add handlers, stuff you only do once or on area/region changes */ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) { - RegionView3D *rv3d= ar->regiondata; - ListBase *keymap; + wmKeyMap *keymap; + + /* object ops. */ + + /* pose is not modal, operator poll checks for this */ + keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); - /* own keymap */ - keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0); + keymap= WM_keymap_find(wm->defaultconf, "Object Mode", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm->defaultconf, "Image Paint", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_listbase(wm, "View3D", SPACE_VIEW3D, 0); + + keymap= WM_keymap_find(wm->defaultconf, "Vertex Paint", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm->defaultconf, "Weight Paint", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm->defaultconf, "Sculpt", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - /* object ops. */ - keymap= WM_keymap_listbase(wm, "Object Non-modal", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "EditMesh", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - /* pose is not modal, operator poll checks for this */ - keymap= WM_keymap_listbase(wm, "Pose", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Curve", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm->defaultconf, "Armature", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm->defaultconf, "Metaball", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - /* modal ops keymaps */ - view3d_modal_keymaps(wm, ar, rv3d->lastmode); - /* operator poll checks for modes */ - keymap= WM_keymap_listbase(wm, "ImagePaint", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Lattice", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + /* armature sketching needs to take over mouse */ + keymap= WM_keymap_find(wm->defaultconf, "Armature_Sketch", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm->defaultconf, "Particle", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + /* editfont keymap swallows all... */ + keymap= WM_keymap_find(wm->defaultconf, "Font", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm->defaultconf, "Object Non-modal", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + /* own keymap, last so modes can override it */ + keymap= WM_keymap_find(wm->defaultconf, "View3D Generic", SPACE_VIEW3D, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm->defaultconf, "View3D", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -444,7 +429,6 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) ED_region_tag_redraw(ar); break; case ND_MODE: - view3d_modal_keymaps(wmn->wm, ar, wmn->subtype); ED_region_tag_redraw(ar); break; } @@ -454,6 +438,7 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) case ND_BONE_ACTIVE: case ND_BONE_SELECT: case ND_TRANSFORM: + case ND_POSE: case ND_DRAW: case ND_MODIFIER: case ND_CONSTRAINT: @@ -482,12 +467,21 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) ED_region_tag_redraw(ar); break; } + break; + case NC_WORLD: + switch(wmn->data) { + case ND_WORLD_DRAW: + ED_region_tag_redraw(ar); + break; + } + break; case NC_LAMP: switch(wmn->data) { case ND_LIGHTING_DRAW: ED_region_tag_redraw(ar); break; } + break; case NC_IMAGE: /* this could be more fine grained checks if we had * more context than just the region */ @@ -516,7 +510,7 @@ static void view3d_main_area_cursor(wmWindow *win, ScrArea *sa, ARegion *ar) /* add handlers, stuff you only do once or on area/region changes */ static void view3d_header_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0); + wmKeyMap *keymap= WM_keymap_find(wm->defaultconf, "View3D Generic", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); @@ -552,11 +546,11 @@ static void view3d_header_area_listener(ARegion *ar, wmNotifier *wmn) /* add handlers, stuff you only do once or on area/region changes */ static void view3d_buttons_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; ED_region_panels_init(wm, ar); - keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0); + keymap= WM_keymap_find(wm->defaultconf, "View3D Generic", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -594,6 +588,7 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn) case ND_BONE_ACTIVE: case ND_BONE_SELECT: case ND_TRANSFORM: + case ND_POSE: case ND_DRAW: case ND_KEYS: ED_region_tag_redraw(ar); @@ -608,6 +603,10 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn) break; } break; + case NC_BRUSH: + if(wmn->action==NA_EDITED) + ED_region_tag_redraw(ar); + break; case NC_SPACE: if(wmn->data == ND_SPACE_VIEW3D) ED_region_tag_redraw(ar); @@ -618,16 +617,14 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn) /* add handlers, stuff you only do once or on area/region changes */ static void view3d_tools_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; ED_region_panels_init(wm, ar); - keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0); + keymap= WM_keymap_find(wm->defaultconf, "View3D Generic", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } - - static void view3d_tools_area_draw(const bContext *C, ARegion *ar) { ED_region_panels(C, ar, 1, CTX_data_mode_string(C), -1); @@ -642,10 +639,10 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes if(CTX_data_dir(member)) { static const char *dir[] = { - "selected_objects", "selected_bases" "selected_editable_objects", - "selected_editable_bases" "visible_objects", "visible_bases", "selectable_objects", "selectable_bases", + "selected_objects", "selected_bases", "selected_editable_objects", + "selected_editable_bases", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases", "active_base", "active_object", "visible_bones", "editable_bones", - "selected_bones", "selected_editable_bones" "visible_pchans", + "selected_bones", "selected_editable_bones", "visible_pchans", "selected_pchans", "active_bone", "active_pchan", NULL}; CTX_data_dir_set(result, dir); diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index ece304fb2b5..c50aa4fc2ed 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -153,8 +153,9 @@ typedef struct { /* is used for both read and write... */ -static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d, Object *ob, float lim) +static void v3d_editvertex_buts(const bContext *C, uiLayout *layout, View3D *v3d, Object *ob, float lim) { + uiBlock *block= (layout)? uiLayoutAbsoluteBlock(layout): NULL; MDeformVert *dvert=NULL; TransformProperties *tfp= v3d->properties_storage; float median[5], ve_median[5]; @@ -474,6 +475,7 @@ static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d, } } +#if 0 /* assumes armature active */ static void validate_bonebutton_cb(bContext *C, void *bonev, void *namev) { @@ -492,14 +494,17 @@ static void validate_bonebutton_cb(bContext *C, void *bonev, void *namev) ED_armature_bone_rename(ob->data, oldname, newname); // editarmature.c } } +#endif -static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim) +static void v3d_posearmature_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim) { - uiBut *but; + uiBlock *block= uiLayoutGetBlock(layout); bArmature *arm; bPoseChannel *pchan; Bone *bone= NULL; TransformProperties *tfp= v3d->properties_storage; + PointerRNA pchanptr; + uiLayout *row; arm = ob->data; if (!arm || !ob->pose) return; @@ -509,14 +514,26 @@ static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer)) break; } + if (!pchan) { + uiDefBut(block, LABEL, 0, "No Bone Active", 0, 240, 100, 20, 0, 0, 0, 0, 0, ""); + return; + } + else { + row= uiLayoutRow(layout, 0); + RNA_pointer_create(&ob->id, &RNA_PoseChannel, pchan, &pchanptr); + uiItemL(row, "", ICON_BONE_DATA); + uiItemR(row, "", 0, &pchanptr, "name", 0); + } - if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + uiLayoutAbsoluteBlock(layout); + + if (pchan->rotmode == ROT_MODE_AXISANGLE) { float quat[4]; /* convert to euler, passing through quats... */ - AxisAngleToQuat(quat, &pchan->quat[1], pchan->quat[0]); + AxisAngleToQuat(quat, pchan->rotAxis, pchan->rotAngle); QuatToEul(quat, tfp->ob_eul); } - else if (pchan->rotmode == PCHAN_ROT_QUAT) + else if (pchan->rotmode == ROT_MODE_QUAT) QuatToEul(pchan->quat, tfp->ob_eul); else VecCopyf(tfp->ob_eul, pchan->eul); @@ -580,12 +597,14 @@ void validate_editbonebutton_cb(bContext *C, void *bonev, void *namev) WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, CTX_data_edit_object(C)); // XXX fix } -static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim) +static void v3d_editarmature_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim) { + uiBlock *block= uiLayoutGetBlock(layout); bArmature *arm= ob->data; EditBone *ebone; - uiBut *but; TransformProperties *tfp= v3d->properties_storage; + uiLayout *row; + PointerRNA eboneptr; ebone= arm->edbo->first; @@ -597,6 +616,13 @@ static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float if (!ebone) return; + row= uiLayoutRow(layout, 0); + RNA_pointer_create(&arm->id, &RNA_EditBone, ebone, &eboneptr); + uiItemL(row, "", ICON_BONE_DATA); + uiItemR(row, "", 0, &eboneptr, "name", 0); + + uiLayoutAbsoluteBlock(layout); + uiDefBut(block, LABEL, 0, "Head:", 0, 210, 100, 20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); uiDefButF(block, NUM, B_ARMATUREPANEL1, "X:", 0, 190, 100, 19, ebone->head, -lim, lim, 10, 3, "X Location of the head end of the bone"); @@ -624,8 +650,9 @@ static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float } -static void v3d_editmetaball_buts(uiBlock *block, Object *ob, float lim) +static void v3d_editmetaball_buts(uiLayout *layout, Object *ob, float lim) { + uiBlock *block= uiLayoutAbsoluteBlock(layout); MetaElem *lastelem= NULL; // XXX if(lastelem) { @@ -683,9 +710,24 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) case B_OBJECTPANELROT: if(ob) { - ob->rot[0]= M_PI*tfp->ob_eul[0]/180.0; - ob->rot[1]= M_PI*tfp->ob_eul[1]/180.0; - ob->rot[2]= M_PI*tfp->ob_eul[2]/180.0; + float eul[3]; + + /* make a copy to eul[3], to allow TAB on buttons to work */ + eul[0]= M_PI*tfp->ob_eul[0]/180.0; + eul[1]= M_PI*tfp->ob_eul[1]/180.0; + eul[2]= M_PI*tfp->ob_eul[2]/180.0; + + if (ob->rotmode == ROT_MODE_AXISANGLE) { + float quat[4]; + /* convert to axis-angle, passing through quats */ + EulToQuat(eul, quat); + QuatToAxisAngle(quat, ob->rotAxis, &ob->rotAngle); + } + else if (ob->rotmode == ROT_MODE_QUAT) + EulToQuat(eul, ob->quat); + else + VecCopyf(ob->rot, eul); + DAG_id_flush_update(&ob->id, OB_RECALC_OB); } break; @@ -860,17 +902,16 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) eul[1]= M_PI*tfp->ob_eul[1]/180.0; eul[2]= M_PI*tfp->ob_eul[2]/180.0; - if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + if (pchan->rotmode == ROT_MODE_AXISANGLE) { float quat[4]; /* convert to axis-angle, passing through quats */ EulToQuat(eul, quat); - QuatToAxisAngle(quat, &pchan->quat[1], &pchan->quat[0]); + QuatToAxisAngle(quat, pchan->rotAxis, &pchan->rotAngle); } - else if (pchan->rotmode == PCHAN_ROT_QUAT) + else if (pchan->rotmode == ROT_MODE_QUAT) EulToQuat(eul, pchan->quat); else VecCopyf(pchan->eul, eul); - } /* no break, pass on */ case B_ARMATUREPANEL2: @@ -880,7 +921,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) } break; case B_TRANSFORMSPACEADD: - BIF_manageTransformOrientation(C, 1, 0); + BIF_createTransformOrientation(C, NULL, "", 1, 0); break; case B_TRANSFORMSPACECLEAR: BIF_clearTransformOrientation(C); @@ -993,7 +1034,7 @@ static void view3d_panel_transform_spaces(const bContext *C, Panel *pa) int xco = 20, yco = 70; int index; - block= uiLayoutFreeBlock(pa->layout); + block= uiLayoutAbsoluteBlock(pa->layout); uiBlockBeginAlign(block); @@ -1075,6 +1116,8 @@ static void view3d_panel_object(const bContext *C, Panel *pa) //uiBut *bt; Object *ob= OBACT; TransformProperties *tfp; + PointerRNA obptr; + uiLayout *col, *row; float lim; if(ob==NULL) return; @@ -1084,33 +1127,42 @@ static void view3d_panel_object(const bContext *C, Panel *pa) v3d->properties_storage= MEM_callocN(sizeof(TransformProperties), "TransformProperties"); tfp= v3d->properties_storage; - block= uiLayoutFreeBlock(pa->layout); - uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); - // XXX uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE); - + /* if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)) { } else { if((ob->mode & OB_MODE_PARTICLE_EDIT)==0) { - strcpy(ob->parsubstr, ""); uiBlockEndAlign(block); } } + */ lim= 10000.0f*MAX2(1.0, v3d->grid); + block= uiLayoutGetBlock(pa->layout); + uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); + + col= uiLayoutColumn(pa->layout, 0); + row= uiLayoutRow(col, 0); + RNA_id_pointer_create(&ob->id, &obptr); + uiItemL(row, "", ICON_OBJECT_DATA); + uiItemR(row, "", 0, &obptr, "name", 0); + if(ob==obedit) { - if(ob->type==OB_ARMATURE) v3d_editarmature_buts(block, v3d, ob, lim); - if(ob->type==OB_MBALL) v3d_editmetaball_buts(block, ob, lim); - else v3d_editvertex_buts(C, block, v3d, ob, lim); + if(ob->type==OB_ARMATURE) v3d_editarmature_buts(col, v3d, ob, lim); + if(ob->type==OB_MBALL) v3d_editmetaball_buts(col, ob, lim); + else v3d_editvertex_buts(C, col, v3d, ob, lim); } else if(ob->mode & OB_MODE_POSE) { - v3d_posearmature_buts(block, v3d, ob, lim); + v3d_posearmature_buts(col, v3d, ob, lim); } else { BoundBox *bb = NULL; - + + uiLayoutAbsoluteBlock(col); + + block= uiLayoutAbsoluteBlock(col); uiDefBut(block, LABEL, 0, "Location:", 0, 300, 100, 20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); uiDefButF(block, NUM, B_OBJECTPANEL, "X:", 0, 280, 120, 19, &(ob->loc[0]), -lim, lim, 100, 3, ""); @@ -1124,9 +1176,19 @@ static void view3d_panel_object(const bContext *C, Panel *pa) uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED, 125, 240, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Z Location value from being Transformed"); uiBlockEndAlign(block); - tfp->ob_eul[0]= 180.0*ob->rot[0]/M_PI; - tfp->ob_eul[1]= 180.0*ob->rot[1]/M_PI; - tfp->ob_eul[2]= 180.0*ob->rot[2]/M_PI; + if (ob->rotmode == ROT_MODE_AXISANGLE) { + float quat[4]; + /* convert to euler, passing through quats... */ + AxisAngleToQuat(quat, ob->rotAxis, ob->rotAngle); + QuatToEul(quat, tfp->ob_eul); + } + else if (ob->rotmode == ROT_MODE_QUAT) + QuatToEul(ob->quat, tfp->ob_eul); + else + VecCopyf(tfp->ob_eul, ob->rot); + tfp->ob_eul[0]*= 180.0/M_PI; + tfp->ob_eul[1]*= 180.0/M_PI; + tfp->ob_eul[2]*= 180.0/M_PI; uiBlockBeginAlign(block); if ((ob->parent) && (ob->partype == PARBONE)) { @@ -1277,7 +1339,7 @@ static void view3d_panel_bonesketch_spaces(const bContext *C, Panel *pa) }; - block= uiLayoutFreeBlock(pa->layout); + block= uiLayoutAbsoluteBlock(pa->layout); uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); uiBlockBeginAlign(block); @@ -1445,25 +1507,12 @@ void view3d_buttons_register(ARegionType *art) pt->draw= view3d_panel_transform_spaces; BLI_addtail(&art->paneltypes, pt); - pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil"); - strcpy(pt->idname, "VIEW3D_PT_gpencil"); - strcpy(pt->label, "Greas Pencil"); - pt->draw= view3d_panel_gpencil; - BLI_addtail(&art->paneltypes, pt);*/ - pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel bonesketch spaces"); strcpy(pt->idname, "VIEW3D_PT_bonesketch_spaces"); strcpy(pt->label, "Bone Sketching"); pt->draw= view3d_panel_bonesketch_spaces; pt->poll= view3d_panel_bonesketch_spaces_poll; BLI_addtail(&art->paneltypes, pt); - - /* - pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel redo"); - strcpy(pt->idname, "VIEW3D_PT_redo"); - strcpy(pt->label, "Last Operator"); - pt->draw= view3d_panel_operator_redo; - BLI_addtail(&art->paneltypes, pt); */ // XXX view3d_panel_preview(C, ar, 0); } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index f8584b14e2b..fac3f9fb555 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -732,7 +732,7 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d) char *name = view3d_get_name(v3d, rv3d); char *printable = NULL; - if (v3d->localview) { + if (v3d->localvd) { printable = malloc(strlen(name) + strlen(" (Local)_")); /* '_' gives space for '\0' */ strcpy(printable, name); strcat(printable, " (Local)"); @@ -745,7 +745,7 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d) BLF_draw_default(22, ar->winy-17, 0.0f, printable); } - if (v3d->localview) { + if (v3d->localvd) { free(printable); } } @@ -1413,6 +1413,7 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d) } if(v3d->zbuf) glDisable(GL_DEPTH_TEST); + glDepthMask(0); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -1433,6 +1434,8 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d) wmPopMatrix(); glDisable(GL_BLEND); + + glDepthMask(1); if(v3d->zbuf) glEnable(GL_DEPTH_TEST); } @@ -1961,6 +1964,8 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) v3d->zbuf= TRUE; glEnable(GL_DEPTH_TEST); } + else + v3d->zbuf= FALSE; // needs to be done always, gridview is adjusted in drawgrid() now v3d->gridview= v3d->grid; diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index bbcee0415f8..cee5c82ef38 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -239,9 +239,10 @@ typedef struct ViewOpsData { float ofs[3], obofs[3]; float reverse, dist0; float grid, far; + short axis_snap; /* view rotate only */ int origx, origy, oldx, oldy; - int origkey; + int origkey; /* the key that triggered the operator */ } ViewOpsData; @@ -276,6 +277,7 @@ static void calctrackballvec(rcti *rect, int mx, int my, float *vec) static void viewops_data(bContext *C, wmOperator *op, wmEvent *event) { + static float lastofs[3] = {0,0,0}; View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d; ViewOpsData *vod= MEM_callocN(sizeof(ViewOpsData), "viewops data"); @@ -289,7 +291,16 @@ static void viewops_data(bContext *C, wmOperator *op, wmEvent *event) QUATCOPY(vod->oldquat, rv3d->viewquat); vod->origx= vod->oldx= event->x; vod->origy= vod->oldy= event->y; - vod->origkey= event->type; + vod->origkey= event->type; /* the key that triggered the operator. */ + + if (U.uiflag & USER_ORBIT_SELECTION) + { + VECCOPY(vod->ofs, rv3d->ofs); + /* If there's no selection, lastofs is unmodified and last value since static */ + calculateTransformCenter(C, event, V3D_CENTROID, lastofs); + VECCOPY(vod->obofs, lastofs); + VecMulf(vod->obofs, -1.0f); + } /* lookup, we dont pass on v3d to prevent confusement */ vod->grid= v3d->grid; @@ -357,11 +368,52 @@ static float snapquats[39][6] = { {0.0, 0.0, 0.0, 1.0, 0, 0} }; +enum { + VIEW_PASS= 0, + VIEW_APPLY, + VIEW_CONFIRM +}; + +/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ +#define VIEW_MODAL_CONFIRM 1 /* used for all view operations */ +#define VIEWROT_MODAL_AXIS_SNAP_ENABLE 2 +#define VIEWROT_MODAL_AXIS_SNAP_DISABLE 3 + + +/* called in transform_ops.c, on each regeneration of keymaps */ +void viewrotate_modal_keymap(wmKeyConfig *keyconf) +{ + static EnumPropertyItem modal_items[] = { + {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Cancel", ""}, + + {VIEWROT_MODAL_AXIS_SNAP_ENABLE, "AXIS_SNAP_ENABLE", 0, "Enable Axis Snap", ""}, + {VIEWROT_MODAL_AXIS_SNAP_DISABLE, "AXIS_SNAP_DISABLE", 0, "Enable Axis Snap", ""}, + + {0, NULL, 0, NULL, NULL}}; + + wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "View3D Rotate Modal"); + + /* this function is called for each spacetype, only needs to add map once */ + if(keymap) return; + + keymap= WM_modalkeymap_add(keyconf, "View3D Rotate Modal", modal_items); -static void viewrotate_apply(ViewOpsData *vod, int x, int y, int ctrl) + /* items for modal map */ + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM); + + WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_ENABLE); + WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_DISABLE); + + /* assign map to operators */ + WM_modalkeymap_assign(keymap, "VIEW3D_OT_rotate"); + +} + +static void viewrotate_apply(ViewOpsData *vod, int x, int y) { RegionView3D *rv3d= vod->rv3d; - int use_sel= 0; /* XXX */ + int use_sel= U.uiflag & USER_ORBIT_SELECTION; rv3d->view= 0; /* need to reset everytime because of view snapping */ @@ -462,7 +514,7 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y, int ctrl) } /* check for view snap */ - if (ctrl){ + if (vod->axis_snap){ int i; float viewmat[3][3]; @@ -496,23 +548,41 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y, int ctrl) static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event) { ViewOpsData *vod= op->customdata; + short event_code= VIEW_PASS; /* execute the events */ - switch(event->type) { - case MOUSEMOVE: - viewrotate_apply(vod, event->x, event->y, event->ctrl); - break; + if(event->type==MOUSEMOVE) { + event_code= VIEW_APPLY; + } + else if(event->type==EVT_MODAL_MAP) { + switch (event->val) { + case VIEW_MODAL_CONFIRM: + event_code= VIEW_CONFIRM; + break; + case VIEWROT_MODAL_AXIS_SNAP_ENABLE: + vod->axis_snap= TRUE; + event_code= VIEW_APPLY; + break; + case VIEWROT_MODAL_AXIS_SNAP_DISABLE: + vod->axis_snap= FALSE; + event_code= VIEW_APPLY; + break; + } + } + else if(event->type==vod->origkey && event->val==KM_RELEASE) { + event_code= VIEW_CONFIRM; + } - default: - /* origkey may be zero when invoked from a button */ - if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==0)) { - request_depth_update(CTX_wm_region_view3d(C)); + if(event_code==VIEW_APPLY) { + viewrotate_apply(vod, event->x, event->y); + } + else if (event_code==VIEW_CONFIRM) { + request_depth_update(CTX_wm_region_view3d(C)); - MEM_freeN(vod); - op->customdata= NULL; + MEM_freeN(vod); + op->customdata= NULL; - return OPERATOR_FINISHED; - } + return OPERATOR_FINISHED; } return OPERATOR_RUNNING_MODAL; @@ -541,19 +611,19 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event) } /* add temp handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } -void VIEW3D_OT_viewrotate(wmOperatorType *ot) +void VIEW3D_OT_rotate(wmOperatorType *ot) { /* identifiers */ ot->name= "Rotate view"; ot->description = "Rotate the view."; - ot->idname= "VIEW3D_OT_viewrotate"; + ot->idname= "VIEW3D_OT_rotate"; /* api callbacks */ ot->invoke= viewrotate_invoke; @@ -561,11 +631,38 @@ void VIEW3D_OT_viewrotate(wmOperatorType *ot) ot->poll= ED_operator_view3d_active; /* flags */ - ot->flag= OPTYPE_BLOCKING; + ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; } /* ************************ viewmove ******************************** */ + +/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ + +/* called in transform_ops.c, on each regeneration of keymaps */ +void viewmove_modal_keymap(wmKeyConfig *keyconf) +{ + static EnumPropertyItem modal_items[] = { + {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, + + {0, NULL, 0, NULL, NULL}}; + + wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "View3D Move Modal"); + + /* this function is called for each spacetype, only needs to add map once */ + if(keymap) return; + + keymap= WM_modalkeymap_add(keyconf, "View3D Move Modal", modal_items); + + /* items for modal map */ + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM); + + /* assign map to operators */ + WM_modalkeymap_assign(keymap, "VIEW3D_OT_move"); +} + + static void viewmove_apply(ViewOpsData *vod, int x, int y) { if(vod->rv3d->persp==V3D_CAMOB) { @@ -596,24 +693,35 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y) static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event) { + ViewOpsData *vod= op->customdata; + short event_code= VIEW_PASS; /* execute the events */ - switch(event->type) { - case MOUSEMOVE: - viewmove_apply(vod, event->x, event->y); - break; + if(event->type==MOUSEMOVE) { + event_code= VIEW_APPLY; + } + else if(event->type==EVT_MODAL_MAP) { + switch (event->val) { + case VIEW_MODAL_CONFIRM: + event_code= VIEW_CONFIRM; + break; + } + } + else if(event->type==vod->origkey && event->val==KM_RELEASE) { + event_code= VIEW_CONFIRM; + } - default: - /* origkey may be zero when invoked from a button */ - if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==0)) { - request_depth_update(CTX_wm_region_view3d(C)); + if(event_code==VIEW_APPLY) { + viewmove_apply(vod, event->x, event->y); + } + else if (event_code==VIEW_CONFIRM) { + request_depth_update(CTX_wm_region_view3d(C)); - MEM_freeN(vod); - op->customdata= NULL; + MEM_freeN(vod); + op->customdata= NULL; - return OPERATOR_FINISHED; - } + return OPERATOR_FINISHED; } return OPERATOR_RUNNING_MODAL; @@ -625,19 +733,19 @@ static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event) viewops_data(C, op, event); /* add temp handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } -void VIEW3D_OT_viewmove(wmOperatorType *ot) +void VIEW3D_OT_move(wmOperatorType *ot) { /* identifiers */ ot->name= "Move view"; ot->description = "Move the view."; - ot->idname= "VIEW3D_OT_viewmove"; + ot->idname= "VIEW3D_OT_move"; /* api callbacks */ ot->invoke= viewmove_invoke; @@ -645,11 +753,34 @@ void VIEW3D_OT_viewmove(wmOperatorType *ot) ot->poll= ED_operator_view3d_active; /* flags */ - ot->flag= OPTYPE_BLOCKING; + ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; } /* ************************ viewzoom ******************************** */ +/* called in transform_ops.c, on each regeneration of keymaps */ +void viewzoom_modal_keymap(wmKeyConfig *keyconf) +{ + static EnumPropertyItem modal_items[] = { + {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, + + {0, NULL, 0, NULL, NULL}}; + + wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "View3D Zoom Modal"); + + /* this function is called for each spacetype, only needs to add map once */ + if(keymap) return; + + keymap= WM_modalkeymap_add(keyconf, "View3D Zoom Modal", modal_items); + + /* items for modal map */ + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM); + + /* assign map to operators */ + WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom"); +} + static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my) { RegionView3D *rv3d= ar->regiondata; @@ -758,23 +889,33 @@ static void viewzoom_apply(ViewOpsData *vod, int x, int y) static int viewzoom_modal(bContext *C, wmOperator *op, wmEvent *event) { ViewOpsData *vod= op->customdata; + short event_code= VIEW_PASS; /* execute the events */ - switch(event->type) { - case MOUSEMOVE: - viewzoom_apply(vod, event->x, event->y); - break; + if(event->type==MOUSEMOVE) { + event_code= VIEW_APPLY; + } + else if(event->type==EVT_MODAL_MAP) { + switch (event->val) { + case VIEW_MODAL_CONFIRM: + event_code= VIEW_CONFIRM; + break; + } + } + else if(event->type==vod->origkey && event->val==KM_RELEASE) { + event_code= VIEW_CONFIRM; + } - default: - /* origkey may be zero when invoked from a button */ - if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==0)) { - request_depth_update(CTX_wm_region_view3d(C)); + if(event_code==VIEW_APPLY) { + viewzoom_apply(vod, event->x, event->y); + } + else if (event_code==VIEW_CONFIRM) { + request_depth_update(CTX_wm_region_view3d(C)); - MEM_freeN(vod); - op->customdata= NULL; + MEM_freeN(vod); + op->customdata= NULL; - return OPERATOR_FINISHED; - } + return OPERATOR_FINISHED; } return OPERATOR_RUNNING_MODAL; @@ -823,7 +964,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event) viewops_data(C, op, event); /* add temp handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -845,7 +986,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot) ot->poll= ED_operator_view3d_active; /* flags */ - ot->flag= OPTYPE_BLOCKING; + ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX); } @@ -925,7 +1066,7 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2. void VIEW3D_OT_view_all(wmOperatorType *ot) { /* identifiers */ - ot->name= "View home"; + ot->name= "View All"; ot->description = "View all objects in scene."; ot->idname= "VIEW3D_OT_view_all"; @@ -1064,7 +1205,7 @@ void VIEW3D_OT_view_center(wmOperatorType *ot) { /* identifiers */ - ot->name= "View center"; + ot->name= "View Selected"; ot->description = "Move the view to the selection center."; ot->idname= "VIEW3D_OT_view_center"; @@ -1628,7 +1769,7 @@ static int viewpersportho_exec(bContext *C, wmOperator *op) void VIEW3D_OT_view_persportho(wmOperatorType *ot) { /* identifiers */ - ot->name= "View persp/ortho"; + ot->name= "View Persp/Ortho"; ot->description = "Switch the current view from perspective/orthographic."; ot->idname= "VIEW3D_OT_view_persportho"; @@ -1748,57 +1889,6 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot) RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX); } -/* ********************* draw type operator ****************** */ - -static int view3d_drawtype_exec(bContext *C, wmOperator *op) -{ - View3D *v3d = CTX_wm_view3d(C); - int dt, dt_alt; - - dt = RNA_int_get(op->ptr, "draw_type"); - dt_alt = RNA_int_get(op->ptr, "draw_type_alternate"); - - if (dt_alt != -1) { - if (v3d->drawtype == dt) - v3d->drawtype = dt_alt; - else - v3d->drawtype = dt; - } - else - v3d->drawtype = dt; - - ED_area_tag_redraw(CTX_wm_area(C)); - - return OPERATOR_FINISHED; -} - -static int view3d_drawtype_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - return view3d_drawtype_exec(C, op); -} - -/* toggles */ -void VIEW3D_OT_drawtype(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Change draw type"; - ot->description = "Change the draw type of the view."; - ot->idname= "VIEW3D_OT_drawtype"; - - /* api callbacks */ - ot->invoke= view3d_drawtype_invoke; - ot->exec= view3d_drawtype_exec; - - ot->poll= ED_operator_view3d_active; - - /* flags */ - ot->flag= 0; - - /* rna XXX should become enum */ - RNA_def_int(ot->srna, "draw_type", 0, INT_MIN, INT_MAX, "Draw Type", "", INT_MIN, INT_MAX); - RNA_def_int(ot->srna, "draw_type_alternate", -1, INT_MIN, INT_MAX, "Draw Type Alternate", "", INT_MIN, INT_MAX); -} - /* ***************** 3d cursor cursor op ******************* */ /* mx my in region coords */ @@ -1850,8 +1940,7 @@ static int set_3dcursor_invoke(bContext *C, wmOperator *op, wmEvent *event) // XXX notifier for scene */ ED_area_tag_redraw(CTX_wm_area(C)); - /* prevent other mouse ops to fail */ - return OPERATOR_PASS_THROUGH; + return OPERATOR_FINISHED; } void VIEW3D_OT_cursor3d(wmOperatorType *ot) @@ -2339,7 +2428,7 @@ void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode) if (use_sel) { QuatConj(q1); /* conj == inv for unit quat */ - VecSubf(v3d->ofs, v3d->ofs, obofs); + VecSubf(rv3d->ofs, rv3d->ofs, obofs); QuatMulVecf(q1, rv3d->ofs); VecAddf(rv3d->ofs, rv3d->ofs, obofs); } diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 0c1d0ba28d2..95900e6faa3 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -178,7 +178,7 @@ static void handle_view3d_lock(bContext *C) View3D *v3d= CTX_wm_view3d(C); if (v3d != NULL && sa != NULL) { - if(v3d->localview==0 && v3d->scenelock && sa->spacetype==SPACE_VIEW3D) { + if(v3d->localvd==NULL && v3d->scenelock && sa->spacetype==SPACE_VIEW3D) { /* copy to scene */ scene->lay= v3d->lay; @@ -196,27 +196,38 @@ static int layers_exec(bContext *C, wmOperator *op) View3D *v3d= sa->spacedata.first; int nr= RNA_int_get(op->ptr, "nr"); - if(nr<=0) + if(nr < 0) return OPERATOR_CANCELLED; - nr--; - - if(RNA_boolean_get(op->ptr, "extend")) - v3d->lay |= (1<<nr); - else - v3d->lay = (1<<nr); - - /* set active layer, ensure to always have one */ - if(v3d->lay & (1<<nr)) - v3d->layact= 1<<nr; - else if((v3d->lay & v3d->layact)==0) { - int bit= 0; + + + if(nr == 0) { + /* all layers */ + v3d->lay |= (1<<20)-1; + + if(!v3d->layact) + v3d->layact= 1; + } + else { + nr--; + + if(RNA_boolean_get(op->ptr, "extend")) + v3d->lay |= (1<<nr); + else + v3d->lay = (1<<nr); - while(bit<32) { - if(v3d->lay & (1<<bit)) { - v3d->layact= 1<<bit; - break; + /* set active layer, ensure to always have one */ + if(v3d->lay & (1<<nr)) + v3d->layact= 1<<nr; + else if((v3d->lay & v3d->layact)==0) { + int bit= 0; + + while(bit<32) { + if(v3d->lay & (1<<bit)) { + v3d->layact= 1<<bit; + break; + } + bit++; } - bit++; } } @@ -264,8 +275,8 @@ void VIEW3D_OT_layers(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_int(ot->srna, "nr", 1, 0, 20, "Number", "", 0, 20); - RNA_def_boolean(ot->srna, "extend", 0, "Extend", ""); + RNA_def_int(ot->srna, "nr", 1, 0, 20, "Number", "The layer number to set, zero for all layers", 0, 20); + RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Add this layer to the current view layers"); } #if 0 @@ -1802,8 +1813,10 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event) ED_area_tag_redraw(sa); break; case B_NDOF: + ED_area_tag_redraw(sa); break; case B_MAN_MODE: + ED_area_tag_redraw(sa); break; case B_VIEW_BUTSEDIT: break; @@ -1949,7 +1962,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) uiBlock *block; int a, xco=0, maxco=0, yco= 0; - block= uiLayoutFreeBlock(layout); + block= uiLayoutAbsoluteBlock(layout); uiBlockSetHandleFunc(block, do_view3d_header_buttons, NULL); if((sa->flag & HEADER_NO_PULLDOWN)==0) @@ -2074,7 +2087,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) } /* LAYERS */ - if(obedit==NULL && v3d->localview==0) { + if(obedit==NULL && v3d->localvd==NULL) { int ob_lay = ob ? ob->lay : 0; uiBlockBeginAlign(block); for(a=0; a<5; a++) { @@ -2113,7 +2126,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) xco+= XIC+10; } uiBlockEndAlign(block); - header_xco_step(ar, &xco, &yco, &maxco, XIC+10); + header_xco_step(ar, &xco, &yco, &maxco, 10); } /* Snap */ @@ -2129,10 +2142,14 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) uiDefIconButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_REDR, ICON_SNAP_PEEL_OBJECT,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Consider objects as whole when finding volume center"); xco+= XIC; } + if (ts->snap_mode == SCE_SNAP_MODE_FACE) { + uiDefIconButBitS(block, TOG, SCE_SNAP_PROJECT, B_REDR, ICON_RETOPO,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Project elements instead of snapping them"); + xco+= XIC; + } uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SNAP_VERTEX, snapmode_pup(), xco,yco,XIC+10,YIC, &(ts->snap_mode), 0.0, 0.0, 0, 0, "Snapping mode"); - xco+= XIC; + xco+= XIC + 10; uiDefButS(block, MENU, B_NOP, "Snap Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,yco,70,YIC, &ts->snap_target, 0, 0, 0, 0, "Snap Target Mode"); - xco+= XIC+70; + xco+= 70; } else { uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)"); xco+= XIC; @@ -2154,10 +2171,11 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, xco,yco,XIC,YIC, &em->selectmode, 1.0, 0.0, 0, 0, "Face select mode (Ctrl Tab 3)"); xco+= XIC; uiBlockEndAlign(block); + header_xco_step(ar, &xco, &yco, &maxco, 10); if(v3d->drawtype > OB_WIRE) { uiDefIconButBitS(block, TOG, V3D_ZBUF_SELECT, B_REDR, ICON_ORTHO, xco,yco,XIC,YIC, &v3d->flag, 1.0, 0.0, 0, 0, "Occlude background geometry"); - xco+= XIC; } + xco+= XIC; uiBlockEndAlign(block); header_xco_step(ar, &xco, &yco, &maxco, XIC); } diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 7dbea44b68b..84d1a1275a9 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -62,12 +62,12 @@ void VIEW3D_OT_layers(struct wmOperatorType *ot); /* view3d_ops.c */ void view3d_operatortypes(void); -void view3d_keymap(struct wmWindowManager *wm); +void view3d_keymap(struct wmKeyConfig *keyconf); /* view3d_edit.c */ void VIEW3D_OT_zoom(struct wmOperatorType *ot); -void VIEW3D_OT_viewmove(struct wmOperatorType *ot); -void VIEW3D_OT_viewrotate(struct wmOperatorType *ot); +void VIEW3D_OT_move(struct wmOperatorType *ot); +void VIEW3D_OT_rotate(struct wmOperatorType *ot); void VIEW3D_OT_view_all(struct wmOperatorType *ot); void VIEW3D_OT_viewnumpad(struct wmOperatorType *ot); void VIEW3D_OT_view_center(struct wmOperatorType *ot); @@ -89,10 +89,13 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt); void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, int dt, int outline); void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob); void drawaxes(float size, int flag, char drawtype); -void view3d_object_text_draw_add(float x, float y, float z, char *str, short xoffs); + +void view3d_cached_text_draw_begin(void); +void view3d_cached_text_draw_add(float x, float y, float z, char *str, short xoffs); +void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4]); /* drawarmature.c */ -int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag); +int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag); /* drawmesh.c */ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, struct DerivedMesh *dm, int faceselect); @@ -119,8 +122,10 @@ void VIEW3D_OT_select_lasso(struct wmOperatorType *ot); /* view3d_view.c */ void VIEW3D_OT_smoothview(struct wmOperatorType *ot); void VIEW3D_OT_setcameratoview(struct wmOperatorType *ot); +void VIEW3D_OT_setobjectascamera(struct wmOperatorType *ot); void VIEW3D_OT_localview(struct wmOperatorType *ot); void VIEW3D_OT_game_start(struct wmOperatorType *ot); +void VIEW3D_OT_fly(struct wmOperatorType *ot); int boundbox_clip(RegionView3D *rv3d, float obmat[][4], struct BoundBox *bb); @@ -132,6 +137,11 @@ void smooth_view(struct bContext *C, Object *, Object *, float *ofs, float *quat void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect); /* rect: for picking */ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d); +void fly_modal_keymap(struct wmKeyConfig *keyconf); +void viewrotate_modal_keymap(struct wmKeyConfig *keyconf); +void viewmove_modal_keymap(struct wmKeyConfig *keyconf); +void viewzoom_modal_keymap(struct wmKeyConfig *keyconf); + /* view3d_buttons.c */ void VIEW3D_OT_properties(struct wmOperatorType *ot); void view3d_buttons_register(struct ARegionType *art); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index e179809adc9..4b692e572e2 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -62,8 +62,8 @@ void view3d_operatortypes(void) { - WM_operatortype_append(VIEW3D_OT_viewrotate); - WM_operatortype_append(VIEW3D_OT_viewmove); + WM_operatortype_append(VIEW3D_OT_rotate); + WM_operatortype_append(VIEW3D_OT_move); WM_operatortype_append(VIEW3D_OT_zoom); WM_operatortype_append(VIEW3D_OT_view_all); WM_operatortype_append(VIEW3D_OT_viewnumpad); @@ -82,9 +82,10 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_cursor3d); WM_operatortype_append(VIEW3D_OT_select_lasso); WM_operatortype_append(VIEW3D_OT_setcameratoview); - WM_operatortype_append(VIEW3D_OT_drawtype); + WM_operatortype_append(VIEW3D_OT_setobjectascamera); WM_operatortype_append(VIEW3D_OT_localview); WM_operatortype_append(VIEW3D_OT_game_start); + WM_operatortype_append(VIEW3D_OT_fly); WM_operatortype_append(VIEW3D_OT_layers); WM_operatortype_append(VIEW3D_OT_properties); @@ -101,46 +102,30 @@ void view3d_operatortypes(void) transform_operatortypes(); } -void view3d_keymap(wmWindowManager *wm) +void view3d_keymap(wmKeyConfig *keyconf) { - ListBase *keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0); - wmKeymapItem *km; + wmKeyMap *keymap; + wmKeyMapItem *km; + + keymap= WM_keymap_find(keyconf, "View3D Generic", SPACE_VIEW3D, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_properties", NKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_toolbar", TKEY, KM_PRESS, 0, 0); /* only for region 3D window */ - keymap= WM_keymap_listbase(wm, "View3D", SPACE_VIEW3D, 0); - - /* paint poll checks mode */ - WM_keymap_verify_item(keymap, "PAINT_OT_vertex_paint", LEFTMOUSE, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "PAINT_OT_weight_paint", LEFTMOUSE, KM_PRESS, 0, 0); - - WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "PAINT_OT_clone_cursor_set", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); - - WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); - - /* sketch poll checks mode */ - WM_keymap_add_item(keymap, "SKETCH_OT_gesture", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, 0, 0); - km = WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0); - RNA_boolean_set(km->ptr, "snap", 1); - WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, 0, 0); - km = WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, KM_CTRL, 0); - RNA_boolean_set(km->ptr, "snap", 1); + keymap= WM_keymap_find(keyconf, "View3D", SPACE_VIEW3D, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, 0, 0); /* manipulator always on left mouse, not on action mouse*/ WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "VIEW3D_OT_viewrotate", MIDDLEMOUSE, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "VIEW3D_OT_viewmove", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0); + WM_keymap_verify_item(keymap, "VIEW3D_OT_rotate", MIDDLEMOUSE, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "VIEW3D_OT_move", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_view_center", PADPERIOD, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "VIEW3D_OT_fly", FKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_verify_item(keymap, "VIEW3D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1); @@ -175,6 +160,7 @@ void view3d_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "VIEW3D_OT_game_start", PKEY, KM_PRESS, 0, 0); /* layers, shift + alt are properties set in invoke() */ + RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", ACCENTGRAVEKEY, KM_PRESS, 0, 0)->ptr, "nr", 0); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", ONEKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 1); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", TWOKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 2); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", THREEKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 3); @@ -187,17 +173,21 @@ void view3d_keymap(wmWindowManager *wm) RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", ZEROKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 10); /* drawtype */ - km = WM_keymap_add_item(keymap, "VIEW3D_OT_drawtype", ZKEY, KM_PRESS, 0, 0); - RNA_int_set(km->ptr, "draw_type", OB_SOLID); - RNA_int_set(km->ptr, "draw_type_alternate", OB_WIRE); - km = WM_keymap_add_item(keymap, "VIEW3D_OT_drawtype", ZKEY, KM_PRESS, KM_ALT, 0); - RNA_int_set(km->ptr, "draw_type", OB_TEXTURE); - RNA_int_set(km->ptr, "draw_type_alternate", OB_SOLID); + km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", ZKEY, KM_PRESS, 0, 0); + RNA_string_set(km->ptr, "path", "space_data.viewport_shading"); + RNA_string_set(km->ptr, "value_1", "SOLID"); + RNA_string_set(km->ptr, "value_2", "WIREFRAME"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", ZKEY, KM_PRESS, KM_ALT, 0); + RNA_string_set(km->ptr, "path", "space_data.viewport_shading"); + RNA_string_set(km->ptr, "value_1", "TEXTURED"); + RNA_string_set(km->ptr, "value_2", "SOLID"); - km = WM_keymap_add_item(keymap, "VIEW3D_OT_drawtype", ZKEY, KM_PRESS, KM_SHIFT, 0); - RNA_int_set(km->ptr, "draw_type", OB_SHADED); - RNA_int_set(km->ptr, "draw_type_alternate", OB_WIRE); + km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", ZKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(km->ptr, "path", "space_data.viewport_shading"); + RNA_string_set(km->ptr, "value_1", "SHADED"); + RNA_string_set(km->ptr, "value_2", "WIREFRAME"); /* selection*/ WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); @@ -230,22 +220,40 @@ void view3d_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_camera_to_view", PAD0, KM_PRESS, KM_ALT|KM_CTRL, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_object_as_camera", PAD0, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_snap_menu", SKEY, KM_PRESS, KM_SHIFT, 0); - - /* radial control */ - RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); - RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); - RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", WM_RADIALCONTROL_ANGLE); - RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_vertex_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); - RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); - RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_texture_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); - RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_vertex_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); - RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); - RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_texture_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); + /* context ops */ + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, 0, 0); + RNA_string_set(km->ptr, "path", "space_data.pivot_point"); + RNA_string_set(km->ptr, "value", "BOUNDING_BOX_CENTER"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, KM_CTRL, 0); /* 2.4x allowed Comma+Shift too, rather not use both */ + RNA_string_set(km->ptr, "path", "space_data.pivot_point"); + RNA_string_set(km->ptr, "value", "MEDIAN_POINT"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_toggle", COMMAKEY, KM_PRESS, KM_ALT, 0); /* new in 2.5 */ + RNA_string_set(km->ptr, "path", "space_data.pivot_point_align"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, 0, 0); + RNA_string_set(km->ptr, "path", "space_data.pivot_point"); + RNA_string_set(km->ptr, "value", "CURSOR"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, KM_CTRL, 0); + RNA_string_set(km->ptr, "path", "space_data.pivot_point"); + RNA_string_set(km->ptr, "value", "INDIVIDUAL_CENTERS"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, KM_ALT, 0); + RNA_string_set(km->ptr, "path", "space_data.pivot_point"); + RNA_string_set(km->ptr, "value", "ACTIVE_ELEMENT"); + - transform_keymap_for_space(wm, keymap, SPACE_VIEW3D); + transform_keymap_for_space(keyconf, keymap, SPACE_VIEW3D); + fly_modal_keymap(keyconf); + viewrotate_modal_keymap(keyconf); + viewmove_modal_keymap(keyconf); + viewzoom_modal_keymap(keyconf); } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 4563b21d6c1..eb85c4ff722 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -465,7 +465,10 @@ static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves data.pass = 0; bbsel= EM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ + if(vc->scene->toolsettings->selectmode & SCE_SELECT_VERTEX) { if (bbsel) { EM_backbuf_checkAndSelectVerts(vc->em, select); @@ -590,6 +593,7 @@ static void do_lasso_select_curve(ViewContext *vc, short mcords[][2], short move data.moves = moves; data.select = select; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data); } @@ -610,6 +614,7 @@ static void do_lasso_select_lattice(ViewContext *vc, short mcords[][2], short mo data.moves = moves; data.select = select; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data); } @@ -1160,7 +1165,7 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter, WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, basact->object); /* in weightpaint, we use selected bone to select vertexgroup, so no switch to new active object */ - if(basact->object->mode & OB_MODE_WEIGHT_PAINT) { + if(BASACT && BASACT->object->mode & OB_MODE_WEIGHT_PAINT) { /* prevent activating */ basact= NULL; } @@ -1268,6 +1273,7 @@ static void do_nurbs_box_select(ViewContext *vc, rcti *rect, int select) data.rect = rect; data.select = select; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data); } @@ -1287,6 +1293,7 @@ static void do_lattice_box_select(ViewContext *vc, rcti *rect, int select) data.rect = rect; data.select = select; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ lattice_foreachScreenVert(vc, do_lattice_box_select__doSelect, &data); } @@ -1340,6 +1347,7 @@ static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select) data.done = 0; bbsel= EDBM_init_backbuf_border(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax); + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ if(vc->scene->toolsettings->selectmode & SCE_SELECT_VERTEX) { if (bbsel) { @@ -1725,6 +1733,7 @@ static void mesh_circle_select(ViewContext *vc, int selecting, short *mval, floa bbsel= EDBM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0)); vc->em= ((Mesh *)vc->obedit->data)->edit_btmesh; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ data.select = selecting; data.mval[0] = mval[0]; @@ -1793,6 +1802,7 @@ static void nurbscurve_circle_select(ViewContext *vc, int selecting, short *mval data.mval[1] = mval[1]; data.radius = rad; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data); } @@ -1818,6 +1828,7 @@ static void lattice_circle_select(ViewContext *vc, int selecting, short *mval, f data.mval[1] = mval[1]; data.radius = rad; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data); } diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index 46341f53c26..e1c6f70bde0 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -163,7 +163,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa) if(op==NULL) return; - if(op->type->poll && op->type->poll((bContext *)C)==0) + if(WM_operator_poll((bContext*)C, op->type) == 0) return; block= uiLayoutGetBlock(pa->layout); @@ -208,7 +208,7 @@ static void operator_search_cb(const struct bContext *C, void *arg, char *str, u for(; ot; ot= ot->next) { if(BLI_strcasestr(ot->name, str)) { - if(ot->poll==NULL || ot->poll((bContext *)C)) { + if(WM_operator_poll((bContext*)C, ot)) { if(0==uiSearchItemAdd(items, ot->name, ot, 0)) break; diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index b6260e66af4..8aafe24e702 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -56,9 +56,11 @@ #include "BKE_object.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_report.h" #include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_utildefines.h" +#include "BKE_depsgraph.h" /* for fly mode updating */ #include "RE_pipeline.h" // make_stars @@ -110,7 +112,7 @@ void view3d_operator_needs_opengl(const bContext *C) float *give_cursor(Scene *scene, View3D *v3d) { - if(v3d && v3d->localview) return v3d->cursor; + if(v3d && v3d->localvd) return v3d->cursor; else return scene->cursor; } @@ -384,26 +386,32 @@ void VIEW3D_OT_smoothview(wmOperatorType *ot) ot->poll= ED_operator_view3d_active; } -static int view3d_setcameratoview_exec(bContext *C, wmOperator *op) +static void setcameratoview3d(View3D *v3d, RegionView3D *rv3d, Object *ob) { - View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d= CTX_wm_region_view3d(C); - Object *ob; float dvec[3]; - ob= v3d->camera; dvec[0]= rv3d->dist*rv3d->viewinv[2][0]; dvec[1]= rv3d->dist*rv3d->viewinv[2][1]; dvec[2]= rv3d->dist*rv3d->viewinv[2][2]; VECCOPY(ob->loc, dvec); - VecSubf(ob->loc, ob->loc, v3d->ofs); + VecSubf(ob->loc, ob->loc, rv3d->ofs); rv3d->viewquat[0]= -rv3d->viewquat[0]; QuatToEul(rv3d->viewquat, ob->rot); rv3d->viewquat[0]= -rv3d->viewquat[0]; ob->recalc= OB_RECALC_OB; +} + + +static int view3d_setcameratoview_exec(bContext *C, wmOperator *op) +{ + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d= CTX_wm_region_view3d(C); + + setcameratoview3d(v3d, rv3d, v3d->camera); + rv3d->persp = V3D_CAMOB; WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, CTX_data_scene(C)); @@ -411,6 +419,16 @@ static int view3d_setcameratoview_exec(bContext *C, wmOperator *op) } +int view3d_setcameratoview_poll(bContext *C) +{ + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d= CTX_wm_region_view3d(C); + + if (v3d==NULL || v3d->camera==NULL) return 0; + if (rv3d && rv3d->viewlock != 0) return 0; + return 1; +} + void VIEW3D_OT_setcameratoview(wmOperatorType *ot) { @@ -421,16 +439,50 @@ void VIEW3D_OT_setcameratoview(wmOperatorType *ot) /* api callbacks */ ot->exec= view3d_setcameratoview_exec; - ot->poll= ED_operator_view3d_active; + ot->poll= view3d_setcameratoview_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +static int view3d_setobjectascamera_exec(bContext *C, wmOperator *op) +{ + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d= CTX_wm_region_view3d(C); + Scene *scene= CTX_data_scene(C); + + if(BASACT) { + rv3d->persp= V3D_CAMOB; + v3d->camera= OBACT; + if(v3d->scenelock) + scene->camera= OBACT; + smooth_view(C, NULL, v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, &v3d->lens); + } + + WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT|ND_DRAW, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void VIEW3D_OT_setobjectascamera(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Set Active Object as Camera"; + ot->description= "Set the active object as the active camera for this view or scene."; + ot->idname= "VIEW3D_OT_object_as_camera"; + + /* api callbacks */ + ot->exec= view3d_setobjectascamera_exec; + ot->poll= ED_operator_view3d_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} /* ********************************** */ /* create intersection coordinates in view Z direction at mouse coordinates */ -void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_end[3]) +void viewline(ARegion *ar, View3D *v3d, float mval[2], float ray_start[3], float ray_end[3]) { RegionView3D *rv3d= ar->regiondata; float vec[4]; @@ -465,7 +517,7 @@ void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float } /* create intersection ray in view Z direction at mouse coordinates */ -void viewray(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3]) +void viewray(ARegion *ar, View3D *v3d, float mval[2], float ray_start[3], float ray_normal[3]) { float ray_end[3]; @@ -1303,7 +1355,6 @@ static void initlocalview(Scene *scene, ScrArea *sa) base->object->lay= base->lay; } } - v3d->localview= 0; } } @@ -1325,7 +1376,6 @@ static void restore_localviewdata(ScrArea *sa, int free) if(free) { MEM_freeN(v3d->localvd); v3d->localvd= NULL; - v3d->localview= 0; } for(ar= sa->regionbase.first; ar; ar= ar->next) { @@ -1416,8 +1466,6 @@ static void SaveState(bContext *C) glPushAttrib(GL_ALL_ATTRIB_BITS); - GPU_state_init(); - if(obact && obact->mode & OB_MODE_TEXTURE_PAINT) GPU_paint_set_mipmap(1); @@ -1446,6 +1494,8 @@ static void RestoreState(bContext *C) win->queue= queue_back; + GPU_state_init(); + glPopAttrib(); } @@ -1574,6 +1624,802 @@ void VIEW3D_OT_game_start(wmOperatorType *ot) ot->poll= game_engine_poll; } + +/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ +#define FLY_MODAL_CANCEL 1 +#define FLY_MODAL_CONFIRM 2 +#define FLY_MODAL_ACCELERATE 3 +#define FLY_MODAL_DECELERATE 4 +#define FLY_MODAL_PAN_ENABLE 5 +#define FLY_MODAL_PAN_DISABLE 6 +#define FLY_MODAL_DIR_FORWARD 7 +#define FLY_MODAL_DIR_BACKWARD 8 +#define FLY_MODAL_DIR_LEFT 9 +#define FLY_MODAL_DIR_RIGHT 10 +#define FLY_MODAL_DIR_UP 11 +#define FLY_MODAL_DIR_DOWN 12 +#define FLY_MODAL_AXIS_LOCK_X 13 +#define FLY_MODAL_AXIS_LOCK_Z 14 +#define FLY_MODAL_PRECISION_ENABLE 15 +#define FLY_MODAL_PRECISION_DISABLE 16 + +/* called in transform_ops.c, on each regeneration of keymaps */ +void fly_modal_keymap(wmKeyConfig *keyconf) +{ + static EnumPropertyItem modal_items[] = { + {FLY_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, + {FLY_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, + {FLY_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""}, + {FLY_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""}, + + {FLY_MODAL_PAN_ENABLE, "PAN_ENABLE", 0, "Pan Enable", ""}, + {FLY_MODAL_PAN_DISABLE, "PAN_DISABLE", 0, "Pan Disable", ""}, + + {FLY_MODAL_DIR_FORWARD, "FORWARD", 0, "Fly Forward", ""}, + {FLY_MODAL_DIR_BACKWARD,"BACKWARD", 0, "Fly Backward", ""}, + {FLY_MODAL_DIR_LEFT, "LEFT", 0, "Fly Left", ""}, + {FLY_MODAL_DIR_RIGHT, "RIGHT", 0, "Fly Right", ""}, + {FLY_MODAL_DIR_UP, "UP", 0, "Fly Up", ""}, + {FLY_MODAL_DIR_DOWN, "DOWN", 0, "Fly Down", ""}, + + {FLY_MODAL_AXIS_LOCK_X, "AXIS_LOCK_X", 0, "X Axis Correction", "X axis correction (toggle)"}, + {FLY_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "X Axis Correction", "Z axis correction (toggle)"}, + + {FLY_MODAL_PRECISION_ENABLE, "PRECISION_ENABLE", 0, "Precision Enable", ""}, + {FLY_MODAL_PRECISION_DISABLE, "PRECISION_DISABLE", 0, "Precision Disable", ""}, + + {0, NULL, 0, NULL, NULL}}; + + wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "View3D Fly Modal"); + + /* this function is called for each spacetype, only needs to add map once */ + if(keymap) return; + + keymap= WM_modalkeymap_add(keyconf, "View3D Fly Modal", modal_items); + + /* items for modal map */ + WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CANCEL); + WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, FLY_MODAL_CANCEL); + + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, FLY_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM); + + WM_modalkeymap_add_item(keymap, PADPLUSKEY, KM_PRESS, 0, 0, FLY_MODAL_ACCELERATE); + WM_modalkeymap_add_item(keymap, PADMINUS, KM_PRESS, 0, 0, FLY_MODAL_DECELERATE); + WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, 0, 0, FLY_MODAL_ACCELERATE); + WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, 0, 0, FLY_MODAL_DECELERATE); + + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_PAN_ENABLE); + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE); /* XXX - Bug in the event system, middle mouse release doesnt work */ + + /* WASD */ + WM_modalkeymap_add_item(keymap, WKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_FORWARD); + WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_BACKWARD); + WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_LEFT); + WM_modalkeymap_add_item(keymap, DKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_RIGHT); + WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_UP); + WM_modalkeymap_add_item(keymap, FKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_DOWN); + + WM_modalkeymap_add_item(keymap, XKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_X); + WM_modalkeymap_add_item(keymap, ZKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_Z); + + WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_PRECISION_ENABLE); + WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PRECISION_DISABLE); + + /* assign map to operators */ + WM_modalkeymap_assign(keymap, "VIEW3D_OT_fly"); + +} + +typedef struct FlyInfo { + /* context stuff */ + RegionView3D *rv3d; + View3D *v3d; + ARegion *ar; + Scene *scene; + + wmTimer *timer; /* needed for redraws */ + + short state; + short use_precision; + short redraw; + short mval[2]; + + /* fly state state */ + float speed; /* the speed the view is moving per redraw */ + short axis; /* Axis index to move allong by default Z to move allong the view */ + short pan_view; /* when true, pan the view instead of rotating */ + + /* relative view axis locking - xlock, zlock + 0; disabled + 1; enabled but not checking because mouse hasnt moved outside the margin since locking was checked an not needed + when the mouse moves, locking is set to 2 so checks are done. + 2; mouse moved and checking needed, if no view altering is donem its changed back to 1 */ + short xlock, zlock; + float xlock_momentum, zlock_momentum; /* nicer dynamics */ + float grid; /* world scale 1.0 default */ + + /* backup values */ + float dist_backup; /* backup the views distance since we use a zero dist for fly mode */ + float ofs_backup[3]; /* backup the views offset incase the user cancels flying in non camera mode */ + float rot_backup[4]; /* backup the views quat incase the user cancels flying in non camera mode. (quat for view, eul for camera) */ + short persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */ + + /* compare between last state */ + double time_lastwheel; /* used to accelerate when using the mousewheel a lot */ + double time_lastdraw; /* time between draws */ + + /* use for some lag */ + float dvec_prev[3]; /* old for some lag */ + +} FlyInfo; + +/* FlyInfo->state */ +#define FLY_RUNNING 0 +#define FLY_CANCEL 1 +#define FLY_CONFIRM 2 + +int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event) +{ + float upvec[3]; // tmp + float mat[3][3]; + + fly->rv3d= CTX_wm_region_view3d(C); + fly->v3d = CTX_wm_view3d(C); + fly->ar = CTX_wm_region(C); + fly->scene= CTX_data_scene(C); + + if(fly->rv3d->persp==V3D_CAMOB && fly->v3d->camera->id.lib) { + BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library"); + return FALSE; + } + + if(fly->v3d->ob_centre) { + BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view is locked to an object"); + return FALSE; + } + + if(fly->rv3d->persp==V3D_CAMOB && fly->v3d->camera->constraints.first) { + BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints"); + return FALSE; + } + + fly->state= FLY_RUNNING; + fly->speed= 0.0f; + fly->axis= 2; + fly->pan_view= FALSE; + fly->xlock= FALSE; + fly->zlock= TRUE; + fly->xlock_momentum=0.0f; + fly->zlock_momentum=0.0f; + fly->grid= 1.0f; + fly->use_precision= 0; + + fly->dvec_prev[0]= fly->dvec_prev[1]= fly->dvec_prev[2]= 0.0f; + + fly->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f); + + + /* we have to rely on events to give proper mousecoords after a warp_pointer */ +//XXX2.5 warp_pointer(cent_orig[0], cent_orig[1]); + //fly->mval[0]= (fly->sa->winx)/2; + //fly->mval[1]= (fly->sa->winy)/2; + + fly->mval[0] = event->x - fly->ar->winrct.xmin; + fly->mval[1] = event->y - fly->ar->winrct.ymin; + + + fly->time_lastdraw= fly->time_lastwheel= PIL_check_seconds_timer(); + + fly->rv3d->rflag |= RV3D_FLYMODE; /* so we draw the corner margins */ + + /* detect weather to start with Z locking */ + upvec[0]=1.0f; upvec[1]=0.0f; upvec[2]=0.0f; + Mat3CpyMat4(mat, fly->rv3d->viewinv); + Mat3MulVecfl(mat, upvec); + if (fabs(upvec[2]) < 0.1) + fly->zlock = 1; + upvec[0]=0; upvec[1]=0; upvec[2]=0; + + fly->persp_backup= fly->rv3d->persp; + fly->dist_backup= fly->rv3d->dist; + if (fly->rv3d->persp==V3D_CAMOB) { + /* store the origoinal camera loc and rot */ + VECCOPY(fly->ofs_backup, fly->v3d->camera->loc); + VECCOPY(fly->rot_backup, fly->v3d->camera->rot); + + where_is_object(fly->scene, fly->v3d->camera); + VECCOPY(fly->rv3d->ofs, fly->v3d->camera->obmat[3]); + VecMulf(fly->rv3d->ofs, -1.0f); /*flip the vector*/ + + fly->rv3d->dist=0.0; + fly->rv3d->viewbut=0; + + /* used for recording */ +//XXX2.5 if(v3d->camera->ipoflag & OB_ACTION_OB) +//XXX2.5 actname= "Object"; + + } else { + /* perspective or ortho */ + if (fly->rv3d->persp==V3D_ORTHO) + fly->rv3d->persp= V3D_PERSP; /*if ortho projection, make perspective */ + QUATCOPY(fly->rot_backup, fly->rv3d->viewquat); + VECCOPY(fly->ofs_backup, fly->rv3d->ofs); + fly->rv3d->dist= 0.0; + + upvec[2]= fly->dist_backup; /*x and y are 0*/ + Mat3MulVecfl(mat, upvec); + VecSubf(fly->rv3d->ofs, fly->rv3d->ofs, upvec); + /*Done with correcting for the dist*/ + } + + return 1; +} + +static int flyEnd(bContext *C, FlyInfo *fly) +{ + RegionView3D *rv3d= fly->rv3d; + View3D *v3d = fly->v3d; + + float upvec[3]; + + if(fly->state == FLY_RUNNING) + return OPERATOR_RUNNING_MODAL; + + WM_event_remove_window_timer(CTX_wm_window(C), fly->timer); + + rv3d->dist= fly->dist_backup; + + if (fly->state == FLY_CANCEL) { + /* Revert to original view? */ + if (fly->persp_backup==V3D_CAMOB) { /* a camera view */ + rv3d->viewbut=1; + VECCOPY(v3d->camera->loc, fly->ofs_backup); + VECCOPY(v3d->camera->rot, fly->rot_backup); + DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB); + } else { + /* Non Camera we need to reset the view back to the original location bacause the user canceled*/ + QUATCOPY(rv3d->viewquat, fly->rot_backup); + VECCOPY(rv3d->ofs, fly->ofs_backup); + rv3d->persp= fly->persp_backup; + } + } + else if (fly->persp_backup==V3D_CAMOB) { /* camera */ + float mat3[3][3]; + Mat3CpyMat4(mat3, v3d->camera->obmat); + Mat3ToCompatibleEul(mat3, v3d->camera->rot, fly->rot_backup); + + DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB); +#if 0 //XXX2.5 + if (IS_AUTOKEY_MODE(NORMAL)) { + allqueue(REDRAWIPO, 0); + allspace(REMAKEIPO, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWTIME, 0); + } +#endif + } + else { /* not camera */ + /* Apply the fly mode view */ + /*restore the dist*/ + float mat[3][3]; + upvec[0]= upvec[1]= 0; + upvec[2]= fly->dist_backup; /*x and y are 0*/ + Mat3CpyMat4(mat, rv3d->viewinv); + Mat3MulVecfl(mat, upvec); + VecAddf(rv3d->ofs, rv3d->ofs, upvec); + /*Done with correcting for the dist */ + } + + rv3d->rflag &= ~RV3D_FLYMODE; +//XXX2.5 BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */ + + + if(fly->state == FLY_CONFIRM) { + MEM_freeN(fly); + return OPERATOR_FINISHED; + } + + MEM_freeN(fly); + return OPERATOR_CANCELLED; +} + +void flyEvent(FlyInfo *fly, wmEvent *event) +{ + if (event->type == TIMER) { + fly->redraw = 1; + } + else if (event->type == MOUSEMOVE) { + fly->mval[0] = event->x - fly->ar->winrct.xmin; + fly->mval[1] = event->y - fly->ar->winrct.ymin; + } /* handle modal keymap first */ + else if (event->type == EVT_MODAL_MAP) { + switch (event->val) { + case FLY_MODAL_CANCEL: + fly->state = FLY_CANCEL; + break; + case FLY_MODAL_CONFIRM: + fly->state = FLY_CONFIRM; + break; + + case FLY_MODAL_ACCELERATE: + { + double time_currwheel; + float time_wheel; + + time_currwheel= PIL_check_seconds_timer(); + time_wheel = (float)(time_currwheel - fly->time_lastwheel); + fly->time_lastwheel = time_currwheel; + /*printf("Wheel %f\n", time_wheel);*/ + /*Mouse wheel delays range from 0.5==slow to 0.01==fast*/ + time_wheel = 1+ (10 - (20*MIN2(time_wheel, 0.5))); /* 0-0.5 -> 0-5.0 */ + + if (fly->speed<0.0f) fly->speed= 0.0f; + else { + if (event->shift) + fly->speed+= fly->grid*time_wheel*0.1; + else + fly->speed+= fly->grid*time_wheel; + } + break; + } + case FLY_MODAL_DECELERATE: + { + double time_currwheel; + float time_wheel; + + time_currwheel= PIL_check_seconds_timer(); + time_wheel = (float)(time_currwheel - fly->time_lastwheel); + fly->time_lastwheel = time_currwheel; + time_wheel = 1+ (10 - (20*MIN2(time_wheel, 0.5))); /* 0-0.5 -> 0-5.0 */ + + if (fly->speed>0) fly->speed=0; + else { + if (event->shift) + fly->speed-= fly->grid*time_wheel*0.1; + else + fly->speed-= fly->grid*time_wheel; + } + break; + } + case FLY_MODAL_PAN_ENABLE: + fly->pan_view= TRUE; + break; + case FLY_MODAL_PAN_DISABLE: +//XXX2.5 warp_pointer(cent_orig[0], cent_orig[1]); + fly->pan_view= FALSE; + break; + + /* impliment WASD keys */ + case FLY_MODAL_DIR_FORWARD: + if (fly->speed < 0.0f) fly->speed= -fly->speed; /* flip speed rather then stopping, game like motion */ + else fly->speed += fly->grid; /* increse like mousewheel if were alredy moving in that difection*/ + fly->axis= 2; + break; + case FLY_MODAL_DIR_BACKWARD: + if (fly->speed>0) fly->speed= -fly->speed; + else fly->speed -= fly->grid; + fly->axis= 2; + break; + case FLY_MODAL_DIR_LEFT: + if (fly->speed < 0.0f) fly->speed= -fly->speed; + fly->axis= 0; + break; + case FLY_MODAL_DIR_RIGHT: + if (fly->speed > 0.0f) fly->speed= -fly->speed; + fly->axis= 0; + break; + + case FLY_MODAL_DIR_UP: + if (fly->speed < 0.0f) fly->speed= -fly->speed; + fly->axis= 1; + break; + + case FLY_MODAL_DIR_DOWN: + if (fly->speed > 0.0f) fly->speed= -fly->speed; + fly->axis= 1; + break; + + case FLY_MODAL_AXIS_LOCK_X: + if (fly->xlock) fly->xlock=0; + else { + fly->xlock = 2; + fly->xlock_momentum = 0.0; + } + break; + case FLY_MODAL_AXIS_LOCK_Z: + if (fly->zlock) fly->zlock=0; + else { + fly->zlock = 2; + fly->zlock_momentum = 0.0; + } + break; + + case FLY_MODAL_PRECISION_ENABLE: + fly->use_precision= TRUE; + break; + case FLY_MODAL_PRECISION_DISABLE: + fly->use_precision= FALSE; + break; + + } + } +} + +//int fly_exec(bContext *C, wmOperator *op) +int flyApply(FlyInfo *fly) +{ + /* + fly mode - Shift+F + a fly loop where the user can move move the view as if they are flying + */ + RegionView3D *rv3d= fly->rv3d; + View3D *v3d = fly->v3d; + ARegion *ar = fly->ar; + Scene *scene= fly->scene; + + float mat[3][3], /* 3x3 copy of the view matrix so we can move allong the view axis */ + dvec[3]={0,0,0}, /* this is the direction thast added to the view offset per redraw */ + + /* Camera Uprighting variables */ + upvec[3]={0,0,0}, /* stores the view's up vector */ + + moffset[2], /* mouse offset from the views center */ + tmp_quat[4]; /* used for rotating the view */ + + int cent_orig[2], /* view center */ +//XXX- can avoid using // cent[2], /* view center modified */ + xmargin, ymargin; /* x and y margin are define the safe area where the mouses movement wont rotate the view */ + unsigned char + apply_rotation= 1; /* if the user presses shift they can look about without movinf the direction there looking*/ + + /* for recording */ +#if 0 //XXX2.5 todo, get animation recording working again. + int playing_anim = 0; //XXX has_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM); + int cfra = -1; /*so the first frame always has a key added */ + char *actname=""; +#endif + /* 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 center. + but to correct the dist removal we must + alter offset so the view doesn't jump. */ + + xmargin= ar->winx/20.0f; + ymargin= ar->winy/20.0f; + + cent_orig[0]= ar->winrct.xmin + ar->winx/2; + cent_orig[1]= ar->winrct.ymin + ar->winy/2; + + { + + /* mouse offset from the center */ + moffset[0]= fly->mval[0]- ar->winx/2; + moffset[1]= fly->mval[1]- ar->winy/2; + + /* enforce a view margin */ + if (moffset[0]>xmargin) moffset[0]-=xmargin; + else if (moffset[0] < -xmargin) moffset[0]+=xmargin; + else moffset[0]=0; + + if (moffset[1]>ymargin) moffset[1]-=ymargin; + else if (moffset[1] < -ymargin) moffset[1]+=ymargin; + else moffset[1]=0; + + + /* scale the mouse movement by this value - scales mouse movement to the view size + * moffset[0]/(ar->winx-xmargin*2) - window size minus margin (same for y) + * + * the mouse moves isnt linear */ + + if(moffset[0]) { + moffset[0] /= ar->winx - (xmargin*2); + moffset[0] *= fabs(moffset[0]); + } + + if(moffset[1]) { + moffset[1] /= ar->winy - (ymargin*2); + moffset[1] *= fabs(moffset[1]); + } + + /* Should we redraw? */ + if(fly->speed != 0.0f || moffset[0] || moffset[1] || fly->zlock || fly->xlock || dvec[0] || dvec[1] || dvec[2] ) { + float dvec_tmp[3]; + double time_current, time_redraw; /*time how fast it takes for us to redraw, this is so simple scenes dont fly too fast */ + float time_redraw_clamped; + + time_current= PIL_check_seconds_timer(); + time_redraw= (float)(time_current - fly->time_lastdraw); + time_redraw_clamped= MIN2(0.05f, time_redraw); /* clamt the redraw time to avoid jitter in roll correction */ + fly->time_lastdraw= time_current; + /*fprintf(stderr, "%f\n", time_redraw);*/ /* 0.002 is a small redraw 0.02 is larger */ + + /* Scale the time to use shift to scale the speed down- just like + shift slows many other areas of blender down */ + if (fly->use_precision) + fly->speed= fly->speed * (1.0f-time_redraw_clamped); + + Mat3CpyMat4(mat, rv3d->viewinv); + + if (fly->pan_view==TRUE) { + /* pan only */ + dvec_tmp[0]= -moffset[0]; + dvec_tmp[1]= -moffset[1]; + dvec_tmp[2]= 0; + + if (fly->use_precision) { + dvec_tmp[0] *= 0.1; + dvec_tmp[1] *= 0.1; + } + + Mat3MulVecfl(mat, dvec_tmp); + VecMulf(dvec_tmp, time_redraw*200.0 * fly->grid); + + } else { + float roll; /* similar to the angle between the camera's up and the Z-up, but its very rough so just roll*/ + + /* 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]*-time_redraw*20, tmp_quat); /* Rotate about the relative up vec */ + QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat); + + if (fly->xlock) fly->xlock = 2; /*check for rotation*/ + if (fly->zlock) fly->zlock = 2; + fly->xlock_momentum= 0.0f; + } + + /* rotate about the Y axis- look left/right */ + if (moffset[0]) { + + /* if we're upside down invert the moffset */ + upvec[0]=0; + upvec[1]=1; + upvec[2]=0; + Mat3MulVecfl(mat, upvec); + + if(upvec[2] < 0.0f) + moffset[0]= -moffset[0]; + + /* make the lock vectors */ + if (fly->zlock) { + upvec[0]=0; + upvec[1]=0; + upvec[2]=1; + } else { + upvec[0]=0; + upvec[1]=1; + upvec[2]=0; + Mat3MulVecfl(mat, upvec); + } + + VecRotToQuat( upvec, (float)moffset[0]*time_redraw*20, tmp_quat); /* Rotate about the relative up vec */ + QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat); + + if (fly->xlock) fly->xlock = 2;/*check for rotation*/ + if (fly->zlock) fly->zlock = 2; + } + + if (fly->zlock==2) { + upvec[0]=1; + upvec[1]=0; + upvec[2]=0; + Mat3MulVecfl(mat, upvec); + + /*make sure we have some z rolling*/ + if (fabs(upvec[2]) > 0.00001f) { + roll= upvec[2]*5; + upvec[0]=0; /*rotate the view about this axis*/ + upvec[1]=0; + upvec[2]=1; + + Mat3MulVecfl(mat, upvec); + VecRotToQuat( upvec, roll*time_redraw_clamped*fly->zlock_momentum*0.1, tmp_quat); /* Rotate about the relative up vec */ + QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat); + + fly->zlock_momentum += 0.05f; + } else { + fly->zlock=1; /* dont check until the view rotates again */ + fly->zlock_momentum= 0.0f; + } + } + + if (fly->xlock==2 && moffset[1]==0) { /*only apply xcorrect when mouse isnt applying x rot*/ + upvec[0]=0; + upvec[1]=0; + upvec[2]=1; + Mat3MulVecfl(mat, upvec); + /*make sure we have some z rolling*/ + if (fabs(upvec[2]) > 0.00001) { + roll= upvec[2] * -5; + + upvec[0]= 1.0f; /*rotate the view about this axis*/ + upvec[1]= 0.0f; + upvec[2]= 0.0f; + + Mat3MulVecfl(mat, upvec); + + VecRotToQuat( upvec, roll*time_redraw_clamped*fly->xlock_momentum*0.1f, tmp_quat); /* Rotate about the relative up vec */ + QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat); + + fly->xlock_momentum += 0.05f; + } else { + fly->xlock=1; /* see above */ + fly->xlock_momentum= 0.0f; + } + } + + + if (apply_rotation) { + /* Normal operation */ + /* define dvec, view direction vector */ + dvec_tmp[0]= dvec_tmp[1]= dvec_tmp[2]= 0.0f; + /* move along the current axis */ + dvec_tmp[fly->axis]= 1.0f; + + Mat3MulVecfl(mat, dvec_tmp); + + VecMulf(dvec_tmp, fly->speed * time_redraw * 0.25f); + } + } + + /* impose a directional lag */ + VecLerpf(dvec, dvec_tmp, fly->dvec_prev, (1.0f/(1.0f+(time_redraw*5.0f)))); + + if (rv3d->persp==V3D_CAMOB) { + if (v3d->camera->protectflag & OB_LOCK_LOCX) + dvec[0] = 0.0; + if (v3d->camera->protectflag & OB_LOCK_LOCY) + dvec[1] = 0.0; + if (v3d->camera->protectflag & OB_LOCK_LOCZ) + dvec[2] = 0.0; + } + + VecAddf(rv3d->ofs, rv3d->ofs, dvec); +#if 0 //XXX2.5 + if (fly->zlock && fly->xlock) + headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); + else if (fly->zlock) + headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); + else if (fly->xlock) + headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); + else + headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); +#endif + +//XXX2.5 do_screenhandlers(G.curscreen); /* advance the next frame */ + + /* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */ + if (rv3d->persp==V3D_CAMOB) { + rv3d->persp= V3D_PERSP; /*set this so setviewmatrixview3d uses the ofs and quat instead of the camera */ + setviewmatrixview3d(scene, v3d, rv3d); + + setcameratoview3d(v3d, rv3d, v3d->camera); + + { //XXX - some reason setcameratoview3d doesnt copy, shouldnt not be needed! + VECCOPY(v3d->camera->loc, rv3d->ofs); + VecNegf(v3d->camera->loc); + } + + rv3d->persp= V3D_CAMOB; +#if 0 //XXX2.5 + /* record the motion */ + if (IS_AUTOKEY_MODE(NORMAL) && (!playing_anim || cfra != G.scene->r.cfra)) { + cfra = G.scene->r.cfra; + + if (fly->xlock || fly->zlock || moffset[0] || moffset[1]) { + insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_ROT_X, 0); + insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_ROT_Y, 0); + insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_ROT_Z, 0); + } + if (fly->speed) { + insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_LOC_X, 0); + insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_LOC_Y, 0); + insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_LOC_Z, 0); + } + } +#endif + } +//XXX2.5 scrarea_do_windraw(curarea); +//XXX2.5 screen_swapbuffers(); + } else + /*were not redrawing but we need to update the time else the view will jump */ + fly->time_lastdraw= PIL_check_seconds_timer(); + /* end drawing */ + VECCOPY(fly->dvec_prev, dvec); + } + +/* moved to flyEnd() */ + + return OPERATOR_FINISHED; +} + + + +static int fly_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + RegionView3D *rv3d= CTX_wm_region_view3d(C); + FlyInfo *fly; + + if(rv3d->viewlock) + return OPERATOR_CANCELLED; + + fly= MEM_callocN(sizeof(FlyInfo), "FlyOperation"); + + op->customdata= fly; + + if(initFlyInfo(C, fly, op, event)==FALSE) { + MEM_freeN(op->customdata); + return OPERATOR_CANCELLED; + } + + flyEvent(fly, event); + + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int fly_cancel(bContext *C, wmOperator *op) +{ + FlyInfo *fly = op->customdata; + + fly->state = FLY_CANCEL; + flyEnd(C, fly); + op->customdata= NULL; + + return OPERATOR_CANCELLED; +} + +static int fly_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + int exit_code; + + FlyInfo *fly = op->customdata; + + fly->redraw= 0; + + flyEvent(fly, event); + + if(event->type==TIMER) + flyApply(fly); + + if(fly->redraw) {; + ED_region_tag_redraw(CTX_wm_region(C)); + } + + exit_code = flyEnd(C, fly); + + if(exit_code!=OPERATOR_RUNNING_MODAL) + ED_region_tag_redraw(CTX_wm_region(C)); + + return exit_code; +} + +void VIEW3D_OT_fly(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Fly Navigation"; + ot->description= "Interactively fly around the scene."; + ot->idname= "VIEW3D_OT_fly"; + + /* api callbacks */ + ot->invoke= fly_invoke; + ot->cancel= fly_cancel; + ot->modal= fly_modal; + ot->poll= ED_operator_view3d_active; + + /* flags */ + ot->flag= OPTYPE_BLOCKING; + +} + /* ************************************** */ void view3d_align_axis_to_vector(View3D *v3d, RegionView3D *rv3d, int axisidx, float vec[3]) |