Merging r41555 through r41563 from trunk into soc-2011-tomato
[blender.git] / source / blender / editors / space_view3d / drawobject.c
index 63a1d7f7b4f49e02435e555018e2768397ae7e36..b6bed7f849cc482491ba8358063022f99051e3a6 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id$
- *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
@@ -57,6 +55,7 @@
 #include "BLI_utildefines.h"
 
 #include "BKE_anim.h"                  //for the where_on_path function
+#include "BKE_camera.h"
 #include "BKE_constraint.h" // for the get_constraint_target function
 #include "BKE_curve.h"
 #include "BKE_DerivedMesh.h"
@@ -76,6 +75,8 @@
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
 #include "BKE_unit.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
 
 #include "smoke_API.h"
 
 
 
 /* this condition has been made more complex since editmode can draw textures */
-#define CHECK_OB_DRAWTEXTURE(vd, dt) \
-((vd->drawtype==OB_TEXTURE && dt>OB_SOLID) || \
+#define CHECK_OB_DRAWTEXTURE(vd, dt)                                          \
+       ((vd->drawtype==OB_TEXTURE && dt>OB_SOLID) ||                             \
        (vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX))
 
-static void draw_bounding_volume(Scene *scene, Object *ob);
+static void draw_bounding_volume(Scene *scene, Object *ob, char type);
 
 static void drawcube_size(float size);
 static void drawcircle_size(float size);
@@ -202,6 +203,40 @@ static void view3d_project_short_noclip(ARegion *ar, const float vec[3], short *
        }
 }
 
+/* same as view3d_project_short_clip but use persmat instead of persmatob for projection */
+static void view3d_project_short_clip_persmat(ARegion *ar, float *vec, short *adr, int local)
+{
+       RegionView3D *rv3d= ar->regiondata;
+       float fx, fy, vec4[4];
+
+       adr[0]= IS_CLIPPED;
+
+       /* clipplanes in eye space */
+       if(rv3d->rflag & RV3D_CLIPPING) {
+               if(ED_view3d_test_clipping(rv3d, vec, local))
+                       return;
+       }
+
+       copy_v3_v3(vec4, vec);
+       vec4[3]= 1.0;
+
+       mul_m4_v4(rv3d->persmat, vec4);
+
+       /* clipplanes in window space */
+       if( vec4[3] > (float)BL_NEAR_CLIP ) {   /* is the NEAR clipping cutoff for picking */
+               fx= (ar->winx/2)*(1 + vec4[0]/vec4[3]);
+
+               if( fx>0 && fx<ar->winx) {
+
+                       fy= (ar->winy/2)*(1 + vec4[1]/vec4[3]);
+
+                       if(fy > 0.0f && fy < (float)ar->winy) {
+                               adr[0]= (short)floorf(fx);
+                               adr[1]= (short)floorf(fy);
+                       }
+               }
+       }
+}
 /* ************************ */
 
 /* check for glsl drawing */
@@ -733,7 +768,12 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
        for(vos= strings->first; vos; vos= vos->next) {
                if(mat && !(vos->flag & V3D_CACHE_TEXT_WORLDSPACE))
                        mul_m4_v3(mat, vos->vec);
-               view3d_project_short_clip(ar, vos->vec, vos->sco, 0);
+
+               if(vos->flag&V3D_CACHE_TEXT_GLOBALSPACE)
+                       view3d_project_short_clip_persmat(ar, vos->vec, vos->sco, 0);
+               else
+                       view3d_project_short_clip(ar, vos->vec, vos->sco, 0);
+
                if(vos->sco[0]!=IS_CLIPPED)
                        tot++;
        }
