Index: release/scripts/ui/properties_physics_field.py
===================================================================
--- release/scripts/ui/properties_physics_field.py	(revision 26838)
+++ release/scripts/ui/properties_physics_field.py	(working copy)
@@ -113,6 +113,14 @@
             col.prop(field, "use_coordinates")
             col.prop(field, "root_coordinates")
             col.prop(field, "force_2d")
+        
+        elif field.type == 'TURBULENCE':
+            basic_force_field_settings_ui(self, context, field)
+
+            col = split.column()
+            col.prop(field, "flow_rotation")
+            col.prop(field, "flow_advection")
+
         else:
             basic_force_field_settings_ui(self, context, field)
 
Index: source/blender/blenkernel/intern/effect.c
===================================================================
--- source/blender/blenkernel/intern/effect.c	(revision 26838)
+++ source/blender/blenkernel/intern/effect.c	(working copy)
@@ -918,9 +918,10 @@
 			else {
 				VECADD(temp, efd->vec_to_point2, efd->nor2);
 			}
-			force[0] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[0], temp[1], temp[2], 2,0,2);
-			force[1] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[1], temp[2], temp[0], 2,0,2);
-			force[2] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[2], temp[0], temp[1], 2,0,2);
+			#define M_2PI 6.283185307
+			force[0] = -1.0f + 2.0f * BLI_flowTurbulence(pd->f_size, temp[0], temp[1], temp[2], pd->flow_rotation*M_2PI, pd->flow_advection, 2, 0);
+			force[1] = -1.0f + 2.0f * BLI_flowTurbulence(pd->f_size, temp[1], temp[2], temp[0], pd->flow_rotation*M_2PI, pd->flow_advection, 2, 0);
+			force[2] = -1.0f + 2.0f * BLI_flowTurbulence(pd->f_size, temp[2], temp[0], temp[1], pd->flow_rotation*M_2PI, pd->flow_advection, 2, 0);
 			mul_v3_fl(force, strength * efd->falloff);
 			break;
 		case PFIELD_DRAG:
Index: source/blender/makesdna/DNA_object_force.h
===================================================================
--- source/blender/makesdna/DNA_object_force.h	(revision 26838)
+++ source/blender/makesdna/DNA_object_force.h	(working copy)
@@ -108,6 +108,10 @@
 	struct RNG *rng;	/* random noise generator for e.g. wind */
 	float f_noise;		/* noise of force						*/
 	int seed;			/* noise random seed					*/
+	
+	/* flow noise parameters */
+	float flow_rotation;
+	float flow_advection;
 } PartDeflect;
 
 typedef struct EffectorWeights {
Index: source/blender/makesrna/intern/rna_object_force.c
===================================================================
--- source/blender/makesrna/intern/rna_object_force.c	(revision 26838)
+++ source/blender/makesrna/intern/rna_object_force.c	(working copy)
@@ -1170,6 +1170,18 @@
 	RNA_def_property_ui_text(prop, "Noise", "Noise of the force");
 	RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
 
+	prop= RNA_def_property(srna, "flow_rotation", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "flow_rotation");
+	RNA_def_property_range(prop, 0.0f, 1.0f);
+	RNA_def_property_ui_text(prop, "Rotation", "Rotation of flow noise");
+	RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
+
+	prop= RNA_def_property(srna, "flow_advection", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "flow_advection");
+	RNA_def_property_range(prop, -2.0f, 2.0f);
+	RNA_def_property_ui_text(prop, "Advection", "Advection of flow noise");
+	RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
+
 	prop= RNA_def_property(srna, "seed", PROP_INT, PROP_UNSIGNED);
 	RNA_def_property_range(prop, 1, 128);
 	RNA_def_property_ui_text(prop, "Seed", "Seed of the noise");
Index: source/blender/blenlib/BLI_noise.h
===================================================================
--- source/blender/blenlib/BLI_noise.h	(revision 26838)
+++ source/blender/blenlib/BLI_noise.h	(working copy)
@@ -56,6 +56,9 @@
 /* newnoise: cellNoise & cellNoiseV (for vector/point/color) */
 float cellNoise(float x, float y, float z);
 void cellNoiseV(float x, float y, float z, float *ca);
+/* flow noise */
+float BLI_flowNoise3(float x, float y, float z, float angle, float *dnoise_dx, float *dnoise_dy, float *dnoise_dz);
+float BLI_flowTurbulence(float noisesize, float x, float y, float z, float angle, float advection, int oct, int hard);
 
 
 #ifdef __cplusplus
Index: source/blender/blenlib/intern/noise.c
===================================================================
--- source/blender/blenlib/intern/noise.c	(revision 26838)
+++ source/blender/blenlib/intern/noise.c	(working copy)
@@ -215,7 +215,7 @@
 	return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v);
 }
 
