Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/subd/subd_dice.cpp')
-rw-r--r--intern/cycles/subd/subd_dice.cpp53
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(&params.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);