@@ -765,7 +805,7 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
                else glDepthMask(0);
                
                for(vos= strings->first; vos; vos= vos->next) {
-#if 0       // too slow, reading opengl info while drawing is very bad, better to see if we cn use the zbuffer while in pixel space - campbell
+#if 0       // too slow, reading opengl info while drawing is very bad, better to see if we can use the zbuffer while in pixel space - campbell
                        if(v3d->zbuf && (vos->flag & V3D_CACHE_TEXT_ZBUF)) {
                                gluProject(vos->vec[0], vos->vec[1], vos->vec[2], mats.modelview, mats.projection, (GLint *)mats.viewport, &ux, &uy, &uz);
                                glReadPixels(ar->winrct.xmin+vos->mval[0]+vos->xoffs, ar->winrct.ymin+vos->mval[1], 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
@@ -1365,19 +1405,203 @@ float view3d_camera_border_hack_col[4];
 short view3d_camera_border_hack_test= FALSE;
 #endif
 
+/* ****************** draw clip data *************** */
+
+static void draw_bundle_sphere(void)
+{
+       static GLuint displist= 0;
+
+       if (displist == 0) {
+               GLUquadricObj *qobj;
+
+               displist= glGenLists(1);
+               glNewList(displist, GL_COMPILE);
+
+               qobj= gluNewQuadric();
+               gluQuadricDrawStyle(qobj, GLU_FILL);
+               glShadeModel(GL_SMOOTH);
+               gluSphere(qobj, 0.05, 8, 8);
+               glShadeModel(GL_FLAT);
+               gluDeleteQuadric(qobj);
+
+               glEndList();
+       }
+
+       glCallList(displist);
+}
+
+static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieClip *clip, int flag)
+{
+       MovieTracking *tracking= &clip->tracking;
+       MovieTrackingTrack *track;
+       float mat[4][4], imat[4][4], curcol[4];
+       unsigned char col[4], scol[4];
+       int bundlenr= 1;
+
+       if((v3d->flag2&V3D_SHOW_RECONSTRUCTION)==0)
+               return;
+
+       if(v3d->flag2&V3D_RENDER_OVERRIDE)
+               return;
+
+       glGetFloatv(GL_CURRENT_COLOR, curcol);
+
+       UI_GetThemeColor4ubv(TH_TEXT, col);
+       UI_GetThemeColor4ubv(TH_SELECT, scol);
+
+       BKE_get_tracking_mat(scene, base->object, mat);
+
+       glEnable(GL_LIGHTING);
+       glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+       glEnable(GL_COLOR_MATERIAL);
+       glShadeModel(GL_SMOOTH);
+
+       /* current ogl matrix is translated in camera space, bundles should
+          be rendered in world space, so camera matrix should be "removed"
+          from current ogl matrix */
+       invert_m4_m4(imat, base->object->obmat);
+
+       glPushMatrix();
+       glMultMatrixf(imat);
+       glMultMatrixf(mat);
+
+       for ( track= tracking->tracks.first; track; track= track->next) {
+               int selected= track->flag&SELECT || track->pat_flag&SELECT || track->search_flag&SELECT;
+               if((track->flag&TRACK_HAS_BUNDLE)==0)
+                       continue;
+
+               if(flag&DRAW_PICKING)
+                       glLoadName(base->selcol + (bundlenr<<16));
+
+               glPushMatrix();
+                       glTranslatef(track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
+                       glScalef(v3d->bundle_size/0.05, v3d->bundle_size/0.05, v3d->bundle_size/0.05);
+
+                       if(v3d->drawtype==OB_WIRE) {
+                               glDisable(GL_LIGHTING);
+                               glDepthMask(0);
+
+                               if(selected) {
+                                       if(base==BASACT) UI_ThemeColor(TH_ACTIVE);
+                                       else UI_ThemeColor(TH_SELECT);
+                               } else {
+                                       if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color);
+                                       else UI_ThemeColor(TH_WIRE);
+                               }
+
+                               drawaxes(0.05f, v3d->bundle_drawtype);
+
+                               glDepthMask(1);
+                               glEnable(GL_LIGHTING);
+                       } else if(v3d->drawtype>OB_WIRE) {
+                               if(v3d->bundle_drawtype==OB_EMPTY_SPHERE) {
+                                       /* selection outline */
+                                       if(selected) {
+                                               if(base==BASACT) UI_ThemeColor(TH_ACTIVE);
+                                               else UI_ThemeColor(TH_SELECT);
+
+                                               glDepthMask(0);
+                                               glLineWidth(2.f);
+                                               glDisable(GL_LIGHTING);
+                                               glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
+                                               draw_bundle_sphere();
+
+                                               glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+                                               glEnable(GL_LIGHTING);
+                                               glLineWidth(1.f);
+                                               glDepthMask(1);
+                                       }
+
+                                       if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color);
+                                       else UI_ThemeColor(TH_BUNDLE_SOLID);
+
+                                       draw_bundle_sphere();
+                               } else {
+                                       glDisable(GL_LIGHTING);
+                                       glDepthMask(0);
+
+                                       if(selected) {
+                                               if(base==BASACT) UI_ThemeColor(TH_ACTIVE);
+                                               else UI_ThemeColor(TH_SELECT);
+                                       } else {
+                                               if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color);
+                                               else UI_ThemeColor(TH_WIRE);
+                                       }
+
+                                       drawaxes(0.05f, v3d->bundle_drawtype);
+
+                                       glDepthMask(1);
+                                       glEnable(GL_LIGHTING);
+                               }
+                       }
+
+               glPopMatrix();
+
+               if((flag & DRAW_PICKING)==0 && (v3d->flag2&V3D_SHOW_BUNDLENAME)) {
+                       float pos[3];
+                       unsigned char tcol[4];
+
+                       if(selected) memcpy(tcol, scol, sizeof(tcol));
+                       else memcpy(tcol, col, sizeof(tcol));
+
+                       mul_v3_m4v3(pos, mat, track->bundle_pos);
+                       view3d_cached_text_draw_add(pos, track->name, 10, V3D_CACHE_TEXT_GLOBALSPACE, tcol);
+               }
+
+               bundlenr++;
+       }
+
+       if((flag & DRAW_PICKING)==0) {
+               if(v3d->flag2&V3D_SHOW_CAMERAPATH && clip->tracking.reconstruction.camnr) {
+                       int a= 0;
+                       MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
+                       MovieReconstructedCamera *camera= tracking->reconstruction.cameras;
+
+                       glDisable(GL_LIGHTING);
+                       UI_ThemeColor(TH_CAMERA_PATH);
+                       glLineWidth(2.0f);
+
+                       glBegin(GL_LINE_STRIP);
+                               for(a= 0; a<reconstruction->camnr; a++, camera++) {
+                                       glVertex3f(camera->mat[3][0], camera->mat[3][1], camera->mat[3][2]);
+                               }
+                       glEnd();
+
+                       glLineWidth(1.0f);
+                       glEnable(GL_LIGHTING);
+               }
+       }
+
+       glPopMatrix();
+
+       /* restore */
+       glShadeModel(GL_FLAT);
+       glDisable(GL_COLOR_MATERIAL);
+       glDisable(GL_LIGHTING);
+
+       glColor4fv(curcol);
+
+       if(flag&DRAW_PICKING)
+               glLoadName(base->selcol);
+}
+
 /* flag similar to draw_object() */
