diff options
Diffstat (limited to 'intern/cycles/subd/subd_dice.cpp')
-rw-r--r-- | intern/cycles/subd/subd_dice.cpp | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp index 44bab066dde..a5dfcd21ceb 100644 --- a/intern/cycles/subd/subd_dice.cpp +++ b/intern/cycles/subd/subd_dice.cpp @@ -58,10 +58,9 @@ void EdgeDice::reserve(int num_verts, int num_tris) int EdgeDice::add_vert(Patch *patch, float2 uv) { - float3 P, N, dPdu, dPdv; + float3 P, N; - patch->eval(&P, &dPdu, &dPdv, uv.x, uv.y); - N = normalize(cross(dPdu, dPdv)); + patch->eval(&P, NULL, NULL, &N, uv.x, uv.y); assert(vert_offset < params.mesh->verts.size()); @@ -81,7 +80,7 @@ int EdgeDice::add_vert(Patch *patch, float2 uv) void EdgeDice::add_triangle(Patch *patch, int v0, int v1, int v2) { - params.mesh->add_triangle(v0, v1, v2, params.shader, params.smooth); + params.mesh->add_triangle(v0, v1, v2, params.shader, params.smooth, false); if(params.ptex) { Attribute *attr_ptex_face_id = params.mesh->attributes.add(ATTR_STD_PTEX_FACE_ID); @@ -159,7 +158,7 @@ float3 QuadDice::eval_projected(SubPatch& sub, float u, float v) float2 uv = map_uv(sub, u, v); float3 P; - sub.patch->eval(&P, NULL, NULL, uv.x, uv.y); + sub.patch->eval(&P, NULL, NULL, NULL, uv.x, uv.y); if(params.camera) P = transform_perspective(¶ms.camera->worldtoraster, P); @@ -260,17 +259,10 @@ float QuadDice::scale_factor(SubPatch& sub, EdgeFactors& ef, int Mu, int Mv) void QuadDice::add_corners(SubPatch& sub) { /* add verts for patch corners */ - if(sub.patch->is_triangle()) { - add_vert(sub, 0.0f, 0.0f); - add_vert(sub, 1.0f, 0.0f); - add_vert(sub, 0.0f, 1.0f); - } - else { - add_vert(sub, 0.0f, 0.0f); - add_vert(sub, 1.0f, 0.0f); - add_vert(sub, 0.0f, 1.0f); - add_vert(sub, 1.0f, 1.0f); - } + add_vert(sub, 0.0f, 0.0f); + add_vert(sub, 1.0f, 0.0f); + add_vert(sub, 0.0f, 1.0f); + add_vert(sub, 1.0f, 1.0f); } void QuadDice::add_grid(SubPatch& sub, int Mu, int Mv, int offset) @@ -305,7 +297,12 @@ void QuadDice::dice(SubPatch& sub, EdgeFactors& ef) int Mu = max(ef.tu0, ef.tu1); int Mv = max(ef.tv0, ef.tv1); +#if 0 /* Doesnt work very well, especially at grazing angles. */ float S = scale_factor(sub, ef, Mu, Mv); +#else + float S = 1.0f; +#endif + Mu = max((int)ceil(S*Mu), 2); // XXX handle 0 & 1? Mv = max((int)ceil(S*Mv), 2); // XXX handle 0 & 1? @@ -454,15 +451,21 @@ void TriangleDice::add_grid(SubPatch& sub, EdgeFactors& ef, int M) add_triangle(sub.patch, outer_w[0], outer_u[0], outer_v[0]); } else { - /* center vertex + 6 triangles */ + /* center vertex + up to 6 triangles */ int center = add_vert(sub, make_float2(1.0f/3.0f, 1.0f/3.0f)); add_triangle(sub.patch, outer_w[0], outer_w[1], center); - add_triangle(sub.patch, outer_w[1], outer_w[2], center); + /* if this is false then there is only one triangle on this side */ + if(outer_w.size() > 2) + add_triangle(sub.patch, outer_w[1], outer_w[2], center); + add_triangle(sub.patch, outer_u[0], outer_u[1], center); - add_triangle(sub.patch, outer_u[1], outer_u[2], center); + if(outer_u.size() > 2) + add_triangle(sub.patch, outer_u[1], outer_u[2], center); + add_triangle(sub.patch, outer_v[0], outer_v[1], center); - add_triangle(sub.patch, outer_v[1], outer_v[2], center); + if(outer_v.size() > 2) + add_triangle(sub.patch, outer_v[1], outer_v[2], center); } } @@ -471,6 +474,16 @@ void TriangleDice::dice(SubPatch& sub, EdgeFactors& ef) /* todo: handle 2 1 1 resolution */ int M = max(ef.tu, max(ef.tv, ef.tw)); + /* Due to the "slant" of the edges of a triangle compared to a quad, the internal + * triangles end up smaller, causing over-tessellation. This is to correct for this + * difference in area. Technically its only correct for equilateral triangles, but + * its better than how it was. + * + * (2*cos(radians(30))/3)**0.5 + */ + float S = 0.7598356856515927f; + M = max((int)ceil(S*M), 1); + reserve(ef, M); add_grid(sub, ef, M); |