diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index af64885d9f2..412c40c7eb0 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -444,6 +444,10 @@ typedef struct SculptData /* Symmetry is separate from the other BrushData because the same settings are always used for all brush types */ char symm; + + /* Added to store if the 'Rake' setting has been set */ + char rake; + char pad[7]; } SculptData; typedef struct Scene { diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 218ae7f3161..116a2c117d2 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -5205,9 +5205,16 @@ void sculptmode_draw_interface_textures(uiBlock *block, unsigned short cx, unsig if(sd->texrept != SCULPTREPT_3D) { uiBlockBeginAlign(block); uiDefButF(block,NUM,0, "Angle", cx,cy,115,19, &mtex->warpfac, 0,360,100,0, "Rotate texture counterclockwise"); + /*Moved inside, so that following buttons aren't made bigger for no reason*/ + cy-= 20; } - cy-= 20; - + + /* Added Rake button. Needs to be turned off if 3D is on / disappear*/ + if(sd->texrept != SCULPTREPT_3D){ + uiDefButC(block,TOG,B_NOP, "Rake", cx,cy,115,19, &sd->rake, 0,0,0,0,"Rotate the brush in the direction of motion"); + cy-=20; + } + if(sd->texrept != SCULPTREPT_DRAG) { uiBlockBeginAlign(block); but= uiDefIconButC(block, TOG, REDRAWBUTSEDIT, sd->texsep ? ICON_UNLOCKED : ICON_LOCKED, cx,cy,20,19, &sd->texsep,0,0,0,0, "Locks the texture sizes together"); diff --git a/source/blender/src/sculptmode.c b/source/blender/src/sculptmode.c index 964c373771e..8fb3a732014 100644 --- a/source/blender/src/sculptmode.c +++ b/source/blender/src/sculptmode.c @@ -225,6 +225,7 @@ void sculptmode_init(Scene *sce) sd->flags= SCULPT_DRAW_BRUSH; sd->tablet_size=3; sd->tablet_strength=10; + sd->rake=0; } void sculptmode_free_session(Scene *); @@ -1645,13 +1646,14 @@ void sculpt(void) SculptData *sd= sculpt_data(); SculptSession *ss= sculpt_session(); Object *ob= OBACT; - short mouse[2], mvalo[2], firsttime=1, mousebut; + /* lastSigMouse is for the rake, to store the last place the mouse movement was significant */ + short mouse[2], mvalo[2], lastSigMouse[2],firsttime=1, mousebut; short modifier_calculations= 0; EditData e; RectNode *rn= NULL; short spacing= 32000; int scissor_box[4]; - + float offsetRot; if(!(G.f & G_SCULPTMODE) || G.obedit || !ob || ob->id.lib || !get_mesh(ob) || (get_mesh(ob)->totface == 0)) return; if(!(ob->lay & G.vd->lay)) @@ -1700,7 +1702,8 @@ void sculpt(void) getmouseco_areawin(mouse); mvalo[0]= mouse[0]; mvalo[1]= mouse[1]; - + lastSigMouse[0]=mouse[0]; + lastSigMouse[1]=mouse[1]; mousebut = L_MOUSE; /* If modifier_calculations is true, then extra time must be spent @@ -1729,9 +1732,19 @@ void sculpt(void) /* Get original scissor box */ glGetIntegerv(GL_SCISSOR_BOX, scissor_box); - + + /* For raking, get the original angle*/ + offsetRot=tex_angle(); + while (get_mbut() & mousebut) { getmouseco_areawin(mouse); + /* If rake, and the mouse has moved over 10 pixels (euclidean) (prevents jitter) then get the new angle */ + if (sd->rake && (pow(lastSigMouse[0]-mouse[0],2)+pow(lastSigMouse[1]-mouse[1],2))>100){ + /*Nasty looking, but just orig + new angle really*/ + set_tex_angle(offsetRot+180.+to_deg(atan2((float)(mouse[1]-lastSigMouse[1]),(float)(mouse[0]-lastSigMouse[0])))); + lastSigMouse[0]=mouse[0]; + lastSigMouse[1]=mouse[1]; + } if(firsttime || mouse[0]!=mvalo[0] || mouse[1]!=mvalo[1] || sculptmode_brush()->airbrush) { firsttime= 0; @@ -1828,6 +1841,9 @@ void sculpt(void) else BIF_wait_for_statechange(); } + /* Set the rotation of the brush back to what it was before any rake */ + set_tex_angle(offsetRot); + if(sd->flags & SCULPT_INPUT_SMOOTH) { sculpt_stroke_apply_all(&e); calc_damaged_verts(&ss->damaged_verts,e.grabdata);