-static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, int flag)
+static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int flag)
 {
        /* a standing up pyramid with (0,0,0) as top */
        Camera *cam;
-       float vec[8][4], facx, facy, depth, aspx, aspy, caspx, caspy, shx, shy;
+       Object *ob= base->object;
+       float tvec[3];
+       float vec[4][3], asp[2], shift[2], scale[3];
        int i;
        float drawsize;
        const short is_view= (rv3d->persp==RV3D_CAMOB && ob==v3d->camera);
+       MovieClip *clip= object_get_movieclip(scene, base->object, 0);
 
-       const float scax= 1.0f / len_v3(ob->obmat[0]);
-       const float scay= 1.0f / len_v3(ob->obmat[1]);
-       const float scaz= 1.0f / len_v3(ob->obmat[2]);
+       /* draw data for movie clip set as active for scene */
+       if(clip)
+               draw_viewport_reconstruction(scene, base, v3d, clip, flag);
 
 #ifdef VIEW3D_CAMERA_BORDER_HACK
        if(is_view && !(G.f & G_PICKSEL)) {
@@ -1388,82 +1612,43 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob
 #endif
 
        cam= ob->data;
-       aspx= (float) scene->r.xsch*scene->r.xasp;
-       aspy= (float) scene->r.ysch*scene->r.yasp;
 
-       if(aspx < aspy) {
-               caspx= aspx / aspy;
-               caspy= 1.0;
-       }
-       else {
-               caspx= 1.0;
-               caspy= aspy / aspx;
-       }
-       
-       glDisable(GL_LIGHTING);
-       glDisable(GL_CULL_FACE);
-       
-       if(cam->type==CAM_ORTHO) {
-               facx= 0.5f * cam->ortho_scale * caspx * scax;
-               facy= 0.5f * cam->ortho_scale * caspy * scay;
-               shx= cam->shiftx * cam->ortho_scale * scax;
-               shy= cam->shifty * cam->ortho_scale * scay;
-               depth= is_view ? -((cam->clipsta * scaz) + 0.1f) : - cam->drawsize * cam->ortho_scale * scaz;
-               
-               drawsize= 0.5f * cam->ortho_scale;
-       }
-       else {
-               /* that way it's always visible - clipsta+0.1 */
-               float fac;
-               drawsize= cam->drawsize / ((scax + scay + scaz) / 3.0f);
+       scale[0]= 1.0f / len_v3(ob->obmat[0]);
+       scale[1]= 1.0f / len_v3(ob->obmat[1]);
+       scale[2]= 1.0f / len_v3(ob->obmat[2]);
 
-               if(is_view) {
-                       /* fixed depth, variable size (avoids exceeding clipping range) */
-                       depth = -(cam->clipsta + 0.1f);
-                       fac = depth / (cam->lens/-16.0f * scaz);
-               }
-               else {
-                       /* fixed size, variable depth (stays a reasonable size in the 3D view) */
-                       depth= drawsize * cam->lens/-16.0f * scaz;
-                       fac= drawsize;
-               }
+       camera_view_frame_ex(scene, cam, cam->drawsize, is_view, scale,
+                            asp, shift, &drawsize, vec);
 
-               facx= fac * caspx * scax;
-               facy= fac * caspy * scay;
-               shx= cam->shiftx*fac*2 * scax;
-               shy= cam->shifty*fac*2 * scay;
-       }
-       
-       vec[0][0]= 0.0; vec[0][1]= 0.0; vec[0][2]= 0.0;
-       vec[1][0]= shx + facx; vec[1][1]= shy + facy; vec[1][2]= depth;
-       vec[2][0]= shx + facx; vec[2][1]= shy - facy; vec[2][2]= depth;
-       vec[3][0]= shx - facx; vec[3][1]= shy - facy; vec[3][2]= depth;
-       vec[4][0]= shx - facx; vec[4][1]= shy + facy; vec[4][2]= depth;
+       glDisable(GL_LIGHTING);
+       glDisable(GL_CULL_FACE);
 
        /* camera frame */
        glBegin(GL_LINE_LOOP);
-               glVertex3fv(vec[1]); 
-               glVertex3fv(vec[2]); 
-               glVertex3fv(vec[3]); 
-               glVertex3fv(vec[4]);
+       glVertex3fv(vec[0]);
+       glVertex3fv(vec[1]);
+       glVertex3fv(vec[2]);
+       glVertex3fv(vec[3]);
        glEnd();
 
        if(is_view)
                return;
 
+       zero_v3(tvec);
+
        /* center point to camera frame */
        glBegin(GL_LINE_STRIP);
-               glVertex3fv(vec[2]); 
-               glVertex3fv(vec[0]);
-               glVertex3fv(vec[1]);
-               glVertex3fv(vec[4]);
-               glVertex3fv(vec[0]);
-               glVertex3fv(vec[3]); 
+       glVertex3fv(vec[1]);
+       glVertex3fv(tvec);
+       glVertex3fv(vec[0]);
+       glVertex3fv(vec[3]);
+       glVertex3fv(tvec);
+       glVertex3fv(vec[2]);
        glEnd();
 
 
        /* arrow on top */
-       vec[0][2]= depth;
+       tvec[2]= vec[1][2]; /* copy the depth */
 
 
        /* draw an outline arrow for inactive cameras and filled
@@ -1474,16 +1659,16 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob
                else if (i==1 && (ob == v3d->camera)) glBegin(GL_TRIANGLES);
                else break;
 
-               vec[0][0]= shx + ((-0.7f * drawsize) * scax);
-               vec[0][1]= shy + ((drawsize * (caspy + 0.1f)) * scay);
-               glVertex3fv(vec[0]); /* left */
+               tvec[0]= shift[0] + ((-0.7f * drawsize) * scale[0]);
+               tvec[1]= shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]);
+               glVertex3fv(tvec); /* left */
                
