diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2010-04-15 14:28:32 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2010-04-15 14:28:32 +0400 |
commit | 9a85013692322f8a821b8228ad552f84d2a215e9 (patch) | |
tree | 666bb54fa093429d65b6b0322e8058c03f5fe223 /source/blender/blenlib/intern | |
parent | 2b018673509fe7a38a6332fae00bd605335bd286 (diff) |
Merge various small changes from render branch:
* Division by zero fix for TNT SVD code.
* Sound fix, in case ffmpeg decode fails, don't use the samples.
* Fix for incorrect bounds of transformed objects in new raytracing code.
* Gave memory arena's a name used for allocations for easier memory
usage debugging.
* Dupligroup no_draw option was using layers but not restrict view/render
setting. (not a bugfix exactly but would do display list context switching
while drawing for no reason).
* Fix objects instanced on hair particles not giving consistent results
when the object is transformed.
* New math functions: madd_v4_v4fl, len_squared_v3v3, interp_v4_v4v4v4,
mul_v4_m4v4, SH and form factor functions, box_minmax_bounds_m4.
* mul_m4_m4m4 and mul_m3_m3m3 now accept the same pointers for multiple
arguments.
* endjob callback for WM jobs system.
* Geometry node uv/color layer now has search list/autocomplete.
* Various small buildsystem tweaks, not strictly needed yet in trunk.
Diffstat (limited to 'source/blender/blenlib/intern')
-rw-r--r-- | source/blender/blenlib/intern/BLI_heap.c | 2 | ||||
-rw-r--r-- | source/blender/blenlib/intern/BLI_memarena.c | 8 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_geom.c | 455 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_geom_inline.c | 138 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_matrix.c | 61 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_vector.c | 8 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_vector_inline.c | 22 | ||||
-rw-r--r-- | source/blender/blenlib/intern/threads.c | 5 |
8 files changed, 664 insertions, 35 deletions
diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c index 6c4e568c380..f6616ecb06b 100644 --- a/source/blender/blenlib/intern/BLI_heap.c +++ b/source/blender/blenlib/intern/BLI_heap.c @@ -69,7 +69,7 @@ Heap *BLI_heap_new() Heap *heap = (Heap*)MEM_callocN(sizeof(Heap), "BLIHeap"); heap->bufsize = 1; heap->tree = (HeapNode**)MEM_mallocN(sizeof(HeapNode*), "BLIHeapTree"); - heap->arena = BLI_memarena_new(1<<16); + heap->arena = BLI_memarena_new(1<<16, "heap arena"); return heap; } diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c index 07e22b30fcc..cdb88e91cad 100644 --- a/source/blender/blenlib/intern/BLI_memarena.c +++ b/source/blender/blenlib/intern/BLI_memarena.c @@ -41,6 +41,7 @@ struct MemArena { unsigned char *curbuf; int bufsize, cursize; + const char *name; int use_calloc; int align; @@ -48,10 +49,11 @@ struct MemArena { LinkNode *bufs; }; -MemArena *BLI_memarena_new(int bufsize) { +MemArena *BLI_memarena_new(int bufsize, const char *name) { MemArena *ma= MEM_callocN(sizeof(*ma), "memarena"); ma->bufsize= bufsize; ma->align = 8; + ma->name= name; return ma; } @@ -94,9 +96,9 @@ void *BLI_memarena_alloc(MemArena *ma, int size) { else ma->cursize = ma->bufsize; if(ma->use_calloc) - ma->curbuf= MEM_callocN(ma->cursize, "memarena calloc"); + ma->curbuf= MEM_callocN(ma->cursize, ma->name); else - ma->curbuf= MEM_mallocN(ma->cursize, "memarena malloc"); + ma->curbuf= MEM_mallocN(ma->cursize, ma->name); BLI_linklist_prepend(&ma->bufs, ma->curbuf); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 27f36752f80..af408e6bcc9 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -26,9 +26,12 @@ * */ +#include "MEM_guardedalloc.h" + #include "BLI_math.h" #include "BLI_memarena.h" -#include "MEM_guardedalloc.h" + +#include "BKE_utildefines.h" /********************************** Polygons *********************************/ @@ -121,10 +124,6 @@ float area_tri_v3(const float v1[3], const float v2[3], const float v3[3]) /* T return (len/2.0f); } -#define MAX2(x,y) ((x)>(y) ? (x) : (y)) -#define MAX3(x,y,z) MAX2(MAX2((x),(y)) , (z)) - - float area_poly_v3(int nr, float verts[][3], float *normal) { float x, y, z, area, max; @@ -1763,6 +1762,27 @@ int box_clip_bounds_m4(float boundbox[2][3], float bounds[4], float winmat[4][4] return flag; } +void box_minmax_bounds_m4(float min[3], float max[3], float boundbox[2][3], float mat[4][4]) +{ + float mn[3], mx[3], vec[3]; + int a; + + copy_v3_v3(mn, min); + copy_v3_v3(mx, max); + + for(a=0; a<8; a++) { + vec[0]= (a & 1)? boundbox[0][0]: boundbox[1][0]; + vec[1]= (a & 2)? boundbox[0][1]: boundbox[1][1]; + vec[2]= (a & 4)? boundbox[0][2]: boundbox[1][2]; + + mul_m4_v3(mat, vec); + DO_MINMAX(vec, mn, mx); + } + + copy_v3_v3(min, mn); + copy_v3_v3(max, mx); +} + /********************************** Mapping **********************************/ void map_to_tube(float *u, float *v,float x, float y, float z) @@ -1794,9 +1814,7 @@ void map_to_sphere(float *u, float *v,float x, float y, float z) } } -/********************************************************/ - -/* Tangents */ +/********************************* Tangents **********************************/ /* For normal map tangents we need to detect uv boundaries, and only average * tangents in case the uvs are connected. Alternative would be to store 1 @@ -1875,7 +1893,7 @@ void tangent_from_uv(float *uv1, float *uv2, float *uv3, float *co1, float *co2, } } -/********************************************************/ +/****************************** Vector Clouds ********************************/ /* vector clouds */ /* void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight,float (*rpos)[3], float *rweight, @@ -2034,3 +2052,422 @@ void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight,flo } } +/******************************* Form Factor *********************************/ + +static void vec_add_dir(float r[3], float v1[3], float v2[3], 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]); +} + +static int ff_visible_quad(float p[3], float n[3], float v0[3], float v1[3], 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 <Accelerate/Accelerate.h> + +typedef union { + vFloat v; + float f[4]; +} vFloatResult; + +static vFloat vec_splat_float(float val) +{ + return (vFloat){val, val, val, val}; +} + +static float ff_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 <xmmintrin.h> + +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 ff_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 ff_normalize(float n[3]) +{ + 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; + } +} + +static float ff_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; + + sub_v3_v3v3(r0, q0, p); + sub_v3_v3v3(r1, q1, p); + sub_v3_v3v3(r2, q2, p); + sub_v3_v3v3(r3, q3, p); + + ff_normalize(r0); + ff_normalize(r1); + ff_normalize(r2); + ff_normalize(r3); + + cross_v3_v3v3(g0, r1, r0); ff_normalize(g0); + cross_v3_v3v3(g1, r2, r1); ff_normalize(g1); + cross_v3_v3v3(g2, r3, r2); ff_normalize(g2); + cross_v3_v3v3(g3, r0, r3); ff_normalize(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; +} + +float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], float v3[3], float v4[3]) +{ + /* computes how much hemisphere defined by point and normal is + covered by a quad or triangle, cosine weighted */ + float q0[3], q1[3], q2[3], q3[3], contrib= 0.0f; + + if(ff_visible_quad(p, n, v1, v2, v3, q0, q1, q2, q3)) + contrib += ff_quad_form_factor(p, n, q0, q1, q2, q3); + + if(v4 && ff_visible_quad(p, n, v1, v3, v4, q0, q1, q2, q3)) + contrib += ff_quad_form_factor(p, n, q0, q1, q2, q3); + + return contrib; +} + diff --git a/source/blender/blenlib/intern/math_geom_inline.c b/source/blender/blenlib/intern/math_geom_inline.c new file mode 100644 index 00000000000..8b04b2a4005 --- /dev/null +++ b/source/blender/blenlib/intern/math_geom_inline.c @@ -0,0 +1,138 @@ +/** + * $Id: math_base_inline.c 26367 2010-01-28 16:02:26Z blendix $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: some of this file. + * + * ***** END GPL LICENSE BLOCK ***** + * */ + +#include "BLI_math.h" + +#ifndef BLI_MATH_GEOM_INLINE +#define BLI_MATH_GEOM_INLINE + +/****************************** Spherical Harmonics **************************/ + +MINLINE void zero_sh(float r[9]) +{ + memset(r, 0, sizeof(float)*9); +} + +MINLINE void copy_sh_sh(float r[9], float a[9]) +{ + memcpy(r, a, sizeof(float)*9); +} + +MINLINE void mul_sh_fl(float r[9], float f) +{ + int i; + + for(i=0; i<9; i++) + r[i] *= f; +} + +MINLINE void add_sh_shsh(float r[9], float a[9], float b[9]) +{ + int i; + + for(i=0; i<9; i++) + r[i]= a[i] + b[i]; +} + +MINLINE float dot_shsh(float a[9], float b[9]) +{ + float r= 0.0f; + int i; + + for(i=0; i<9; i++) + r += a[i]*b[i]; + + return r; +} + +MINLINE float diffuse_shv3(float sh[9], float v[3]) +{ + /* See formula (13) in: + "An Efficient Representation for Irradiance Environment Maps" */ + static const float c1 = 0.429043f, c2 = 0.511664f, c3 = 0.743125f; + static const float c4 = 0.886227f, c5 = 0.247708f; + float x, y, z, sum; + + x= v[0]; + y= v[1]; + z= v[2]; + + sum= c1*sh[8]*(x*x - y*y); + sum += c3*sh[6]*z*z; + sum += c4*sh[0]; + sum += -c5*sh[6]; + sum += 2.0f*c1*(sh[4]*x*y + sh[7]*x*z + sh[5]*y*z); + sum += 2.0f*c2*(sh[3]*x + sh[1]*y + sh[2]*z); + + return sum; +} + +MINLINE void vec_fac_to_sh(float r[9], float v[3], float f) +{ + /* See formula (3) in: + "An Efficient Representation for Irradiance Environment Maps" */ + float sh[9], x, y, z; + + x= v[0]; + y= v[1]; + z= v[2]; + + sh[0]= 0.282095f; + + sh[1]= 0.488603f*y; + sh[2]= 0.488603f*z; + sh[3]= 0.488603f*x; + + sh[4]= 1.092548f*x*y; + sh[5]= 1.092548f*y*z; + sh[6]= 0.315392f*(3.0f*z*z - 1.0f); + sh[7]= 1.092548f*x*z; + sh[8]= 0.546274f*(x*x - y*y); + + mul_sh_fl(sh, f); + copy_sh_sh(r, sh); +} + +MINLINE float eval_shv3(float sh[9], float v[3]) +{ + float tmp[9]; + + vec_fac_to_sh(tmp, v, 1.0f); + return dot_shsh(tmp, sh); +} + +MINLINE void madd_sh_shfl(float r[9], float sh[3], float f) +{ + float tmp[9]; + + copy_sh_sh(tmp, sh); + mul_sh_fl(tmp, f); + add_sh_shsh(r, r, tmp); +} + +#endif /* BLI_MATH_GEOM_INLINE */ + diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index fca8cf445d1..396ae7ca5ee 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -125,10 +125,15 @@ void swap_m4m4(float m1[][4], float m2[][4]) /******************************** Arithmetic *********************************/ -void mul_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) +void mul_m4_m4m4(float m1[][4], float m2_[][4], float m3_[][4]) { - /* matrix product: m1[j][k] = m2[j][i].m3[i][k] */ + float m2[4][4], m3[4][4]; + /* copy so it works when m1 is the same pointer as m2 or m3 */ + copy_m4_m4(m2, m2_); + copy_m4_m4(m3, m3_); + + /* matrix product: m1[j][k] = m2[j][i].m3[i][k] */ m1[0][0] = m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0] + m2[0][3]*m3[3][0]; m1[0][1] = m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1] + m2[0][3]*m3[3][1]; m1[0][2] = m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2] + m2[0][3]*m3[3][2]; @@ -151,20 +156,26 @@ void mul_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) } -void mul_m3_m3m3(float m1[][3], float m3[][3], float m2[][3]) +void mul_m3_m3m3(float m1[][3], float m3_[][3], float m2_[][3]) { - /* m1[i][j] = m2[i][k]*m3[k][j], args are flipped! */ - m1[0][0]= m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0]; - m1[0][1]= m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1]; - m1[0][2]= m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2]; + float m2[3][3], m3[3][3]; + + /* copy so it works when m1 is the same pointer as m2 or m3 */ + copy_m3_m3(m2, m2_); + copy_m3_m3(m3, m3_); - m1[1][0]= m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0]; - m1[1][1]= m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1]; - m1[1][2]= m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2]; + /* m1[i][j] = m2[i][k]*m3[k][j], args are flipped! */ + m1[0][0]= m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0]; + m1[0][1]= m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1]; + m1[0][2]= m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2]; - m1[2][0]= m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0]; - m1[2][1]= m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1]; - m1[2][2]= m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2]; + m1[1][0]= m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0]; + m1[1][1]= m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1]; + m1[1][2]= m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2]; + + m1[2][0]= m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0]; + m1[2][1]= m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1]; + m1[2][2]= m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2]; } void mul_m4_m4m3(float (*m1)[4], float (*m3)[4], float (*m2)[3]) @@ -321,17 +332,23 @@ void mul_project_m4_v4(float mat[][4], float *vec) vec[2] /= w; } -void mul_m4_v4(float mat[][4], float *vec) +void mul_v4_m4v4(float r[4], float mat[4][4], float v[4]) { - float x,y,z; + float x, y, z; - x=vec[0]; - y=vec[1]; - z= vec[2]; - vec[0]=x*mat[0][0] + y*mat[1][0] + z*mat[2][0] + mat[3][0]*vec[3]; - vec[1]=x*mat[0][1] + y*mat[1][1] + z*mat[2][1] + mat[3][1]*vec[3]; - vec[2]=x*mat[0][2] + y*mat[1][2] + z*mat[2][2] + mat[3][2]*vec[3]; - vec[3]=x*mat[0][3] + y*mat[1][3] + z*mat[2][3] + mat[3][3]*vec[3]; + x= v[0]; + y= v[1]; + z= v[2]; + + r[0]= x*mat[0][0] + y*mat[1][0] + z*mat[2][0] + mat[3][0]*v[3]; + r[1]= x*mat[0][1] + y*mat[1][1] + z*mat[2][1] + mat[3][1]*v[3]; + r[2]= x*mat[0][2] + y*mat[1][2] + z*mat[2][2] + mat[3][2]*v[3]; + r[3]= x*mat[0][3] + y*mat[1][3] + z*mat[2][3] + mat[3][3]*v[3]; +} + +void mul_m4_v4(float mat[4][4], float r[4]) +{ + mul_v4_m4v4(r, mat, r); } void mul_v3_m3v3(float r[3], float M[3][3], float a[3]) diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 8032cd64de5..9baf897c830 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -83,6 +83,14 @@ void interp_v3_v3v3v3v3(float p[3], const float v1[3], const float v2[3], const p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2] + v4[2]*w[3]; } +void interp_v4_v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float w[3]) +{ + p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2]; + p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2]; + p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2]; + p[3] = v1[3]*w[0] + v2[3]*w[1] + v3[3]*w[2]; +} + void mid_v3_v3v3(float *v, float *v1, float *v2) { v[0]= 0.5f*(v1[0] + v2[0]); diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index f82daaa8af6..974832051af 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -188,6 +188,12 @@ MINLINE void mul_v3_v3(float r[3], const float a[3]) r[2] *= a[2]; } +MINLINE void madd_v2_v2fl(float r[2], const float a[2], float f) +{ + r[0] += a[0]*f; + r[1] += a[1]*f; +} + MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f) { r[0] += a[0]*f; @@ -222,6 +228,14 @@ MINLINE void madd_v3_v3v3v3(float r[3], const float a[3], const float b[3], cons r[2] = a[2] + b[2]*c[2]; } +MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f) +{ + r[0] += a[0]*f; + r[1] += a[1]*f; + r[2] += a[2]*f; + r[3] += a[3]*f; +} + MINLINE void mul_v3_v3v3(float *v, const float *v1, const float *v2) { v[0] = v1[0] * v2[0]; @@ -305,6 +319,14 @@ MINLINE float len_v3v3(const float a[3], const float b[3]) return len_v3(d); } +MINLINE float len_squared_v3v3(const float a[3], const float b[3]) +{ + float d[3]; + + sub_v3_v3v3(d, b, a); + return dot_v3v3(d, d); +} + MINLINE float normalize_v2_v2(float r[2], const float a[2]) { float d= dot_v2v2(a, a); diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index 6e2eff6f97a..aa87a56a60c 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -106,6 +106,7 @@ static pthread_mutex_t _image_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _preview_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _viewer_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _custom1_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t _rcache_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_t mainid; static int thread_levels= 0; /* threads can be invoked inside threads */ @@ -340,6 +341,8 @@ void BLI_lock_thread(int type) pthread_mutex_lock(&_viewer_lock); else if (type==LOCK_CUSTOM1) pthread_mutex_lock(&_custom1_lock); + else if (type==LOCK_RCACHE) + pthread_mutex_lock(&_rcache_lock); } void BLI_unlock_thread(int type) @@ -352,6 +355,8 @@ void BLI_unlock_thread(int type) pthread_mutex_unlock(&_viewer_lock); else if(type==LOCK_CUSTOM1) pthread_mutex_unlock(&_custom1_lock); + else if(type==LOCK_RCACHE) + pthread_mutex_unlock(&_rcache_lock); } /* Mutex Locks */ |