From 79e80d83229aaa1d81da84edc3102db0b00171d9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 3 Mar 2013 05:07:58 +0000 Subject: code cleanup: ~400 duplicate lines for AO form factor math. --- source/blender/render/intern/source/occlusion.c | 416 +----------------------- 1 file changed, 4 insertions(+), 412 deletions(-) (limited to 'source/blender/render') diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index 747362a7974..1c594ef7db2 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -763,414 +763,6 @@ static float occ_solid_angle(OccNode *node, const float v[3], float d2, float in return ((node->area * dotemit * dotreceive) / (d2 + node->area * INVPI)) * INVPI; } -static void vec_add_dir(float r[3], const float v1[3], const float v2[3], const float fac) -{ - r[0] = v1[0] + fac * (v2[0] - v1[0]); - r[1] = v1[1] + fac * (v2[1] - v1[1]); - r[2] = v1[2] + fac * (v2[2] - v1[2]); -} - -/* TODO: exact duplicate of ff_visible_quad() in math_geom.c - * why not de-duplicate? (also above helper func) */ -static int occ_visible_quad(const float p[3], const float n[3], - const float v0[3], const float v1[3], const float v2[3], - float q0[3], float q1[3], float q2[3], float q3[3]) -{ - static const float epsilon = 1e-6f; - float c, sd[3]; - - c = dot_v3v3(n, p); - - /* signed distances from the vertices to the plane. */ - sd[0] = dot_v3v3(n, v0) - c; - sd[1] = dot_v3v3(n, v1) - c; - sd[2] = dot_v3v3(n, v2) - c; - - if (fabsf(sd[0]) < epsilon) sd[0] = 0.0f; - if (fabsf(sd[1]) < epsilon) sd[1] = 0.0f; - if (fabsf(sd[2]) < epsilon) sd[2] = 0.0f; - - if (sd[0] > 0) { - if (sd[1] > 0) { - if (sd[2] > 0) { - /* +++ */ - copy_v3_v3(q0, v0); - copy_v3_v3(q1, v1); - copy_v3_v3(q2, v2); - copy_v3_v3(q3, q2); - } - else if (sd[2] < 0) { - /* ++- */ - copy_v3_v3(q0, v0); - copy_v3_v3(q1, v1); - vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2]))); - vec_add_dir(q3, v0, v2, (sd[0] / (sd[0] - sd[2]))); - } - else { - /* ++0 */ - copy_v3_v3(q0, v0); - copy_v3_v3(q1, v1); - copy_v3_v3(q2, v2); - copy_v3_v3(q3, q2); - } - } - else if (sd[1] < 0) { - if (sd[2] > 0) { - /* +-+ */ - copy_v3_v3(q0, v0); - vec_add_dir(q1, v0, v1, (sd[0] / (sd[0] - sd[1]))); - vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2]))); - copy_v3_v3(q3, v2); - } - else if (sd[2] < 0) { - /* +-- */ - copy_v3_v3(q0, v0); - vec_add_dir(q1, v0, v1, (sd[0] / (sd[0] - sd[1]))); - vec_add_dir(q2, v0, v2, (sd[0] / (sd[0] - sd[2]))); - copy_v3_v3(q3, q2); - } - else { - /* +-0 */ - copy_v3_v3(q0, v0); - vec_add_dir(q1, v0, v1, (sd[0] / (sd[0] - sd[1]))); - copy_v3_v3(q2, v2); - copy_v3_v3(q3, q2); - } - } - else { - if (sd[2] > 0) { - /* +0+ */ - copy_v3_v3(q0, v0); - copy_v3_v3(q1, v1); - copy_v3_v3(q2, v2); - copy_v3_v3(q3, q2); - } - else if (sd[2] < 0) { - /* +0- */ - copy_v3_v3(q0, v0); - copy_v3_v3(q1, v1); - vec_add_dir(q2, v0, v2, (sd[0] / (sd[0] - sd[2]))); - copy_v3_v3(q3, q2); - } - else { - /* +00 */ - copy_v3_v3(q0, v0); - copy_v3_v3(q1, v1); - copy_v3_v3(q2, v2); - copy_v3_v3(q3, q2); - } - } - } - else if (sd[0] < 0) { - if (sd[1] > 0) { - if (sd[2] > 0) { - /* -++ */ - vec_add_dir(q0, v0, v1, (sd[0] / (sd[0] - sd[1]))); - copy_v3_v3(q1, v1); - copy_v3_v3(q2, v2); - vec_add_dir(q3, v0, v2, (sd[0] / (sd[0] - sd[2]))); - } - else if (sd[2] < 0) { - /* -+- */ - vec_add_dir(q0, v0, v1, (sd[0] / (sd[0] - sd[1]))); - copy_v3_v3(q1, v1); - vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2]))); - copy_v3_v3(q3, q2); - } - else { - /* -+0 */ - vec_add_dir(q0, v0, v1, (sd[0] / (sd[0] - sd[1]))); - copy_v3_v3(q1, v1); - copy_v3_v3(q2, v2); - copy_v3_v3(q3, q2); - } - } - else if (sd[1] < 0) { - if (sd[2] > 0) { - /* --+ */ - vec_add_dir(q0, v0, v2, (sd[0] / (sd[0] - sd[2]))); - vec_add_dir(q1, v1, v2, (sd[1] / (sd[1] - sd[2]))); - copy_v3_v3(q2, v2); - copy_v3_v3(q3, q2); - } - else if (sd[2] < 0) { - /* --- */ - return 0; - } - else { - /* --0 */ - return 0; - } - } - else { - if (sd[2] > 0) { - /* -0+ */ - vec_add_dir(q0, v0, v2, (sd[0] / (sd[0] - sd[2]))); - copy_v3_v3(q1, v1); - copy_v3_v3(q2, v2); - copy_v3_v3(q3, q2); - } - else if (sd[2] < 0) { - /* -0- */ - return 0; - } - else { - /* -00 */ - return 0; - } - } - } - else { - if (sd[1] > 0) { - if (sd[2] > 0) { - /* 0++ */ - copy_v3_v3(q0, v0); - copy_v3_v3(q1, v1); - copy_v3_v3(q2, v2); - copy_v3_v3(q3, q2); - } - else if (sd[2] < 0) { - /* 0+- */ - copy_v3_v3(q0, v0); - copy_v3_v3(q1, v1); - vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2]))); - copy_v3_v3(q3, q2); - } - else { - /* 0+0 */ - copy_v3_v3(q0, v0); - copy_v3_v3(q1, v1); - copy_v3_v3(q2, v2); - copy_v3_v3(q3, q2); - } - } - else if (sd[1] < 0) { - if (sd[2] > 0) { - /* 0-+ */ - copy_v3_v3(q0, v0); - vec_add_dir(q1, v1, v2, (sd[1] / (sd[1] - sd[2]))); - copy_v3_v3(q2, v2); - copy_v3_v3(q3, q2); - } - else if (sd[2] < 0) { - /* 0-- */ - return 0; - } - else { - /* 0-0 */ - return 0; - } - } - else { - if (sd[2] > 0) { - /* 00+ */ - copy_v3_v3(q0, v0); - copy_v3_v3(q1, v1); - copy_v3_v3(q2, v2); - copy_v3_v3(q3, q2); - } - else if (sd[2] < 0) { - /* 00- */ - return 0; - } - else { - /* 000 */ - return 0; - } - } - } - - return 1; -} - -/* altivec optimization, this works, but is unused */ - -#if 0 -#include - -typedef union { - vFloat v; - float f[4]; -} vFloatResult; - -static vFloat vec_splat_float(float val) -{ - return (vFloat) {val, val, val, val}; -} - -static float occ_quad_form_factor(float *p, float *n, float *q0, float *q1, float *q2, float *q3) -{ - vFloat vcos, rlen, vrx, vry, vrz, vsrx, vsry, vsrz, gx, gy, gz, vangle; - vUInt8 rotate = (vUInt8) {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3}; - vFloatResult vresult; - float result; - - /* compute r* */ - vrx = (vFloat) {q0[0], q1[0], q2[0], q3[0]} -vec_splat_float(p[0]); - vry = (vFloat) {q0[1], q1[1], q2[1], q3[1]} -vec_splat_float(p[1]); - vrz = (vFloat) {q0[2], q1[2], q2[2], q3[2]} -vec_splat_float(p[2]); - - /* normalize r* */ - rlen = vec_rsqrte(vrx * vrx + vry * vry + vrz * vrz + vec_splat_float(1e-16f)); - vrx = vrx * rlen; - vry = vry * rlen; - vrz = vrz * rlen; - - /* rotate r* for cross and dot */ - vsrx = vec_perm(vrx, vrx, rotate); - vsry = vec_perm(vry, vry, rotate); - vsrz = vec_perm(vrz, vrz, rotate); - - /* cross product */ - gx = vsry * vrz - vsrz * vry; - gy = vsrz * vrx - vsrx * vrz; - gz = vsrx * vry - vsry * vrx; - - /* normalize */ - rlen = vec_rsqrte(gx * gx + gy * gy + gz * gz + vec_splat_float(1e-16f)); - gx = gx * rlen; - gy = gy * rlen; - gz = gz * rlen; - - /* angle */ - vcos = vrx * vsrx + vry * vsry + vrz * vsrz; - vcos = vec_max(vec_min(vcos, vec_splat_float(1.0f)), vec_splat_float(-1.0f)); - vangle = vacosf(vcos); - - /* dot */ - vresult.v = (vec_splat_float(n[0]) * gx + - vec_splat_float(n[1]) * gy + - vec_splat_float(n[2]) * gz) * vangle; - - result = (vresult.f[0] + vresult.f[1] + vresult.f[2] + vresult.f[3]) * (0.5f / (float)M_PI); - result = MAX2(result, 0.0f); - - return result; -} - -#endif - -/* SSE optimization, acos code doesn't work */ - -#if 0 - -#include - -static __m128 sse_approx_acos(__m128 x) -{ - /* needs a better approximation than taylor expansion of acos, since that - * gives big erros for near 1.0 values, sqrt(2*x)*acos(1-x) should work - * better, see http://www.tom.womack.net/projects/sse-fast-arctrig.html */ - - return _mm_set_ps1(1.0f); -} - -static float occ_quad_form_factor(float *p, float *n, float *q0, float *q1, float *q2, float *q3) -{ - float r0[3], r1[3], r2[3], r3[3], g0[3], g1[3], g2[3], g3[3]; - float a1, a2, a3, a4, dot1, dot2, dot3, dot4, result; - float fresult[4] __attribute__((aligned(16))); - __m128 qx, qy, qz, rx, ry, rz, rlen, srx, sry, srz, gx, gy, gz, glen, rcos, angle, aresult; - - /* compute r */ - qx = _mm_set_ps(q3[0], q2[0], q1[0], q0[0]); - qy = _mm_set_ps(q3[1], q2[1], q1[1], q0[1]); - qz = _mm_set_ps(q3[2], q2[2], q1[2], q0[2]); - - rx = qx - _mm_set_ps1(p[0]); - ry = qy - _mm_set_ps1(p[1]); - rz = qz - _mm_set_ps1(p[2]); - - /* normalize r */ - rlen = _mm_rsqrt_ps(rx * rx + ry * ry + rz * rz + _mm_set_ps1(1e-16f)); - rx = rx * rlen; - ry = ry * rlen; - rz = rz * rlen; - - /* cross product */ - srx = _mm_shuffle_ps(rx, rx, _MM_SHUFFLE(0, 3, 2, 1)); - sry = _mm_shuffle_ps(ry, ry, _MM_SHUFFLE(0, 3, 2, 1)); - srz = _mm_shuffle_ps(rz, rz, _MM_SHUFFLE(0, 3, 2, 1)); - - gx = sry * rz - srz * ry; - gy = srz * rx - srx * rz; - gz = srx * ry - sry * rx; - - /* normalize g */ - glen = _mm_rsqrt_ps(gx * gx + gy * gy + gz * gz + _mm_set_ps1(1e-16f)); - gx = gx * glen; - gy = gy * glen; - gz = gz * glen; - - /* compute angle */ - rcos = rx * srx + ry * sry + rz * srz; - rcos = _mm_max_ps(_mm_min_ps(rcos, _mm_set_ps1(1.0f)), _mm_set_ps1(-1.0f)); - - angle = sse_approx_cos(rcos); - aresult = (_mm_set_ps1(n[0]) * gx + _mm_set_ps1(n[1]) * gy + _mm_set_ps1(n[2]) * gz) * angle; - - /* sum together */ - result = (fresult[0] + fresult[1] + fresult[2] + fresult[3]) * (0.5f / (float)M_PI); - result = MAX2(result, 0.0f); - - return result; -} - -#endif - -static void normalizef(float *n) -{ - float d; - - d = dot_v3v3(n, n); - - if (d > 1.0e-35F) { - d = 1.0f / sqrtf(d); - - n[0] *= d; - n[1] *= d; - n[2] *= d; - } -} - -/* TODO: exact duplicate of ff_quad_form_factor() in math_geom.c - * why not de-duplicate? (also above helper func) */ -static float occ_quad_form_factor(const float p[3], const float n[3], const float q0[3], const float q1[3], const float q2[3], const float q3[3]) -{ - float r0[3], r1[3], r2[3], r3[3], g0[3], g1[3], g2[3], g3[3]; - float a1, a2, a3, a4, dot1, dot2, dot3, dot4, result; - - sub_v3_v3v3(r0, q0, p); - sub_v3_v3v3(r1, q1, p); - sub_v3_v3v3(r2, q2, p); - sub_v3_v3v3(r3, q3, p); - - normalizef(r0); - normalizef(r1); - normalizef(r2); - normalizef(r3); - - cross_v3_v3v3(g0, r1, r0); normalizef(g0); - cross_v3_v3v3(g1, r2, r1); normalizef(g1); - cross_v3_v3v3(g2, r3, r2); normalizef(g2); - cross_v3_v3v3(g3, r0, r3); normalizef(g3); - - a1 = saacosf(dot_v3v3(r0, r1)); - a2 = saacosf(dot_v3v3(r1, r2)); - a3 = saacosf(dot_v3v3(r2, r3)); - a4 = saacosf(dot_v3v3(r3, r0)); - - dot1 = dot_v3v3(n, g0); - dot2 = dot_v3v3(n, g1); - dot3 = dot_v3v3(n, g2); - dot4 = dot_v3v3(n, g3); - - result = (a1 * dot1 + a2 * dot2 + a3 * dot3 + a4 * dot4) * 0.5f / (float)M_PI; - result = MAX2(result, 0.0f); - - return result; -} - static float occ_form_factor(OccFace *face, float *p, float *n) { ObjectInstanceRen *obi; @@ -1190,16 +782,16 @@ static float occ_form_factor(OccFace *face, float *p, float *n) mul_m4_v3(obi->mat, v3); } - if (occ_visible_quad(p, n, v1, v2, v3, q0, q1, q2, q3)) - contrib += occ_quad_form_factor(p, n, q0, q1, q2, q3); + if (form_factor_visible_quad(p, n, v1, v2, v3, q0, q1, q2, q3)) + contrib += form_factor_quad(p, n, q0, q1, q2, q3); if (vlr->v4) { copy_v3_v3(v4, vlr->v4->co); if (obi->flag & R_TRANSFORMED) mul_m4_v3(obi->mat, v4); - if (occ_visible_quad(p, n, v1, v3, v4, q0, q1, q2, q3)) - contrib += occ_quad_form_factor(p, n, q0, q1, q2, q3); + if (form_factor_visible_quad(p, n, v1, v3, v4, q0, q1, q2, q3)) + contrib += form_factor_quad(p, n, q0, q1, q2, q3); } return contrib; -- cgit v1.2.3