-               vec[0][0]= shx + ((0.7f * drawsize) * scax);
-               glVertex3fv(vec[0]); /* right */
+               tvec[0]= shift[0] + ((0.7f * drawsize) * scale[0]);
+               glVertex3fv(tvec); /* right */
                
-               vec[0][0]= shx;
-               vec[0][1]= shy + ((1.1f * drawsize * (caspy + 0.7f)) * scay);
-               glVertex3fv(vec[0]); /* top */
+               tvec[0]= shift[0];
+               tvec[1]= shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]);
+               glVertex3fv(tvec); /* top */
        
                glEnd();
        }
@@ -1817,7 +2002,9 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *ce
        if (efa && efa->h==0 && efa->fgonf!=EM_FGON) {
                view3d_project_short_clip(data->vc.ar, cent, s, 1);
 
-               data->func(data->userData, efa, s[0], s[1], index);
+               if (s[0] != IS_CLIPPED) {
+                       data->func(data->userData, efa, s[0], s[1], index);
+               }
        }
 }
 
@@ -2738,15 +2925,14 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
        totface = dm->getNumFaces(dm);
        
        /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */
-       if(dt!=OB_SHADED)
-               glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
+       glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
 
                // Unwanted combination.
        if (is_paint_sel) draw_wire = 0;
 
        if(dt==OB_BOUNDBOX) {
                if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_WIRE)==0)
