From c740f1a792fd47995b21422a84bc65f50d0b42ed Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Thu, 12 Dec 2013 19:01:11 +0200 Subject: Sculpt mode Gravity feature from GSOC 2010 by Jason Wilkins. Reviewers: sergey, brecht, campbellbarton, jwilkins Differential Revision: http://developer.blender.org/D89 --- source/blender/editors/sculpt_paint/sculpt.c | 65 ++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'source/blender/editors/sculpt_paint') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index c0f0fcf8230..14b6ab8859a 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -317,6 +317,7 @@ typedef struct StrokeCache { int alt_smooth; float plane_trim_squared; + float gravity_direction[3]; rcti previous_r; /* previous redraw rectangle */ } StrokeCache; @@ -2997,6 +2998,49 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod } } +static void do_gravity(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float bstrength) +{ + SculptSession *ss = ob->sculpt; + Brush *brush = BKE_paint_brush(&sd->paint); + + float offset[3]/*, an[3]*/; + int n; + float gravity_vector[3]; + + mul_v3_v3fl(gravity_vector, ss->cache->gravity_direction, -ss->cache->radius_squared); + + /* offset with as much as possible factored in already */ + mul_v3_v3v3(offset, gravity_vector, ss->cache->scale); + mul_v3_fl(offset, bstrength); + + /* threaded loop over nodes */ + #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) + for(n = 0; n < totnode; n++) { + PBVHVertexIter vd; + SculptBrushTest test; + float (*proxy)[3]; + + proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; + + sculpt_brush_test_init(ss, &test); + + BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { + if (sculpt_brush_test_sq(&test, vd.co)) { + const float fade = tex_strength(ss, brush, vd.co, sqrt(test.dist), + ss->cache->sculpt_normal_symm, vd.no, + vd.fno, vd.mask ? *vd.mask : 0.0f); + + mul_v3_v3fl(proxy[vd.i], offset, fade); + + if(vd.mvert) + vd.mvert->flag |= ME_VERT_PBVH_UPDATE; + } + } + BKE_pbvh_vertex_iter_end; + } +} + + void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) { Mesh *me = (Mesh *)ob->data; @@ -3223,6 +3267,9 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush) } } + if (brush->sculpt_tool != SCULPT_TOOL_MASK && sd->gravity_factor > 0.0f) + do_gravity(sd, ob, nodes, totnode, sd->gravity_factor); + MEM_freeN(nodes); /* update average stroke position */ @@ -3826,6 +3873,24 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio cache->scale[1] = max_scale / ob->size[1]; cache->scale[2] = max_scale / ob->size[2]; + if (sd->gravity_object) { + Object *gravity_object = sd->gravity_object; + float rmat[3][3], loc[3], size[3]; + + /* get gravity vector in world space */ + copy_v3_v3(cache->gravity_direction, gravity_object->obmat[2]); + normalize_v3(cache->gravity_direction); + + /* transform to sculpted object space by inverting object rotation matrix */ + mat4_to_loc_rot_size(loc, rmat, size, ob->obmat); + /* transposition of orthogonal matrix (rotation), inverts */ + transpose_m3(rmat); + mul_m3_v3(rmat, cache->gravity_direction); + } + else { + cache->gravity_direction[0] = cache->gravity_direction[1] = 0.0; + cache->gravity_direction[2] = sd->gravity_factor; + } cache->plane_trim_squared = brush->plane_trim * brush->plane_trim; -- cgit v1.2.3