diff options
Diffstat (limited to 'source/blender/editors/space_view3d/drawobject.c')
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 1233 |
1 files changed, 723 insertions, 510 deletions
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 05490e2fce1..60ae91e7a89 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -37,9 +37,10 @@ #include "IMB_imbuf.h" -#include "MTC_matrixops.h" + #include "DNA_armature_types.h" +#include "DNA_boid_types.h" #include "DNA_camera_types.h" #include "DNA_curve_types.h" #include "DNA_constraint_types.h" // for drawing constraint @@ -58,6 +59,7 @@ #include "DNA_space_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "DNA_smoke_types.h" #include "DNA_userdef_types.h" #include "DNA_view3d_types.h" #include "DNA_world_types.h" @@ -85,9 +87,14 @@ #include "BKE_mball.h" #include "BKE_modifier.h" #include "BKE_object.h" +#include "BKE_paint.h" #include "BKE_particle.h" +#include "BKE_pointcache.h" #include "BKE_property.h" +#include "BKE_smoke.h" +#include "BKE_unit.h" #include "BKE_utildefines.h" +#include "smoke_API.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -122,11 +129,6 @@ (((vd->drawtype==OB_SOLID) && (dt>=OB_SOLID) && (vd->flag2 & V3D_SOLID_TEX) && (vd->flag & V3D_ZBUF_SELECT)) == 0) \ ) - -/* pretty stupid */ -/* editmball.c */ -extern ListBase editelems; - static void draw_bounding_volume(Scene *scene, Object *ob); static void drawcube_size(float size); @@ -212,11 +214,10 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt) return 0; if(!CHECK_OB_DRAWTEXTURE(v3d, dt)) return 0; - if(ob==OBACT && (G.f & G_WEIGHTPAINT)) + if(ob==OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT)) return 0; - return ((G.fileflags & G_FILE_GAME_MAT) && - (G.fileflags & G_FILE_GAME_MAT_GLSL) && (dt >= OB_SHADED)); + return (scene->gm.matmode == GAME_MAT_GLSL) && (dt >= OB_SHADED); } static int check_material_alpha(Base *base, Mesh *me, int glsl) @@ -433,11 +434,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; @@ -495,23 +496,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; @@ -520,22 +530,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); @@ -543,16 +554,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(); @@ -561,62 +578,14 @@ static void view3d_object_text_draw(View3D *v3d, ARegion *ar) glEnable(GL_CLIP_PLANE0+a); } - if(strings.first) - BLI_freelistN(&strings); -} - -void drawsolidcube(float size) -{ - float n[3]; - - glPushMatrix(); - glScalef(size, size, size); - - n[0]=0; n[1]=0; n[2]=0; - glBegin(GL_QUADS); - n[0]= -1.0; - glNormal3fv(n); - glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]); - n[0]=0; - glEnd(); - - glBegin(GL_QUADS); - n[1]= -1.0; - glNormal3fv(n); - glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]); - n[1]=0; - glEnd(); - - glBegin(GL_QUADS); - n[0]= 1.0; - glNormal3fv(n); - glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]); - n[0]=0; - glEnd(); - - glBegin(GL_QUADS); - n[1]= 1.0; - glNormal3fv(n); - glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]); - n[1]=0; - glEnd(); - - glBegin(GL_QUADS); - n[2]= 1.0; - glNormal3fv(n); - glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]); - n[2]=0; - glEnd(); - - glBegin(GL_QUADS); - n[2]= -1.0; - glNormal3fv(n); - glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]); - glEnd(); + if(strings->first) + BLI_freelistN(strings); - glPopMatrix(); + CachedTextLevel--; } +/* ******************** primitive drawing ******************* */ + static void drawcube(void) { @@ -1175,7 +1144,7 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob Mat4Ortho(vec); wmMultMatrix(vec); - MTC_Mat4SwapMat4(rv3d->persmat, tmat); + Mat4SwapMat4(rv3d->persmat, tmat); wmGetSingleMatrix(rv3d->persmat); if(cam->flag & CAM_SHOWLIMITS) { @@ -1188,7 +1157,7 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob if(cam->flag & CAM_SHOWMIST) if(wrld) draw_limit_line(wrld->miststa, wrld->miststa+wrld->mistdist, 0xFFFFFF); - MTC_Mat4SwapMat4(rv3d->persmat, tmat); + Mat4SwapMat4(rv3d->persmat, tmat); } } } @@ -1249,7 +1218,7 @@ static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, i if(use_wcol) { float col[3]; - MDeformWeight *mdw= get_defweight (lt->dvert+index, use_wcol-1); + MDeformWeight *mdw= ED_vgroup_weight_get (lt->dvert+index, use_wcol-1); weight_to_rgb(mdw?mdw->weight:0.0f, col, col+1, col+2); glColor3fv(col); @@ -1443,12 +1412,13 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb int i; for (nu= cu->editnurb->first; nu; nu=nu->next) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { for (i=0; i<nu->pntsu; i++) { BezTriple *bezt = &nu->bezt[i]; if(bezt->hide==0) { - if (G.f & G_HIDDENHANDLES) { + + if(cu->drawflag & CU_HIDE_HANDLES) { view3d_project_short_clip(vc->ar, bezt->vec[1], s); if (s[0] != IS_CLIPPED) func(userData, nu, NULL, bezt, 1, s[0], s[1]); @@ -1902,7 +1872,7 @@ static void draw_em_fancy_edges(Scene *scene, View3D *v3d, Mesh *me, DerivedMesh } } -static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, EditMesh *em) +static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, EditMesh *em, UnitSettings *unit) { Mesh *me= ob->data; EditEdge *eed; @@ -1912,18 +1882,20 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E char val[32]; /* Stores the measurement display text here */ char conv_float[5]; /* Use a float conversion matching the grid size */ float area, col[3]; /* area of the face, color of the text to draw */ - + float grid= unit->system ? unit->scale_length : v3d->grid; + int do_split= unit->flag & USER_UNIT_OPT_SPLIT; if(G.f & (G_RENDER_OGL|G_RENDER_SHADOW)) return; /* make the precission of the pronted value proportionate to the gridsize */ - if ((v3d->grid) < 0.01) + + if (grid < 0.01f) strcpy(conv_float, "%.6f"); - else if ((v3d->grid) < 0.1) + else if (grid < 0.1f) strcpy(conv_float, "%.5f"); - else if ((v3d->grid) < 1.0) + else if (grid < 1.0f) strcpy(conv_float, "%.4f"); - else if ((v3d->grid) < 10.0) + else if (grid < 10.0f) strcpy(conv_float, "%.3f"); else strcpy(conv_float, "%.2f"); @@ -1932,13 +1904,13 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E if(v3d->zbuf && (v3d->flag & V3D_ZBUF_SELECT)==0) glDisable(GL_DEPTH_TEST); - if(v3d->zbuf) bglPolygonOffset(rv3d->dist, 5.0); + if(v3d->zbuf) bglPolygonOffset(rv3d->dist, 5.0f); if(me->drawflag & ME_DRAW_EDGELEN) { UI_GetThemeColor3fv(TH_TEXT, col); /* make color a bit more red */ - if(col[0]> 0.5) {col[1]*=0.7; col[2]*= 0.7;} - else col[0]= col[0]*0.7 + 0.3; + if(col[0]> 0.5f) {col[1]*=0.7f; col[2]*= 0.7f;} + else col[0]= col[0]*0.7f + 0.3f; glColor3fv(col); for(eed= em->edges.first; eed; eed= eed->next) { @@ -1947,17 +1919,20 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E VECCOPY(v1, eed->v1->co); VECCOPY(v2, eed->v2->co); - x= 0.5*(v1[0]+v2[0]); - y= 0.5*(v1[1]+v2[1]); - z= 0.5*(v1[2]+v2[2]); + x= 0.5f*(v1[0]+v2[0]); + y= 0.5f*(v1[1]+v2[1]); + z= 0.5f*(v1[2]+v2[2]); if(v3d->flag & V3D_GLOBAL_STATS) { Mat4MulVecfl(ob->obmat, v1); Mat4MulVecfl(ob->obmat, v2); } + if(unit->system) + bUnit_AsString(val, sizeof(val), VecLenf(v1, v2)*unit->scale_length, 3, unit->system, B_UNIT_LENGTH, do_split, FALSE); + else + sprintf(val, conv_float, VecLenf(v1, v2)); - 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); } } } @@ -1967,8 +1942,8 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E UI_GetThemeColor3fv(TH_TEXT, col); /* make color a bit more green */ - if(col[1]> 0.5) {col[0]*=0.7; col[2]*= 0.7;} - else col[1]= col[1]*0.7 + 0.3; + if(col[1]> 0.5f) {col[0]*=0.7f; col[2]*= 0.7f;} + else col[1]= col[1]*0.7f + 0.3f; glColor3fv(col); for(efa= em->faces.first; efa; efa= efa->next) { @@ -1991,8 +1966,12 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E else area = AreaT3Dfl(v1, v2, v3); - sprintf(val, conv_float, area); - view3d_object_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0); + if(unit->system) + bUnit_AsString(val, sizeof(val), area*unit->scale_length, 3, unit->system, B_UNIT_LENGTH, do_split, FALSE); // XXX should be B_UNIT_AREA + else + sprintf(val, conv_float, area); + + view3d_cached_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0); } } } @@ -2002,8 +1981,8 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E UI_GetThemeColor3fv(TH_TEXT, col); /* make color a bit more blue */ - if(col[2]> 0.5) {col[0]*=0.7; col[1]*= 0.7;} - else col[2]= col[2]*0.7 + 0.3; + if(col[2]> 0.5f) {col[0]*=0.7f; col[1]*= 0.7f;} + else col[2]= col[2]*0.7f + 0.3f; glColor3fv(col); for(efa= em->faces.first; efa; efa= efa->next) { @@ -2032,31 +2011,31 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E if( (e4->f & e1->f & SELECT) || (G.moving && (efa->v1->f & SELECT)) ) { /* Vec 1 */ - sprintf(val,"%.3f", VecAngle3(v4, v1, v2)); - VecLerpf(fvec, efa->cent, efa->v1->co, 0.8); - view3d_object_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0); + sprintf(val,"%.3f", RAD2DEG(VecAngle3(v4, v1, v2))); + VecLerpf(fvec, efa->cent, efa->v1->co, 0.8f); + 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)); - VecLerpf(fvec, efa->cent, efa->v2->co, 0.8); - view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); + sprintf(val,"%.3f", RAD2DEG(VecAngle3(v1, v2, v3))); + VecLerpf(fvec, efa->cent, efa->v2->co, 0.8f); + 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)); - VecLerpf(fvec, efa->cent, efa->v3->co, 0.8); - view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); + sprintf(val,"%.3f", RAD2DEG(VecAngle3(v2, v3, v1))); + VecLerpf(fvec, efa->cent, efa->v3->co, 0.8f); + 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)); - VecLerpf(fvec, efa->cent, efa->v4->co, 0.8); - view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); + sprintf(val,"%.3f", RAD2DEG(VecAngle3(v3, v4, v1))); + VecLerpf(fvec, efa->cent, efa->v4->co, 0.8f); + view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); } } } @@ -2064,7 +2043,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E if(v3d->zbuf) { glEnable(GL_DEPTH_TEST); - bglPolygonOffset(rv3d->dist, 0.0); + bglPolygonOffset(rv3d->dist, 0.0f); } } @@ -2149,7 +2128,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object } } - if((me->drawflag & (ME_DRAWFACES)) || FACESEL_PAINT_TEST) { /* transp faces */ + if((me->drawflag & (ME_DRAWFACES)) || paint_facesel_test(ob)) { /* transp faces */ unsigned char col1[4], col2[4], col3[4]; UI_GetThemeColor4ubv(TH_FACE, (char *)col1); @@ -2237,7 +2216,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object } if(me->drawflag & (ME_DRAW_EDGELEN|ME_DRAW_FACEAREA|ME_DRAW_EDGEANG)) - draw_em_measure_stats(v3d, rv3d, ob, em); + draw_em_measure_stats(v3d, rv3d, ob, em, &scene->unit); } if(dt>OB_WIRE) { @@ -2308,7 +2287,7 @@ static void draw_mesh_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); // Unwanted combination. - if (ob==OBACT && FACESEL_PAINT_TEST) draw_wire = 0; + if (ob==OBACT && paint_facesel_test(ob)) draw_wire = 0; if(dt==OB_BOUNDBOX) { draw_bounding_volume(scene, ob); @@ -2321,12 +2300,12 @@ static void draw_mesh_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base else if(dt==OB_WIRE || totface==0) { draw_wire = 1; /* draw wire only, no depth buffer stuff */ } - else if( (ob==OBACT && (G.f & G_TEXTUREPAINT || FACESEL_PAINT_TEST)) || + else if( (ob==OBACT && (ob->mode & OB_MODE_TEXTURE_PAINT || paint_facesel_test(ob))) || CHECK_OB_DRAWTEXTURE(v3d, dt)) { - int faceselect= (ob==OBACT && FACESEL_PAINT_TEST); + int faceselect= (ob==OBACT && paint_facesel_test(ob)); - if ((v3d->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !(G.f&G_PICKSEL || FACESEL_PAINT_TEST) && !draw_wire) { + if ((v3d->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !(G.f&G_PICKSEL || paint_facesel_test(ob)) && !draw_wire) { draw_mesh_object_outline(v3d, ob, dm); } @@ -2380,7 +2359,7 @@ static void draw_mesh_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base if(ob==OBACT) { do_draw= 0; - if( (G.f & G_WEIGHTPAINT)) { + if(ob && ob->mode & OB_MODE_WEIGHT_PAINT) { /* enforce default material settings */ GPU_enable_material(0, NULL); @@ -2400,12 +2379,13 @@ static void draw_mesh_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base GPU_disable_material(); } - else if((G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) && me->mcol) { - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 1); - } - else if(G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) { - glColor3f(1.0f, 1.0f, 1.0f); - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 0); + else if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_TEXTURE_PAINT)) { + if(me->mcol) + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 1); + else { + glColor3f(1.0f, 1.0f, 1.0f); + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 0); + } } else do_draw= 1; } @@ -2515,11 +2495,13 @@ static int draw_mesh_object(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base if(dt>OB_WIRE) { // no transp in editmode, the fancy draw over goes bad then glsl = draw_glsl_material(scene, ob, v3d, dt); - GPU_set_object_materials(v3d, rv3d, scene, ob, glsl, NULL); + GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL); } draw_em_fancy(scene, v3d, rv3d, ob, em, cageDM, finalDM, dt); + GPU_end_object_materials(); + if (obedit!=ob && finalDM) finalDM->release(finalDM); } @@ -2534,17 +2516,19 @@ static int draw_mesh_object(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base check_alpha = check_material_alpha(base, me, glsl); if(dt==OB_SOLID || glsl) { - GPU_set_object_materials(v3d, rv3d, scene, ob, glsl, + GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, (check_alpha)? &do_alpha_pass: NULL); } draw_mesh_fancy(scene, v3d, rv3d, base, dt, flag); + + GPU_end_object_materials(); if(me->totvert==0) retval= 1; } } - /* GPU_set_object_materials checked if this is needed */ + /* GPU_begin_object_materials checked if this is needed */ if(do_alpha_pass) add_view3d_after(v3d, base, V3D_TRANSP, flag); return retval; @@ -2722,7 +2706,6 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl) glVertexPointer(3, GL_FLOAT, 0, dl->verts); glNormalPointer(GL_FLOAT, 0, dl->nors); glDrawElements(GL_QUADS, 4*dl->totindex, GL_UNSIGNED_INT, dl->index); - GPU_disable_material(); } break; @@ -2740,7 +2723,6 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl) glNormalPointer(GL_FLOAT, 0, dl->nors); glDrawElements(GL_TRIANGLES, 3*dl->parts, GL_UNSIGNED_INT, dl->index); - GPU_disable_material(); if(index3_nors_incr==0) glEnableClientState(GL_NORMAL_ARRAY); @@ -2754,8 +2736,6 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl) glNormalPointer(GL_FLOAT, 0, dl->nors); glDrawElements(GL_QUADS, 4*dl->parts, GL_UNSIGNED_INT, dl->index); - GPU_disable_material(); - break; } dl= dl->next; @@ -2838,7 +2818,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas if(solid) { dl= lb->first; if(dl==NULL) return 1; - + if(dl->nors==0) addnormalsDispList(ob, lb); index3_nors_incr= 0; @@ -2849,17 +2829,19 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas } else { if(draw_glsl_material(scene, ob, v3d, dt)) { - GPU_set_object_materials(v3d, rv3d, scene, ob, 1, NULL); + GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL); drawDispListsolid(lb, ob, 1); + GPU_end_object_materials(); } else if(dt == OB_SHADED) { if(ob->disp.first==0) shadeDispList(scene, base); drawDispListshaded(lb, ob); } else { - GPU_set_object_materials(v3d, rv3d, scene, ob, 0, NULL); + GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); drawDispListsolid(lb, ob, 0); + GPU_end_object_materials(); } if(cu->editnurb && cu->bevobj==NULL && cu->taperobj==NULL && cu->ext1 == 0.0 && cu->ext2 == 0.0) { cpack(0); @@ -2877,7 +2859,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas } break; case OB_SURF: - + lb= &((Curve *)ob->data)->disp; if(solid) { @@ -2887,18 +2869,19 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas if(dl->nors==NULL) addnormalsDispList(ob, lb); if(draw_glsl_material(scene, ob, v3d, dt)) { - GPU_set_object_materials(v3d, rv3d, scene, ob, 1, NULL); + GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL); drawDispListsolid(lb, ob, 1); + GPU_end_object_materials(); } else if(dt==OB_SHADED) { if(ob->disp.first==NULL) shadeDispList(scene, base); drawDispListshaded(lb, ob); } else { - GPU_set_object_materials(v3d, rv3d, scene, ob, 0, NULL); + GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); - drawDispListsolid(lb, ob, 0); + GPU_end_object_materials(); } } else { @@ -2915,8 +2898,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas if(solid) { if(draw_glsl_material(scene, ob, v3d, dt)) { - GPU_set_object_materials(v3d, rv3d, scene, ob, 1, NULL); + GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL); drawDispListsolid(lb, ob, 1); + GPU_end_object_materials(); } else if(dt == OB_SHADED) { dl= lb->first; @@ -2924,10 +2908,10 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas drawDispListshaded(lb, ob); } else { - GPU_set_object_materials(v3d, rv3d, scene, ob, 0, NULL); + GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); - drawDispListsolid(lb, ob, 0); + GPU_end_object_materials(); } } else{ @@ -2941,6 +2925,153 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas return retval; } +/* *********** drawing for particles ************* */ + +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]; + float *vd = pdd->vd; + float *cd = pdd->cd; + float ma_r=0.0f; + float ma_g=0.0f; + float ma_b=0.0f; + + if(pdd->ma_r) { + ma_r = *pdd->ma_r; + ma_g = *pdd->ma_g; + ma_b = *pdd->ma_b; + } + + switch(draw_as){ + case PART_DRAW_DOT: + { + if(vd) { + VECCOPY(vd,state->co) pdd->vd+=3; + } + if(cd) { + cd[0]=ma_r; + cd[1]=ma_g; + cd[2]=ma_b; + pdd->cd+=3; + } + break; + } + case PART_DRAW_CROSS: + case PART_DRAW_AXIS: + { + vec[0]=2.0f*pixsize; + vec[1]=vec[2]=0.0; + QuatMulVecf(state->rot,vec); + if(draw_as==PART_DRAW_AXIS) { + cd[1]=cd[2]=cd[4]=cd[5]=0.0; + cd[0]=cd[3]=1.0; + cd[6]=cd[8]=cd[9]=cd[11]=0.0; + cd[7]=cd[10]=1.0; + cd[13]=cd[12]=cd[15]=cd[16]=0.0; + cd[14]=cd[17]=1.0; + cd+=18; + + VECCOPY(vec2,state->co); + } + else { + if(cd) { + cd[0]=cd[3]=cd[6]=cd[9]=cd[12]=cd[15]=ma_r; + cd[1]=cd[4]=cd[7]=cd[10]=cd[13]=cd[16]=ma_g; + cd[2]=cd[5]=cd[8]=cd[11]=cd[14]=cd[17]=ma_b; + pdd->cd+=18; + } + VECSUB(vec2,state->co,vec); + } + + VECADD(vec,state->co,vec); + VECCOPY(pdd->vd,vec); pdd->vd+=3; + VECCOPY(pdd->vd,vec2); pdd->vd+=3; + + vec[1]=2.0f*pixsize; + vec[0]=vec[2]=0.0; + QuatMulVecf(state->rot,vec); + if(draw_as==PART_DRAW_AXIS){ + VECCOPY(vec2,state->co); + } + else VECSUB(vec2,state->co,vec); + + VECADD(vec,state->co,vec); + VECCOPY(pdd->vd,vec); pdd->vd+=3; + VECCOPY(pdd->vd,vec2); pdd->vd+=3; + + vec[2]=2.0f*pixsize; + vec[0]=vec[1]=0.0; + QuatMulVecf(state->rot,vec); + if(draw_as==PART_DRAW_AXIS){ + VECCOPY(vec2,state->co); + } + else VECSUB(vec2,state->co,vec); + + VECADD(vec,state->co,vec); + + VECCOPY(pdd->vd,vec); pdd->vd+=3; + VECCOPY(pdd->vd,vec2); pdd->vd+=3; + break; + } + case PART_DRAW_LINE: + { + VECCOPY(vec,state->vel); + Normalize(vec); + if(draw & PART_DRAW_VEL_LENGTH) + VecMulf(vec,VecLength(state->vel)); + VECADDFAC(pdd->vd,state->co,vec,-draw_line[0]); pdd->vd+=3; + VECADDFAC(pdd->vd,state->co,vec,draw_line[1]); pdd->vd+=3; + if(cd) { + cd[0]=cd[3]=ma_r; + cd[1]=cd[4]=ma_g; + cd[2]=cd[5]=ma_b; + pdd->cd+=6; + } + break; + } + case PART_DRAW_CIRC: + { + if(pdd->ma_r) + glColor3f(ma_r,ma_g,ma_b); + drawcircball(GL_LINE_LOOP, state->co, pixsize, imat); + break; + } + case PART_DRAW_BB: + { + float xvec[3], yvec[3], zvec[3], bb_center[3]; + if(cd) { + cd[0]=cd[3]=cd[6]=cd[9]=ma_r; + cd[1]=cd[4]=cd[7]=cd[10]=ma_g; + cd[2]=cd[5]=cd[8]=cd[11]=ma_b; + pdd->cd+=12; + } + + + VECCOPY(bb->vec, state->co); + VECCOPY(bb->vel, state->vel); + + psys_make_billboard(bb, xvec, yvec, zvec, bb_center); + + VECADD(pdd->vd,bb_center,xvec); + VECADD(pdd->vd,pdd->vd,yvec); pdd->vd+=3; + + VECSUB(pdd->vd,bb_center,xvec); + VECADD(pdd->vd,pdd->vd,yvec); pdd->vd+=3; + + VECSUB(pdd->vd,bb_center,xvec); + VECSUB(pdd->vd,pdd->vd,yvec); pdd->vd+=3; + + VECADD(pdd->vd,bb_center,xvec); + VECSUB(pdd->vd,pdd->vd,yvec); pdd->vd+=3; + + VECCOPY(pdd->nd, zvec); pdd->nd+=3; + VECCOPY(pdd->nd, zvec); pdd->nd+=3; + VECCOPY(pdd->nd, zvec); pdd->nd+=3; + VECCOPY(pdd->nd, zvec); pdd->nd+=3; + break; + } + } +} /* unified drawing of all new particle systems draw types except dupli ob & group */ /* mostly tries to use vertex arrays for speed */ @@ -2951,22 +3082,25 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas /* 5. start filling the arrays */ /* 6. draw the arrays */ /* 7. clean up */ -static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, ParticleSystem *psys, int dt) +static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, ParticleSystem *psys, int ob_dt) { Object *ob=base->object; ParticleSystemModifierData *psmd; + ParticleEditSettings *pset = PE_settings(scene); ParticleSettings *part; ParticleData *pars, *pa; ParticleKey state, *states=0; ParticleBillboardData bb; + ParticleSimulationData sim = {scene, ob, psys, NULL}; + ParticleDrawData *pdd = psys->pdd; Material *ma; - float vel[3], vec[3], vec2[3], imat[4][4], bb_center[3]; - float timestep, pixsize=1.0, pa_size, pa_time, r_tilt; + float vel[3], imat[4][4]; + float timestep, pixsize=1.0, pa_size, r_tilt, r_length; + float pa_time, pa_birthtime, pa_dietime, pa_health; float cfra= bsystem_time(scene, ob,(float)CFRA,0.0); - float *vdata=0, *vedata=0, *cdata=0, *ndata=0, *vd=0, *ved=0, *cd=0, *nd=0, xvec[3], yvec[3], zvec[3]; float ma_r=0.0f, ma_g=0.0f, ma_b=0.0f; - int a, totpart, totpoint=0, draw_as, totchild=0; - int select=ob->flag&SELECT, create_cdata=0; + int a, totpart, totpoint=0, totve=0, drawn, draw_as, totchild=0; + int select=ob->flag&SELECT, create_cdata=0, need_v=0; GLint polygonmode[2]; char val[32]; @@ -2982,24 +3116,21 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(pars==0) return; - // XXX what logic is this? - if(!scene->obedit && psys_in_edit_mode(scene, psys) - && psys->flag & PSYS_HAIR_DONE && part->draw_as==PART_DRAW_PATH) + /* don't draw normal paths in edit mode */ + if(psys_in_edit_mode(scene, psys) && (pset->flag & PE_DRAW_PART)==0) return; if(part->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_FIRST_KEYED){ - if(psys->flag&PSYS_KEYED){ - select=psys_count_keyed_targets(ob,psys); - if(psys->totkeyed==0) - return; - } + if(psys->flag&PSYS_KEYED){ + psys_count_keyed_targets(&sim); + if(psys->totkeyed==0) + return; } - else - return; } if(select){ @@ -3014,14 +3145,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv totchild=0; else totchild=psys->totchild*part->disp/100; - - ma= give_current_material(ob,part->omat); - if(ma) { - ma_r = ma->r; - ma_g = ma->g; - ma_b = ma->b; - } + ma= give_current_material(ob,part->omat); if(v3d->zbuf) glDepthMask(1); @@ -3029,16 +3154,21 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv cpack(0xFFFFFF); else 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); - - timestep= psys_get_timestep(part); - - wmLoadMatrix(rv3d->viewmat); + timestep= psys_get_timestep(&sim); if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) { float mat[4][4]; @@ -3053,8 +3183,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv else draw_as = part->draw_as; - if(part->flag&PART_GLOB_TIME) - cfra=bsystem_time(scene, 0, (float)CFRA, 0.0f); + //if(part->flag&PART_GLOB_TIME) + cfra=bsystem_time(scene, 0, (float)CFRA, 0.0f); if(draw_as==PART_DRAW_PATH && psys->pathcache==NULL) draw_as=PART_DRAW_DOT; @@ -3119,6 +3249,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv break; case PART_DRAW_PATH: break; + case PART_DRAW_LINE: + need_v=1; + break; } if(part->draw & PART_DRAW_SIZE && part->draw_as!=PART_DRAW_CIRC){ Mat4CpyMat4(imat, rv3d->viewinv); @@ -3130,56 +3263,80 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(draw_as && draw_as!=PART_DRAW_PATH) { int tot_vec_size = (totpart + totchild) * 3 * sizeof(float); + 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(pdd->tot_vec_size != tot_vec_size) + psys_free_pdd(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) - cdata = MEM_callocN(tot_vec_size * 6, "particle_cdata"); - vdata = MEM_callocN(tot_vec_size * 6, "particle_vdata"); + if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 6, "particle_cdata"); + if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 6, "particle_vdata"); break; case PART_DRAW_LINE: if(create_cdata) - cdata = MEM_callocN(tot_vec_size * 2, "particle_cdata"); - vdata = MEM_callocN(tot_vec_size * 2, "particle_vdata"); + if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 2, "particle_cdata"); + if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 2, "particle_vdata"); break; case PART_DRAW_BB: if(create_cdata) - cdata = MEM_callocN(tot_vec_size * 4, "particle_cdata"); - vdata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); - ndata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); + if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 4, "particle_cdata"); + if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); + if(!pdd->ndata) pdd->ndata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); break; default: if(create_cdata) - cdata=MEM_callocN(tot_vec_size, "particle_cdata"); - vdata=MEM_callocN(tot_vec_size, "particle_vdata"); + if(!pdd->cdata) pdd->cdata=MEM_callocN(tot_vec_size, "particle_cdata"); + if(!pdd->vdata) pdd->vdata=MEM_callocN(tot_vec_size, "particle_vdata"); } } - if(part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) - vedata = MEM_callocN(tot_vec_size * 2, "particle_vedata"); + if(part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) { + if(!pdd->vedata) pdd->vedata = MEM_callocN(tot_vec_size * 2, "particle_vedata"); + need_v = 1; + } - vd=vdata; - ved=vedata; - cd=cdata; - nd=ndata; + pdd->vd= pdd->vdata; + pdd->ved= pdd->vedata; + pdd->cd= pdd->cdata; + pdd->nd= pdd->ndata; + pdd->tot_vec_size= tot_vec_size; - psys->lattice= psys_get_lattice(scene, ob, psys); + psys->lattice= psys_get_lattice(&sim); } if(draw_as){ /* 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; if(pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) continue; pa_time=(cfra-pa->time)/pa->lifetime; + pa_birthtime=pa->time; + pa_dietime = pa->dietime; pa_size=pa->size; + if(part->phystype==PART_PHYS_BOIDS) + pa_health = pa->boid->data.health; + else + pa_health = -1.0; - if((part->flag&PART_ABS_TIME)==0){ -#if 0 // XXX old animation system +#if 0 // XXX old animation system + if((part->flag&PART_ABS_TIME)==0){ if(ma && ma->ipo){ IpoCurve *icu; @@ -3206,19 +3363,20 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv pa_size = icu->curval; } } -#endif // XXX old animation system } +#endif // XXX old animation system - r_tilt=1.0f+pa->r_ave[0]; + r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f); + r_length = PSYS_FRAND(a + 22); } else{ ChildParticle *cpa= &psys->child[a-totpart]; - pa_time=psys_get_child_time(psys,cpa,cfra); + pa_time=psys_get_child_time(psys,cpa,cfra,&pa_birthtime,&pa_dietime); +#if 0 // XXX old animation system if((part->flag&PART_ABS_TIME)==0) { if(ma && ma->ipo){ -#if 0 // XXX old animation system IpoCurve *icu; /* correction for lifetime */ @@ -3232,154 +3390,88 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv else if(icu->adrcode == MA_COL_B) ma_b = icu->curval; } -#endif // XXX old animation system } } +#endif // XXX old animation system pa_size=psys_get_child_size(psys,cpa,cfra,0); - r_tilt=2.0f*cpa->rand[2]; + pa_health = -1.0; + + r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f); + r_length = PSYS_FRAND(a + 22); } if(draw_as!=PART_DRAW_PATH){ - 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 */ - switch(draw_as){ - case PART_DRAW_DOT: - if(vd){ - VECCOPY(vd,state.co) vd+=3; - } - if(cd) { - cd[0]=ma_r; - cd[1]=ma_g; - cd[2]=ma_b; - cd+=3; - } - break; - case PART_DRAW_CROSS: - case PART_DRAW_AXIS: - vec[0]=2.0f*pixsize; - vec[1]=vec[2]=0.0; - QuatMulVecf(state.rot,vec); - if(draw_as==PART_DRAW_AXIS){ - cd[1]=cd[2]=cd[4]=cd[5]=0.0; - cd[0]=cd[3]=1.0; - cd[6]=cd[8]=cd[9]=cd[11]=0.0; - cd[7]=cd[10]=1.0; - cd[13]=cd[12]=cd[15]=cd[16]=0.0; - cd[14]=cd[17]=1.0; - cd+=18; - - VECCOPY(vec2,state.co); - } - else { - if(cd) { - cd[0]=cd[3]=cd[6]=cd[9]=cd[12]=cd[15]=ma_r; - cd[1]=cd[4]=cd[7]=cd[10]=cd[13]=cd[16]=ma_g; - cd[2]=cd[5]=cd[8]=cd[11]=cd[14]=cd[17]=ma_b; - cd+=18; - } - VECSUB(vec2,state.co,vec); - } + 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; - VECADD(vec,state.co,vec); - VECCOPY(vd,vec); vd+=3; - VECCOPY(vd,vec2); vd+=3; - - vec[1]=2.0f*pixsize; - vec[0]=vec[2]=0.0; - QuatMulVecf(state.rot,vec); - if(draw_as==PART_DRAW_AXIS){ - VECCOPY(vec2,state.co); - } - else VECSUB(vec2,state.co,vec); - - VECADD(vec,state.co,vec); - VECCOPY(vd,vec); vd+=3; - VECCOPY(vd,vec2); vd+=3; - - vec[2]=2.0f*pixsize; - vec[0]=vec[1]=0.0; - QuatMulVecf(state.rot,vec); - if(draw_as==PART_DRAW_AXIS){ - VECCOPY(vec2,state.co); - } - else VECSUB(vec2,state.co,vec); - - VECADD(vec,state.co,vec); - - VECCOPY(vd,vec); vd+=3; - VECCOPY(vd,vec2); vd+=3; - break; - case PART_DRAW_LINE: - VECCOPY(vec,state.vel); - Normalize(vec); - if(part->draw & PART_DRAW_VEL_LENGTH) - VecMulf(vec,VecLength(state.vel)); - VECADDFAC(vd,state.co,vec,-part->draw_line[0]); vd+=3; - VECADDFAC(vd,state.co,vec,part->draw_line[1]); vd+=3; - if(cd) { - cd[0]=cd[3]=ma_r; - cd[1]=cd[4]=ma_g; - cd[2]=cd[5]=ma_b; - cd+=3; - } - break; - case PART_DRAW_CIRC: - if(create_cdata) - glColor3f(ma_r,ma_g,ma_b); - drawcircball(GL_LINE_LOOP, state.co, pixsize, imat); - break; - case PART_DRAW_BB: - if(cd) { - cd[0]=cd[3]=cd[6]=cd[9]=ma_r; - cd[1]=cd[4]=cd[7]=cd[10]=ma_g; - cd[2]=cd[5]=cd[8]=cd[11]=ma_b; - cd+=12; - } + 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 = pa_time; - VECCOPY(bb.vec, state.co); - VECCOPY(bb.vel, state.vel); - - psys_make_billboard(&bb, xvec, yvec, zvec, bb_center); - - VECADD(vd,bb_center,xvec); - VECADD(vd,vd,yvec); vd+=3; + bb.time = ct; + } - VECSUB(vd,bb_center,xvec); - VECADD(vd,vd,yvec); vd+=3; + draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, psys->pdd); - VECSUB(vd,bb_center,xvec); - VECSUB(vd,vd,yvec); vd+=3; + totpoint++; + drawn = 1; + } + } + 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; + } - VECADD(vd,bb_center,xvec); - VECSUB(vd,vd,yvec); vd+=3; + draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, pdd); - VECCOPY(nd, zvec); nd+=3; - VECCOPY(nd, zvec); nd+=3; - VECCOPY(nd, zvec); nd+=3; - VECCOPY(nd, zvec); nd+=3; - break; + totpoint++; + drawn = 1; } + } - totpoint++; - + if(drawn) { /* additional things to draw for each particle */ /* (velocity, size and number) */ - if(vedata){ - VECCOPY(ved,state.co); - ved+=3; + if(pdd->vedata){ + VECCOPY(pdd->ved,state.co); + pdd->ved+=3; VECCOPY(vel,state.vel); VecMulf(vel,timestep); - VECADD(ved,state.co,vel); - ved+=3; + VECADD(pdd->ved,state.co,vel); + pdd->ved+=3; + + totve++; } if(part->draw & PART_DRAW_SIZE){ @@ -3388,10 +3480,20 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv setlinestyle(0); } - if(part->draw&PART_DRAW_NUM && !(G.f & G_RENDER_SHADOW)){ + 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_HEALTH && a < totpart && part->phystype==PART_PHYS_BOIDS) + sprintf(val, "%s %.2f", val, pa_health); + /* in path drawing state.co is the end point */ - sprintf(val," %i",a); - view3d_object_text_draw_add(state.co[0], state.co[1], state.co[2], val, 0); + view3d_cached_text_draw_add(state.co[0], state.co[1], state.co[2], val, 0); } } } @@ -3408,7 +3510,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv glEnableClientState(GL_VERTEX_ARRAY); /* setup gl flags */ - if(dt > OB_WIRE) { + if(ob_dt > OB_WIRE) { glEnableClientState(GL_NORMAL_ARRAY); if(part->draw&PART_DRAW_MAT_COL) @@ -3436,7 +3538,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(path->steps > 0) { glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); - if(dt > OB_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); @@ -3452,7 +3554,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv path=cache[a]; glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); - if(dt > OB_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); @@ -3463,7 +3565,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv /* restore & clean up */ - if(dt > OB_WIRE) { + if(ob_dt > OB_WIRE) { if(part->draw&PART_DRAW_MAT_COL) glDisable(GL_COLOR_ARRAY); glDisable(GL_COLOR_MATERIAL); @@ -3479,16 +3581,17 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv glDisableClientState(GL_COLOR_ARRAY); /* setup created data arrays */ - if(vdata){ + if(pdd->vdata){ glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, vdata); + glVertexPointer(3, GL_FLOAT, 0, pdd->vdata); } else glDisableClientState(GL_VERTEX_ARRAY); - if(ndata && dt>OB_WIRE){ + /* billboards are drawn this way */ + if(pdd->ndata && ob_dt>OB_WIRE){ glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, ndata); + glNormalPointer(GL_FLOAT, 0, pdd->ndata); glEnable(GL_LIGHTING); } else{ @@ -3496,9 +3599,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv glDisable(GL_LIGHTING); } - if(cdata){ + if(pdd->cdata){ glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(3, GL_FLOAT, 0, cdata); + glColorPointer(3, GL_FLOAT, 0, pdd->cdata); } /* draw created data arrays */ @@ -3511,7 +3614,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv glDrawArrays(GL_LINES, 0, 2*totpoint); break; case PART_DRAW_BB: - if(dt<=OB_WIRE) + if(ob_dt<=OB_WIRE) glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); glDrawArrays(GL_QUADS, 0, 4*totpoint); @@ -3520,16 +3623,19 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv glDrawArrays(GL_POINTS, 0, totpoint); break; } + + pdd->flag |= PARTICLE_DRAW_DATA_UPDATED; + pdd->totpoint = totpoint; } - if(vedata){ + if(pdd->vedata){ glDisableClientState(GL_COLOR_ARRAY); cpack(0xC0C0C0); glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, vedata); + glVertexPointer(3, GL_FLOAT, 0, pdd->vedata); - glDrawArrays(GL_LINES, 0, 2*totpoint); + glDrawArrays(GL_LINES, 0, 2*totve); } glPolygonMode(GL_FRONT, polygonmode[0]); @@ -3544,14 +3650,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(states) MEM_freeN(states); - if(vdata) - MEM_freeN(vdata); - if(vedata) - MEM_freeN(vedata); - if(cdata) - MEM_freeN(cdata); - if(ndata) - MEM_freeN(ndata); psys->flag &= ~PSYS_DRAWING; @@ -3560,44 +3658,40 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv psys->lattice= NULL; } - wmLoadMatrix(rv3d->viewmat); - wmMultMatrix(ob->obmat); // bring back local matrix for dtx + if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) + wmLoadMatrix(rv3d->viewmat); } -static void draw_particle_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, ParticleSystem *psys, int dt) +static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, PTCacheEdit *edit, int dt) { - ParticleEdit *edit = psys->edit; - ParticleData *pa; - ParticleCacheKey **path; - ParticleEditKey *key; + ParticleCacheKey **cache, *path, *pkey; + PTCacheEditPoint *point; + PTCacheEditKey *key; ParticleEditSettings *pset = PE_settings(scene); - int i, k, totpart = psys->totpart, totchild=0, timed = pset->draw_timed; + int i, k, totpoint = edit->totpoint, timed = pset->flag & PE_FADE_TIME ? pset->fade_frames : 0; + int steps; char nosel[4], sel[4]; float sel_col[3]; float nosel_col[3]; - char val[32]; + float *pathcol = NULL, *pcol; + + + if(edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED) + PE_update_object(scene, ob, 0); /* create path and child path cache if it doesn't exist already */ - if(psys->pathcache==0){ - PE_hide_keys_time(scene, psys,CFRA); - psys_cache_paths(scene, ob, psys, CFRA,0); - } - if(psys->pathcache==0) + if(edit->pathcache==0) + psys_cache_edit_paths(scene, ob, edit, CFRA); + + if(edit->pathcache==0) return; - if(pset->flag & PE_SHOW_CHILD && psys->part->draw_as == PART_DRAW_PATH) { - if(psys->childcache==0) - psys_cache_child_paths(scene, ob, psys, CFRA, 0); - } - else if(!(pset->flag & PE_SHOW_CHILD) && psys->childcache) - free_child_path_cache(psys); + PE_hide_keys_time(scene, edit, CFRA); /* opengl setup */ if((v3d->flag & V3D_ZBUF_SELECT)==0) glDisable(GL_DEPTH_TEST); - wmLoadMatrix(rv3d->viewmat); - /* get selection theme colors */ UI_GetThemeColor3ubv(TH_VERTEX_SELECT, sel); UI_GetThemeColor3ubv(TH_VERTEX, nosel); @@ -3608,129 +3702,115 @@ static void draw_particle_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ob nosel_col[1]=(float)nosel[1]/255.0f; nosel_col[2]=(float)nosel[2]/255.0f; - if(psys->childcache) - totchild = psys->totchildcache; - /* draw paths */ - if(timed) + if(timed) { glEnable(GL_BLEND); + steps = (*edit->pathcache)->steps + 1; + pathcol = MEM_callocN(steps*4*sizeof(float), "particle path color data"); + } glEnableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); - if(dt > OB_WIRE) { - /* solid shaded with lighting */ - glEnableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glEnable(GL_COLOR_MATERIAL); - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - } - else { - /* flat wire color */ - glDisableClientState(GL_NORMAL_ARRAY); - glDisable(GL_LIGHTING); - UI_ThemeColor(TH_WIRE); - } + cache=edit->pathcache; + for(i=0; i<totpoint; i++){ + path = cache[i]; + glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); - /* only draw child paths with lighting */ - if(dt > OB_WIRE) - glEnable(GL_LIGHTING); - - if(psys->part->draw_as == PART_DRAW_PATH) { - for(i=0, path=psys->childcache; i<totchild; i++,path++){ - glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->co); - if(dt > OB_WIRE) { - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel); - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col); + if(timed) { + for(k=0, pcol=pathcol, pkey=path; k<steps; k++, pkey++, pcol+=4){ + VECCOPY(pcol, pkey->col); + pcol[3] = 1.0f - fabs((float)CFRA - pkey->time)/(float)pset->fade_frames; } - glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1); + glColorPointer(4, GL_FLOAT, 4*sizeof(float), pathcol); } - } - - if(dt > OB_WIRE) - glDisable(GL_LIGHTING); + else + glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); - if(pset->brushtype == PE_BRUSH_WEIGHT) { - glLineWidth(2.0f); - glEnableClientState(GL_COLOR_ARRAY); - glDisable(GL_LIGHTING); + glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); } - /* draw parents last without lighting */ - for(i=0, pa=psys->particles, path = psys->pathcache; i<totpart; i++, pa++, path++){ - glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->co); - if(dt > OB_WIRE) - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel); - if(dt > OB_WIRE || pset->brushtype == PE_BRUSH_WEIGHT) - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col); + if(pathcol) { MEM_freeN(pathcol); pathcol = pcol = NULL; } - glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1); - } /* draw edit vertices */ if(pset->selectmode!=SCE_SELECT_PATH){ - glDisableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glDisable(GL_LIGHTING); glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); if(pset->selectmode==SCE_SELECT_POINT){ + float *pd=0,*pdata=0; float *cd=0,*cdata=0; - cd=cdata=MEM_callocN(edit->totkeys*(timed?4:3)*sizeof(float), "particle edit color data"); + int totkeys = 0; + + for (i=0, point=edit->points; i<totpoint; i++, point++) + if(!(point->flag & PEP_HIDE)) + totkeys += point->totkey; + + if(!(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"); + + for(i=0, point=edit->points; i<totpoint; i++, point++){ + if(point->flag & PEP_HIDE) + continue; + + for(k=0, key=point->keys; k<point->totkey; k++, key++){ + if(pd) { + VECCOPY(pd, key->co); + pd += 3; + } - for(i=0, pa=psys->particles; i<totpart; i++, pa++){ - for(k=0, key=edit->keys[i]; k<pa->totkey; k++, key++){ if(key->flag&PEK_SELECT){ VECCOPY(cd,sel_col); } else{ VECCOPY(cd,nosel_col); } + if(timed) - *(cd+3) = (key->flag&PEK_HIDE)?0.0f:1.0f; + *(cd+3) = 1.0f - fabs((float)CFRA - *key->time)/(float)pset->fade_frames; + cd += (timed?4:3); } } cd=cdata; - for(i=0, pa=psys->particles; i<totpart; i++, pa++){ - if((pa->flag & PARS_HIDE)==0){ - glVertexPointer(3, GL_FLOAT, sizeof(ParticleEditKey), edit->keys[i]->world_co); - glColorPointer((timed?4:3), GL_FLOAT, (timed?4:3)*sizeof(float), cd); - glDrawArrays(GL_POINTS, 0, pa->totkey); - } - cd += (timed?4:3) * pa->totkey; + pd=pdata; + for(i=0, point=edit->points; i<totpoint; i++, point++){ + if(point->flag & PEP_HIDE) + continue; - if((pset->flag&PE_SHOW_TIME) && (pa->flag&PARS_HIDE)==0 && !(G.f & G_RENDER_SHADOW)){ - for(k=0, key=edit->keys[i]+k; k<pa->totkey; k++, key++){ - if(key->flag & PEK_HIDE) continue; + if(point->keys->flag & PEK_USE_WCO) + glVertexPointer(3, GL_FLOAT, sizeof(PTCacheEditKey), point->keys->world_co); + else + glVertexPointer(3, GL_FLOAT, 3*sizeof(float), pd); - sprintf(val," %.1f",*key->time); - view3d_object_text_draw_add(key->world_co[0], key->world_co[1], key->world_co[2], val, 0); - } - } + glColorPointer((timed?4:3), GL_FLOAT, (timed?4:3)*sizeof(float), cd); + + glDrawArrays(GL_POINTS, 0, point->totkey); + + pd += pd ? 3 * point->totkey : 0; + cd += (timed?4:3) * point->totkey; } - if(cdata) - MEM_freeN(cdata); - cd=cdata=0; + if(pdata) { MEM_freeN(pdata); pd=pdata=0; } + if(cdata) { MEM_freeN(cdata); cd=cdata=0; } } else if(pset->selectmode == SCE_SELECT_END){ - for(i=0, pa=psys->particles; i<totpart; i++, pa++){ - if((pa->flag & PARS_HIDE)==0){ - key = edit->keys[i] + pa->totkey - 1; + for(i=0, point=edit->points; i<totpoint; i++, point++){ + if((point->flag & PEP_HIDE)==0){ + key = point->keys + point->totkey - 1; if(key->flag & PEK_SELECT) glColor3fv(sel_col); else glColor3fv(nosel_col); /* has to be like this.. otherwise selection won't work, have try glArrayElement later..*/ glBegin(GL_POINTS); - glVertex3fv(key->world_co); + glVertex3fv(key->flag & PEK_USE_WCO ? key->world_co : key->co); glEnd(); - - if((pset->flag & PE_SHOW_TIME) && !(G.f & G_RENDER_SHADOW)){ - sprintf(val," %.1f",*key->time); - view3d_object_text_draw_add(key->world_co[0], key->world_co[1], key->world_co[2], val, 0); - } } } } @@ -3744,25 +3824,24 @@ static void draw_particle_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ob glEnable(GL_DEPTH_TEST); glLineWidth(1.0f); - wmMultMatrix(ob->obmat); // bring back local matrix for dtx glPointSize(1.0); } unsigned int nurbcol[8]= { 0, 0x9090, 0x409030, 0x603080, 0, 0x40fff0, 0x40c033, 0xA090F0 }; -static void tekenhandlesN(Nurb *nu, short sel) +static void tekenhandlesN(Nurb *nu, short sel, short hide_handles) { BezTriple *bezt; float *fp; unsigned int *col; int a; - if(nu->hide || (G.f & G_HIDDENHANDLES)) return; + if(nu->hide || hide_handles) return; glBegin(GL_LINES); - if( (nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { if(sel) col= nurbcol+4; else col= nurbcol; @@ -3802,7 +3881,7 @@ static void tekenhandlesN(Nurb *nu, short sel) glEnd(); } -static void tekenvertsN(Nurb *nu, short sel) +static void tekenvertsN(Nurb *nu, short sel, short hide_handles) { BezTriple *bezt; BPoint *bp; @@ -3819,13 +3898,13 @@ static void tekenvertsN(Nurb *nu, short sel) bglBegin(GL_POINTS); - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { if(bezt->hide==0) { - if (G.f & G_HIDDENHANDLES) { + if (hide_handles) { if((bezt->f2 & SELECT)==sel) bglVertex3fv(bezt->vec[1]); } else { if((bezt->f1 & SELECT)==sel) bglVertex3fv(bezt->vec[0]); @@ -3860,7 +3939,7 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel) nu= nurb; while(nu) { if(nu->hide==0) { - switch(nu->type & 7) { + switch(nu->type) { case CU_POLY: cpack(nurbcol[3]); bp= nu->bp; @@ -3957,6 +4036,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Curve *cu = ob->data; Nurb *nu; BevList *bl; + short hide_handles = (cu->drawflag & CU_HIDE_HANDLES); // XXX retopo_matrix_update(v3d); @@ -3968,23 +4048,25 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, /* first non-selected handles */ for(nu=nurb; nu; nu=nu->next) { - if((nu->type & 7)==CU_BEZIER) { - tekenhandlesN(nu, 0); + if(nu->type == CU_BEZIER) { + tekenhandlesN(nu, 0, hide_handles); } } draw_editnurb(ob, nurb, 0); draw_editnurb(ob, nurb, 1); /* selected handles */ for(nu=nurb; nu; nu=nu->next) { - if((nu->type & 7)==1) tekenhandlesN(nu, 1); - tekenvertsN(nu, 0); + if(nu->type == CU_BEZIER && (cu->drawflag & CU_HIDE_HANDLES)==0) + tekenhandlesN(nu, 1, hide_handles); + tekenvertsN(nu, 0, hide_handles); } if(v3d->zbuf) glEnable(GL_DEPTH_TEST); /* direction vectors for 3d curve paths when at its lowest, dont render normals */ - if(cu->flag & CU_3D && ts->normalsize > 0.0015) { + if(cu->flag & CU_3D && ts->normalsize > 0.0015 && (cu->drawflag & CU_HIDE_NORMALS)==0) { + UI_ThemeColor(TH_WIRE); for (bl=cu->bev.first,nu=nurb; nu && bl; bl=bl->next,nu=nu->next) { BevPoint *bevp= (BevPoint *)(bl+1); @@ -3993,21 +4075,21 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, while (nr-->0) { /* accounts for empty bevel lists */ float fac= bevp->radius * ts->normalsize; - float ox,oy,oz; // Offset perpendicular to the curve - float dx,dy,dz; // Delta along the curve + float vec_a[3] = { fac,0, 0}; // Offset perpendicular to the curve + float vec_b[3] = {-fac,0, 0}; // Delta along the curve + + QuatMulVecf(bevp->quat, vec_a); + QuatMulVecf(bevp->quat, vec_b); + VecAddf(vec_a, vec_a, bevp->vec); + VecAddf(vec_b, vec_b, bevp->vec); - ox = fac*bevp->mat[0][0]; - oy = fac*bevp->mat[0][1]; - oz = fac*bevp->mat[0][2]; - - dx = fac*bevp->mat[2][0]; - dy = fac*bevp->mat[2][1]; - dz = fac*bevp->mat[2][2]; + VECSUBFAC(vec_a, vec_a, bevp->dir, fac); + VECSUBFAC(vec_b, vec_b, bevp->dir, fac); glBegin(GL_LINE_STRIP); - glVertex3f(bevp->x - ox - dx, bevp->y - oy - dy, bevp->z - oz - dz); - glVertex3f(bevp->x, bevp->y, bevp->z); - glVertex3f(bevp->x + ox - dx, bevp->y + oy - dy, bevp->z + oz - dz); + glVertex3fv(vec_a); + glVertex3fv(bevp->vec); + glVertex3fv(vec_b); glEnd(); bevp += skip+1; @@ -4019,7 +4101,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, if(v3d->zbuf) glDisable(GL_DEPTH_TEST); for(nu=nurb; nu; nu=nu->next) { - tekenvertsN(nu, 1); + tekenvertsN(nu, 1, hide_handles); } if(v3d->zbuf) glEnable(GL_DEPTH_TEST); @@ -4268,7 +4350,7 @@ static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, if(ml==NULL) return 1; /* in case solid draw, reset wire colors */ - if(mb->editelems && (ob->flag & SELECT)) { + if(ob->flag & SELECT) { if(ob==OBACT) UI_ThemeColor(TH_ACTIVE); else UI_ThemeColor(TH_SELECT); } @@ -4410,13 +4492,13 @@ static void draw_forcefield(Scene *scene, Object *ob) /*path end*/ setlinestyle(3); - where_on_path(ob, 1.0f, guidevec1, guidevec2); + where_on_path(ob, 1.0f, guidevec1, guidevec2, NULL, NULL); UI_ThemeColorBlend(curcol, TH_BACK, 0.5); drawcircball(GL_LINE_LOOP, guidevec1, mindist, imat); /*path beginning*/ setlinestyle(0); - where_on_path(ob, 0.0f, guidevec1, guidevec2); + where_on_path(ob, 0.0f, guidevec1, guidevec2, NULL, NULL); UI_ThemeColorBlend(curcol, TH_BACK, 0.5); drawcircball(GL_LINE_LOOP, guidevec1, mindist, imat); @@ -4626,8 +4708,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); @@ -4645,8 +4728,8 @@ static void drawSolidSelect(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base drawDispListwire(&ob->disp); } else if(ob->type==OB_ARMATURE) { - if(!(ob->flag & OB_POSEMODE)) - draw_armature(scene, v3d, rv3d, base, OB_WIRE, 0); + if(!(ob->mode & OB_MODE_POSE)) + draw_armature(scene, v3d, ar, base, OB_WIRE, 0); } glLineWidth(1.0); @@ -4756,11 +4839,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); @@ -4770,6 +4853,7 @@ void drawRBpivot(bRigidBodyJointConstraint *data) void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) { static int warning_recursive= 0; + ModifierData *md = NULL; Object *ob; Curve *cu; RegionView3D *rv3d= ar->regiondata; @@ -4793,7 +4877,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* xray delay? */ if((flag & DRAW_PICKING)==0 && (base->flag & OB_FROMDUPLI)==0) { /* don't do xray in particle mode, need the z-buffer */ - if(!(G.f & G_PARTICLEEDIT)) { + if(!(ob->mode & OB_MODE_PARTICLE_EDIT)) { /* xray and transp are set when it is drawing the 2nd/3rd pass */ if(!v3d->xray && !v3d->transp && (ob->dtx & OB_DRAWXRAY) && !(ob->dtx & OB_DRAWTRANSP)) { add_view3d_after(v3d, base, V3D_XRAY, flag); @@ -4802,6 +4886,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))) { @@ -4880,6 +4967,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* patch? children objects with a timeoffs change the parents. How to solve! */ /* if( ((int)ob->ctime) != F_(scene->r.cfra)) where_is_object(scene, ob); */ + + /* draw paths... */ + // TODO... /* multiply view with object matrix */ wmMultMatrix(ob->obmat); @@ -4939,7 +5029,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) dtx= 0; /* faceselect exception: also draw solid when dt==wire, except in editmode */ - if(ob==OBACT && (G.f & (G_VERTEXPAINT+G_TEXTUREPAINT+G_WEIGHTPAINT))) { + 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); @@ -4983,7 +5073,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if(dt>OB_WIRE && dt<OB_TEXTURE && ob!=scene->obedit && (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); } } } @@ -5129,7 +5219,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: @@ -5145,19 +5235,142 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) ) { ParticleSystem *psys; if(col || (ob->flag & SELECT)) cpack(0xFFFFFF); /* for visibility, also while wpaint */ - glDepthMask(GL_FALSE); + //glDepthMask(GL_FALSE); + + 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); - if(G.f & G_PARTICLEEDIT && ob==OBACT) { - psys= PE_get_current(scene, ob); - if(psys && !scene->obedit && psys_in_edit_mode(scene, psys)) - draw_particle_edit(scene, v3d, rv3d, ob, psys, dt); - } - glDepthMask(GL_TRUE); + view3d_cached_text_draw_end(v3d, ar, 0, NULL); + + wmMultMatrix(ob->obmat); + + //glDepthMask(GL_TRUE); if(col) cpack(col); } + + if( (warning_recursive==0) && + (flag & DRAW_PICKING)==0 && + (!scene->obedit) + ) { + + if(ob->mode & OB_MODE_PARTICLE_EDIT && ob==OBACT) { + PTCacheEdit *edit = PE_get_current(scene, ob); + if(edit) { + wmLoadMatrix(rv3d->viewmat); + draw_ptcache_edit(scene, v3d, rv3d, ob, edit, dt); + wmMultMatrix(ob->obmat); + } + } + } + + /* draw code for smoke */ + if((md = modifiers_findByType(ob, eModifierType_Smoke))) + { + SmokeModifierData *smd = (SmokeModifierData *)md; + + // draw collision objects + if((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll) + { + /*SmokeCollSettings *scs = smd->coll; + if(scs->points) + { + size_t i; + + wmLoadMatrix(rv3d->viewmat); + + if(col || (ob->flag & SELECT)) cpack(0xFFFFFF); + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); + + + // glPointSize(3.0); + bglBegin(GL_POINTS); + + for(i = 0; i < scs->numpoints; i++) + { + bglVertex3fv(&scs->points[3*i]); + } + + bglEnd(); + glPointSize(1.0); + + wmMultMatrix(ob->obmat); + glDisable(GL_BLEND); + glDepthMask(GL_TRUE); + if(col) cpack(col); + + } + */ + } + + // only draw domains + if(smd->domain && smd->domain->fluid) + { + if(!smd->domain->wt || !(smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) + { +// #if 0 + smd->domain->tex = NULL; + GPU_create_smoke(smd, 0); + draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->p0, smd->domain->p1, smd->domain->res, smd->domain->dx, smd->domain->tex_shadow); + GPU_free_smoke(smd); +// #endif +#if 0 + int x, y, z; + float *density = smoke_get_density(smd->domain->fluid); + + wmLoadMatrix(rv3d->viewmat); + // wmMultMatrix(ob->obmat); + + if(col || (ob->flag & SELECT)) cpack(0xFFFFFF); + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); + + + // glPointSize(3.0); + bglBegin(GL_POINTS); + + for(x = 0; x < smd->domain->res[0]; x++) + for(y = 0; y < smd->domain->res[1]; y++) + for(z = 0; z < smd->domain->res[2]; z++) + { + float tmp[3]; + int index = smoke_get_index(x, smd->domain->res[0], y, smd->domain->res[1], z); + + if(density[index] > FLT_EPSILON) + { + float color[3]; + VECCOPY(tmp, smd->domain->p0); + tmp[0] += smd->domain->dx * x + smd->domain->dx * 0.5; + tmp[1] += smd->domain->dx * y + smd->domain->dx * 0.5; + tmp[2] += smd->domain->dx * z + smd->domain->dx * 0.5; + color[0] = color[1] = color[2] = density[index]; + glColor3fv(color); + bglVertex3fv(tmp); + } + } + + bglEnd(); + glPointSize(1.0); + + wmMultMatrix(ob->obmat); + glDisable(GL_BLEND); + glDepthMask(GL_TRUE); + if(col) cpack(col); +#endif + } + else if(smd->domain->wt && (smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) + { + smd->domain->tex = NULL; + GPU_create_smoke(smd, 1); + draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->p0, smd->domain->p1, smd->domain->res_wt, smd->domain->dx_wt, smd->domain->tex_shadow); + GPU_free_smoke(smd); + } + } + } { bConstraint *con; @@ -5183,7 +5396,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);*/ @@ -5206,7 +5419,7 @@ 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); @@ -5217,7 +5430,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if(G.f & G_RENDER_SHADOW) return; /* object centers, need to be drawn in viewmat space for speed, but OK for picking select */ - if(ob!=OBACT || (G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT))==0) { + if(ob!=OBACT || !(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))) { int do_draw_center= -1; /* defines below are zero or positive... */ if((scene->basact)==base) @@ -5497,7 +5710,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r if(dm) { glsl = draw_glsl_material(scene, ob, v3d, dt); - GPU_set_object_materials(v3d, rv3d, scene, ob, glsl, NULL); + GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL); } else { glEnable(GL_COLOR_MATERIAL); @@ -5511,7 +5724,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r if(dm) { dm->drawFacesSolid(dm, GPU_enable_material); - GPU_disable_material(); + GPU_end_object_materials(); } else if(edm) edm->drawMappedFaces(edm, NULL, NULL, 0); |