-                       draw_bounding_volume(scene, ob);
+                       draw_bounding_volume(scene, ob, ob->boundtype);
        }
        else if(hasHaloMat || (totface==0 && totedge==0)) {
                glPointSize(1.5);
@@ -2856,7 +3042,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                                dm->drawLooseEdges(dm);
                }
        }
-       else if(dt==OB_SHADED) {
+       else if(dt==OB_PAINT) {
                if(ob==OBACT) {
                        if(ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
                                /* enforce default material settings */
@@ -5145,8 +5331,6 @@ static void drawspiral(const float cent[3], float rad, float tmat[][4], int star
                }
        }
        else {
-               a= 0;
-
                fac= (float)(CIRCLE_RESOL-1) * tot_inv;
                x= sinval[start] * fac;
                y= cosval[start] * fac;
@@ -5514,7 +5698,7 @@ static void get_local_bounds(Object *ob, float center[3], float size[3])
 }
 #endif
 
-static void draw_bb_quadric(BoundBox *bb, short type)
+static void draw_bb_quadric(BoundBox *bb, char type)
 {
        float size[3], cent[3];
        GLUquadricObj *qobj = gluNewQuadric(); 
@@ -5553,7 +5737,7 @@ static void draw_bb_quadric(BoundBox *bb, short type)
        gluDeleteQuadric(qobj); 
 }
 
-static void draw_bounding_volume(Scene *scene, Object *ob)
+static void draw_bounding_volume(Scene *scene, Object *ob, char type)
 {
        BoundBox *bb= NULL;
        
@@ -5579,8 +5763,8 @@ static void draw_bounding_volume(Scene *scene, Object *ob)
        
        if(bb==NULL) return;
        
-       if(ob->boundtype==OB_BOUND_BOX) draw_box(bb->vec);
-       else draw_bb_quadric(bb, ob->boundtype);
+       if(type==OB_BOUND_BOX) draw_box(bb->vec);
+       else draw_bb_quadric(bb, type);
        
 }
 
@@ -5999,7 +6183,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        }
 
        /* maximum drawtype */
-       dt= MIN2(v3d->drawtype, ob->dt);
+       dt= v3d->drawtype;
+       if(dt==OB_RENDER) dt= OB_SOLID;
+       dt= MIN2(dt, ob->dt);
        if(v3d->zbuf==0 && dt>OB_WIRE) dt= OB_WIRE;
        dtx= 0;
 
@@ -6014,7 +6200,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                                        dt= OB_SOLID;
                                }
                                else {
-                                       dt= OB_SHADED;
+                                       dt= OB_PAINT;
                                }
 
                                glEnable(GL_DEPTH_TEST);
@@ -6144,7 +6330,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        }
                        else if(dt==OB_BOUNDBOX) {
                                if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_WIRE)==0)