-/* instead of adding another permutation array, just use hash table defined above */
+/* instead of adding another hashutation array, just use hash table defined above */
 static float newPerlin(float x, float y, float z)
 {
 	int A, AA, AB, B, BA, BB;
@@ -1855,3 +1855,297 @@
 /****************/
 /* musgrave end */
 /****************/
+
+/* Flow noise
+ * This code was copied & modified from Stefan Gustavson's (stefan.gustavson@gmail.com)
+ * DSOnoises package, available under GNU GPL here: http://webstaff.itn.liu.se/~stegu/aqsis/DSOs/DSOnoises.html
+ */
+
+/*
+ * This is an implementation of Perlin "simplex noise" over two dimensions
+ * (x,y) and three dimensions (x,y,z). One extra parameter 't' rotates the
+ * underlying gradients of the grid, which gives a swirling, flow-like
+ * motion. The derivative is returned, to make it possible to do pseudo-
+ * advection and implement "flow noise", as presented by Ken Perlin and
+ * Fabrice Neyret at Siggraph 2001.
+ *
+ * When not animated and presented in one octave only, this noise
+ * looks exactly the same as the plain version of simplex noise.
+ * It's nothing magical by itself, although the extra animation
+ * parameter 't' is useful. Fun stuff starts to happen when you
+ * do fractal sums of several octaves, with different rotation speeds
+ * and an advection of smaller scales by larger scales (or even the
+ * other way around it you feel adventurous).
+ *
+ * The gradient rotations that can be performed by this noise function
+ * and the true analytic derivatives are required to do flow noise.
+ * You can't do it properly with regular Perlin noise.
+ *
+ */
+
+#define FLOW_NOISE_FASTFLOOR(x) ( ((x)>0) ? ((int)x) : (((int)x)-1) )
+
+/*
+ * For 3D, we define two orthogonal vectors in the desired rotation plane.
+ * These vectors are based on the midpoints of the 12 edges of a cube,
+ * they all rotate in their own plane and are never coincident or collinear.
+ * A larger array of random vectors would also do the job, but these 12
+ * (including 4 repeats to make the array length a power of two) work better.
+ * They are not random, they are carefully chosen to represent a small
+ * isotropic set of directions for any rotation angle.
+ */
+
+/* a = sqrt(2)/sqrt(3) = 0.816496580 */
+#define a 0.81649658f
+
+static float grad3u[16][3] = {
+  { 1.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, // 12 cube edges
+  { -1.0f, 0.0f, 1.0f }, { 0.0f, -1.0f, 1.0f },
+  { 1.0f, 0.0f, -1.0f }, { 0.0f, 1.0f, -1.0f },
+  { -1.0f, 0.0f, -1.0f }, { 0.0f, -1.0f, -1.0f },
+  { a, a, a }, { -a, a, -a },
+  { -a, -a, a }, { a, -a, -a },
+  { -a, a, a }, { a, -a, a },
+  { a, -a, -a }, { -a, a, -a }
+};
+
+static float grad3v[16][3] = {
+  { -a, a, a }, { -a, -a, a },
+  { a, -a, a }, { a, a, a },
+  { -a, -a, -a }, { a, -a, -a },
+  { a, a, -a }, { -a, a, -a },
+  { 1.0f, -1.0f, 0.0f }, { 1.0f, 1.0f, 0.0f },
+  { -1.0f, 1.0f, 0.0f }, { -1.0f, -1.0f, 0.0f },
+  { 1.0f, 0.0f, 1.0f }, { -1.0f, 0.0f, 1.0f }, // 4 repeats to make 16
+  { 0.0f, 1.0f, -1.0f }, { 0.0f, -1.0f, -1.0f }
+};
+
+#undef a
+
+static void gradrot3( int hash, float sin_t, float cos_t, float *gx, float *gy, float *gz ) {
+    int h = hash & 15;
+    float gux = grad3u[h][0];
+    float guy = grad3u[h][1];
+    float guz = grad3u[h][2];
+    float gvx = grad3v[h][0];
+    float gvy = grad3v[h][1];
+    float gvz = grad3v[h][2];
+    *gx = cos_t * gux + sin_t * gvx;
+    *gy = cos_t * guy + sin_t * gvy;
+    *gz = cos_t * guz + sin_t * gvz;
+    return;
+}
+
+static float graddotp3( float gx, float gy, float gz, float x, float y, float z ) {
+  return gx * x + gy * y + gz * z;
+}
+
+/* Skewing factors for 3D simplex grid:
+ * F3 = 1/3
+ * G3 = 1/6 */
+#define FLOW_NOISE_F3 0.333333333
+#define FLOW_NOISE_G3 0.166666667
+
+float BLI_flowNoise3( float _x, float _y, float _z, float angle,
+                 float *dnoise_dx, float *dnoise_dy, float *dnoise_dz )
+{
+	/* TODO the pattern seems to repeat for something like z+0.5*x+0.5*y < 0
+	 * This is a workaround, which provides a quick fix, but should be fixed in the main code - phonybone
+	 */
+	float x = (_x < 0.0f ? 512.0f - fmod(-_x, 512.0f) : _x);
+	float y = (_y < 0.0f ? 512.0f - fmod(-_y, 512.0f) : _y);
+	float z = (_z < 0.0f ? 512.0f - fmod(-_z, 512.0f) : _z);
+	/* end workaround */
+	
+	float n0, n1, n2, n3; /* Noise contributions from the four simplex corners */
+	float noise;          /* Return value */
+	float gx0, gy0, gz0, gx1, gy1, gz1; /* Gradients at simplex corners */
+	float gx2, gy2, gz2, gx3, gy3, gz3;
+	float sin_t, cos_t; /* Sine and cosine for the gradient rotation angle */
+
+	/* Skew the input space to determine which simplex cell we're in */
+	float s = (x+y+z)*FLOW_NOISE_F3; /* Very nice and simple skew factor for 3D */
+	float xs = x+s;
+	float ys = y+s;
+	float zs = z+s;
+	int i = FLOW_NOISE_FASTFLOOR(xs);
+	int j = FLOW_NOISE_FASTFLOOR(ys);
+	int k = FLOW_NOISE_FASTFLOOR(zs);
+
+	float t = (float)(i+j+k)*FLOW_NOISE_G3; 
+	float X0 = i-t; /* Unskew the cell origin back to (x,y,z) space */
+	float Y0 = j-t;
+	float Z0 = k-t;
+	float x0 = x-X0; /* The x,y,z distances from the cell origin */
+	float y0 = y-Y0;
+	float z0 = z-Z0;
+
+	/* For the 3D case, the simplex shape is a slightly irregular tetrahedron.
+	 * Determine which simplex we are in. */
+	int i1, j1, k1; /* Offsets for second corner of simplex in (i,j,k) coords */
+	int i2, j2, k2; /* Offsets for third corner of simplex in (i,j,k) coords */
+	
+	float x1, y1, z1, x2, y2, z2, x3, y3, z3;
+	int ii, jj, kk;
+	float t0, t20, t40, t1, t21, t41, t2, t22, t42, t3, t23, t43;
+
+	sin_t = sin( angle );
+	cos_t = cos( angle );
+
+	if(x0>=y0) {
+		if(y0>=z0)
+		{ i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; } /* X Y Z order */
+		else if(x0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; } /* X Z Y order */
+		else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } /* Z X Y order */
+		}
+	else { // x0<y0
+		if(y0<z0) { i1=0; j1=0; k1=1; i2=0; j2=1; k2=1; } /* Z Y X order */
+		else if(x0<z0) { i1=0; j1=1; k1=0; i2=0; j2=1; k2=1; } /* Y Z X order */
+		else { i1=0; j1=1; k1=0; i2=1; j2=1; k2=0; } /* Y X Z order */
+	}
+
+	/* A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
+	 * a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
+	 * a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
+	 * c = 1/6.   */
+
+	x1 = x0 - i1 + FLOW_NOISE_G3; /* Offsets for second corner in (x,y,z) coords */
+	y1 = y0 - j1 + FLOW_NOISE_G3;
+	z1 = z0 - k1 + FLOW_NOISE_G3;
+	x2 = x0 - i2 + 2.0f * FLOW_NOISE_G3; /* Offsets for third corner in (x,y,z) coords */
+	y2 = y0 - j2 + 2.0f * FLOW_NOISE_G3;
+	z2 = z0 - k2 + 2.0f * FLOW_NOISE_G3;
+	x3 = x0 - 1.0f + 3.0f * FLOW_NOISE_G3; /* Offsets for last corner in (x,y,z) coords */
+	y3 = y0 - 1.0f + 3.0f * FLOW_NOISE_G3;
+	z3 = z0 - 1.0f + 3.0f * FLOW_NOISE_G3;
+
+	/* Wrap the integer indices at 256, to avoid indexing hash[] out of bounds */
+	ii = i % 256;
+	jj = j % 256;
+	kk = k % 256;
+
+	/* Calculate the contribution from the four corners */
+	t0 = 0.6f - x0*x0 - y0*y0 - z0*z0;
+	if(t0 < 0.0f) n0 = t0 = t20 = t40 = gx0 = gy0 = gz0 = 0.0f;
+	else {
+		gradrot3( hash[ii + hash[jj + hash[kk]]], sin_t, cos_t, &gx0, &gy0, &gz0 );
+		t20 = t0 * t0;
+		t40 = t20 * t20;
+		n0 = t40 * graddotp3( gx0, gy0, gz0, x0, y0, z0 );
+	}
+
+	t1 = 0.6f - x1*x1 - y1*y1 - z1*z1;
+	if(t1 < 0.0f) n1 = t1 = t21 = t41 = gx1 = gy1 = gz1 = 0.0f;
+	else {
+		gradrot3( hash[ii + i1 + hash[jj + j1 + hash[kk + k1]]], sin_t, cos_t, &gx1, &gy1, &gz1 );
+		t21 = t1 * t1;
+		t41 = t21 * t21;
+		n1 = t41 * graddotp3( gx1, gy1, gz1, x1, y1, z1 );
+	}
+
+	t2 = 0.6f - x2*x2 - y2*y2 - z2*z2;
+	if(t2 < 0.0f) n2 = t2 = t22 = t42 = gx2 = gy2 = gz2 = 0.0f;
+	else {
+		gradrot3( hash[ii + i2 + hash[jj + j2 + hash[kk + k2]]], sin_t, cos_t, &gx2, &gy2, &gz2 );
+		t22 = t2 * t2;
+		t42 = t22 * t22;
+		n2 = t42 * graddotp3( gx2, gy2, gz2, x2, y2, z2 );
+	}
+
+	t3 = 0.6f - x3*x3 - y3*y3 - z3*z3;
+	if(t3 < 0.0f) n3 = t3 = t23 = t43 = gx3 = gy3 = gz3 = 0.0f;
+	else {
+		gradrot3( hash[ii + 1 + hash[jj + 1 + hash[kk + 1]]], sin_t, cos_t, &gx3, &gy3, &gz3 );
+		t23 = t3 * t3;
+		t43 = t23 * t23;
+		n3 = t43 * graddotp3( gx3, gy3, gz3, x3, y3, z3 );
+	}
+
+	/*  Add contributions from each corner to get the final noise value.
+		* The result is scaled to return values in the range [-1,1] */
+	noise = 28.0f * (n0 + n1 + n2 + n3);
+
+	/* Compute derivative, if requested by supplying non-null pointers
+		* for the last three arguments */
+	if( ( dnoise_dx != 0 ) && ( dnoise_dy != 0 ) && ( dnoise_dz != 0 ))
+	{
+		/*  A straight, unoptimised calculation would be like:
+		*     *dnoise_dx = -8.0f * t20 * t0 * x0 * graddotp3(gx0, gy0, gz0, x0, y0, z0) + t40 * gx0;
+		*    *dnoise_dy = -8.0f * t20 * t0 * y0 * graddotp3(gx0, gy0, gz0, x0, y0, z0) + t40 * gy0;
+		*    *dnoise_dz = -8.0f * t20 * t0 * z0 * graddotp3(gx0, gy0, gz0, x0, y0, z0) + t40 * gz0;
+		*    *dnoise_dx += -8.0f * t21 * t1 * x1 * graddotp3(gx1, gy1, gz1, x1, y1, z1) + t41 * gx1;
+		*    *dnoise_dy += -8.0f * t21 * t1 * y1 * graddotp3(gx1, gy1, gz1, x1, y1, z1) + t41 * gy1;
+		*    *dnoise_dz += -8.0f * t21 * t1 * z1 * graddotp3(gx1, gy1, gz1, x1, y1, z1) + t41 * gz1;
+		*    *dnoise_dx += -8.0f * t22 * t2 * x2 * graddotp3(gx2, gy2, gz2, x2, y2, z2) + t42 * gx2;
+		*    *dnoise_dy += -8.0f * t22 * t2 * y2 * graddotp3(gx2, gy2, gz2, x2, y2, z2) + t42 * gy2;
+		*    *dnoise_dz += -8.0f * t22 * t2 * z2 * graddotp3(gx2, gy2, gz2, x2, y2, z2) + t42 * gz2;
+		*    *dnoise_dx += -8.0f * t23 * t3 * x3 * graddotp3(gx3, gy3, gz3, x3, y3, z3) + t43 * gx3;
+		*    *dnoise_dy += -8.0f * t23 * t3 * y3 * graddotp3(gx3, gy3, gz3, x3, y3, z3) + t43 * gy3;
+		*    *dnoise_dz += -8.0f * t23 * t3 * z3 * graddotp3(gx3, gy3, gz3, x3, y3, z3) + t43 * gz3;
+		*/
+		float temp0, temp1, temp2, temp3;
+		temp0 = t20 * t0 * graddotp3( gx0, gy0, gz0, x0, y0, z0 );
+		*dnoise_dx = temp0 * x0;
+		*dnoise_dy = temp0 * y0;
+		*dnoise_dz = temp0 * z0;
+		temp1 = t21 * t1 * graddotp3( gx1, gy1, gz1, x1, y1, z1 );
+		*dnoise_dx += temp1 * x1;
+		*dnoise_dy += temp1 * y1;
+		*dnoise_dz += temp1 * z1;
+		temp2 = t22 * t2 * graddotp3( gx2, gy2, gz2, x2, y2, z2 );
+		*dnoise_dx += temp2 * x2;
+		*dnoise_dy += temp2 * y2;
+		*dnoise_dz += temp2 * z2;
+		temp3 = t23 * t3 * graddotp3( gx3, gy3, gz3, x3, y3, z3 );
+		*dnoise_dx += temp3 * x3;
+		*dnoise_dy += temp3 * y3;
+		*dnoise_dz += temp3 * z3;
+		*dnoise_dx *= -8.0f;
+		*dnoise_dy *= -8.0f;
+		*dnoise_dz *= -8.0f;
+		/* This corrects a bug in the original implementation */
+		*dnoise_dx += t40 * gx0 + t41 * gx1 + t42 * gx2 + t43 * gx3;
+		*dnoise_dy += t40 * gy0 + t41 * gy1 + t42 * gy2 + t43 * gy3;
+		*dnoise_dz += t40 * gz0 + t41 * gz1 + t42 * gz2 + t43 * gz3;
+		*dnoise_dx *= 28.0f; /* Scale derivative to match the noise scaling */
+		*dnoise_dy *= 28.0f;
+		*dnoise_dz *= 28.0f;
+	}
+	return noise;
+}
+
+float BLI_flowTurbulence(float noisesize, float x, float y, float z, float angle, float advection, int oct, int hard)
+{
+	float sum, t, amp=1, adv_amp=advection, fscale=1;
+	int i;
+	float dx, dy, dz, adv_x=0.0f, adv_y=0.0f, adv_z=0.0f;
+	
+	if (noisesize!=0.0) {
+		noisesize = 1.0/noisesize;
+		x *= noisesize;
+		y *= noisesize;
+		z *= noisesize;
+	}
+	
+	sum = 0.0f;
+	if (hard) {
+		for (i=0; i<=oct; i++, amp*=0.5, adv_amp*=0.5f, fscale*=2) {
+			t = BLI_flowNoise3(fscale*x + adv_x, fscale*y + adv_y, fscale*z + adv_z, angle, &dx, &dy, &dz);
+			adv_x -= dx*adv_amp; adv_y -= dy*adv_amp; adv_z -= dz*adv_amp;
+			sum += t * amp;
+		}
+	} else {
+		for (i=0; i<=oct; i++, amp*=0.5, fscale*=2) {
+			t = 0.5f*(1.0f + BLI_flowNoise3(fscale*x + adv_x, fscale*y + adv_y, fscale*z + adv_z, angle, &dx, &dy, &dz));
+			adv_x -= dx*adv_amp; adv_y -= dy*adv_amp; adv_z -= dz*adv_amp;
+			sum += t * amp;
+		}
+	}
+	
+	sum *= ((float)(1<<oct)/(float)((1<<(oct+1))-1));
+
+	return sum;
+}
+/*
+ * Flow noise end
+ */