-                                       draw_bounding_volume(scene, ob);
+                                       draw_bounding_volume(scene, ob, ob->boundtype);
                        }
                        else if(ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb))
                                empty_object= drawDispList(scene, v3d, rv3d, base, dt);
@@ -6160,7 +6346,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        }
                        else if(dt==OB_BOUNDBOX) {
                                if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_WIRE)==0)
-                                       draw_bounding_volume(scene, ob);
+                                       draw_bounding_volume(scene, ob, ob->boundtype);
                        }
                        else if(ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) {
                                empty_object= drawDispList(scene, v3d, rv3d, base, dt);
@@ -6177,7 +6363,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                                drawmball(scene, v3d, rv3d, base, dt);
                        else if(dt==OB_BOUNDBOX) {
                                if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_WIRE)==0)
-                                       draw_bounding_volume(scene, ob);
+                                       draw_bounding_volume(scene, ob, ob->boundtype);
                        }
                        else 
                                empty_object= drawmball(scene, v3d, rv3d, base, dt);
@@ -6201,7 +6387,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        break;
                case OB_CAMERA:
                        if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0 || (rv3d->persp==RV3D_CAMOB && v3d->camera==ob)) /* special exception for active camera */
-                               drawcamera(scene, v3d, rv3d, ob, flag);
+                               drawcamera(scene, v3d, rv3d, base, flag);
                        break;
                case OB_SPEAKER:
                        if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0)
@@ -6419,6 +6605,14 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        }
                }
 
+               if(ob->gameflag & OB_BOUNDS) {
+                       if(ob->boundtype!=ob->collision_boundtype || (dtx & OB_BOUNDBOX)==0) {
+                               setlinestyle(2);
+                               draw_bounding_volume(scene, ob, ob->collision_boundtype);
+                               setlinestyle(0);
+                       }
+               }
+
                /* draw extra: after normal draw because of makeDispList */
                if(dtx && (G.f & G_RENDER_OGL)==0) {
 
@@ -6426,8 +6620,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                                drawaxes(1.0f, OB_ARROWS);
                        }
                        if(dtx & OB_BOUNDBOX) {
-                               if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0)
-                                       draw_bounding_volume(scene, ob);
+                               draw_bounding_volume(scene, ob, ob->boundtype);
                        }
                        if(dtx & OB_TEXSPACE) drawtexspace(ob);
                        if(dtx & OB_DRAWNAME) {
@@ -6765,7 +6958,10 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
                }
                else {
                        Mesh *me= ob->data;
-                       if(me->editflag & ME_EDIT_VERT_SEL) {
+                       if(     (me->editflag & ME_EDIT_VERT_SEL) &&
+                               /* currently vertex select only supports weight paint */
+                               (ob->mode & OB_MODE_WEIGHT_PAINT))
+                       {
                                DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
                                glColor3ub(0, 0, 0);