[Bf-blender-cvs] [5faf582] hair_system: Simulate hair in world space.

Lukas Tönne noreply at git.blender.org
Mon Jul 28 17:15:39 CEST 2014


Commit: 5faf582c931465512362d6df3f6e006b7bda2187
Author: Lukas Tönne
Date:   Mon Jul 28 17:13:23 2014 +0200
Branches: hair_system
https://developer.blender.org/rB5faf582c931465512362d6df3f6e006b7bda2187

Simulate hair in world space.

Object space is used for the DNA data, which is more suitable for tools
and object handling. For the simulation though, world space is much
better since calculating forces becomes a lot easier. Otherwise one
would have to take into account "virtual" forces generated by the
accelerated object frame of reference.

===================================================================

M	source/blender/hair/CMakeLists.txt
M	source/blender/hair/HAIR_capi.cpp
M	source/blender/hair/HAIR_capi.h
A	source/blender/hair/intern/HAIR_math.cpp
M	source/blender/hair/intern/HAIR_math.h
A	source/blender/hair/intern/HAIR_types.cpp
M	source/blender/hair/intern/HAIR_types.h
M	source/blender/modifiers/intern/MOD_hair.c

===================================================================

diff --git a/source/blender/hair/CMakeLists.txt b/source/blender/hair/CMakeLists.txt
index 5b76bad..e5cd991 100644
--- a/source/blender/hair/CMakeLists.txt
+++ b/source/blender/hair/CMakeLists.txt
@@ -43,12 +43,14 @@ set(SRC
 	intern/HAIR_curve.h
 	intern/HAIR_curve.cpp
 	intern/HAIR_math.h
+	intern/HAIR_math.cpp
 	intern/HAIR_memalloc.h
 	intern/HAIR_smoothing.h
 	intern/HAIR_smoothing.cpp
 	intern/HAIR_solver.h
 	intern/HAIR_solver.cpp
 	intern/HAIR_types.h
+	intern/HAIR_types.cpp
 )
 
 add_definitions(
diff --git a/source/blender/hair/HAIR_capi.cpp b/source/blender/hair/HAIR_capi.cpp
index 7fb0091..39e3017 100644
--- a/source/blender/hair/HAIR_capi.cpp
+++ b/source/blender/hair/HAIR_capi.cpp
@@ -28,6 +28,7 @@ extern "C" {
 #include "BLI_math.h"
 
 #include "DNA_hair_types.h"
+#include "DNA_object_types.h"
 
 #include "BKE_hair.h"
 }
@@ -54,12 +55,14 @@ void HAIR_solver_free(struct HAIR_Solver *csolver)
 	delete solver;
 }
 
-void HAIR_solver_init(struct HAIR_Solver *csolver, HairSystem *hsys)
+void HAIR_solver_init(struct HAIR_Solver *csolver, Object *ob, HairSystem *hsys)
 {
 	Solver *solver = (Solver *)csolver;
 	HairCurve *hair;
 	int i;
 	
+	Transform mat = Transform(ob->obmat);
+	
 	/* count points */
 	int totpoints = 0;
 	for (hair = hsys->curves, i = 0; i < hsys->totcurves; ++hair, ++i) {
@@ -80,9 +83,9 @@ void HAIR_solver_init(struct HAIR_Solver *csolver, HairSystem *hsys)
 			HairPoint *hair_pt = hair->points + k;
 			bool is_root = (k == 0);
 			
-			*point = Point(hair_pt->rest_co, !is_root);
-			point->cur.co = float3(hair_pt->co);
-			point->cur.vel = float3(hair_pt->vel);
+			*point = Point(transform_point(mat, hair_pt->rest_co), !is_root);
+			point->cur.co = transform_point(mat, hair_pt->co);
+			point->cur.vel = transform_direction(mat, hair_pt->vel);
 		}
 	}
 }
@@ -94,11 +97,13 @@ void HAIR_solver_step(struct HAIR_Solver *csolver, float timestep)
 	solver->step(timestep);
 }
 
-void HAIR_solver_apply(struct HAIR_Solver *csolver, HairSystem *hsys)
+void HAIR_solver_apply(struct HAIR_Solver *csolver, Object *ob, HairSystem *hsys)
 {
 	Solver *solver = (Solver *)csolver;
 	int i;
 	
+	Transform imat = transform_inverse(Transform(ob->obmat));
+	
 	Curve *solver_curves = solver->data()->curves;
 	int totcurves = solver->data()->totcurves;
 	
@@ -111,8 +116,8 @@ void HAIR_solver_apply(struct HAIR_Solver *csolver, HairSystem *hsys)
 			Point *point = curve->points + k;
 			HairPoint *hpoint = hcurve->points + k;
 			
-			copy_v3_v3(hpoint->co, point->cur.co.data());
-			copy_v3_v3(hpoint->vel, point->cur.vel.data());
+			copy_v3_v3(hpoint->co, transform_point(imat, point->cur.co).data());
+			copy_v3_v3(hpoint->vel, transform_direction(imat, point->cur.vel).data());
 		}
 	}
 }
diff --git a/source/blender/hair/HAIR_capi.h b/source/blender/hair/HAIR_capi.h
index 69536a9..87d121a 100644
--- a/source/blender/hair/HAIR_capi.h
+++ b/source/blender/hair/HAIR_capi.h
@@ -36,9 +36,9 @@ struct HAIR_SmoothingIteratorFloat3;
 
 struct HAIR_Solver *HAIR_solver_new(const struct HairParams *params);
 void HAIR_solver_free(struct HAIR_Solver *solver);
-void HAIR_solver_init(struct HAIR_Solver *solver, struct HairSystem *hsys);
+void HAIR_solver_init(struct HAIR_Solver *solver, struct Object *ob, struct HairSystem *hsys);
 void HAIR_solver_step(struct HAIR_Solver *solver, float timestep);
-void HAIR_solver_apply(struct HAIR_Solver *solver, struct HairSystem *hsys);
+void HAIR_solver_apply(struct HAIR_Solver *solver, struct Object *ob, struct HairSystem *hsys);
 
 struct HAIR_SmoothingIteratorFloat3 *HAIR_smoothing_iter_new(struct HairCurve *curve, float rest_length, float amount, float cval[3]);
 void HAIR_smoothing_iter_free(struct HAIR_SmoothingIteratorFloat3 *iter);
diff --git a/source/blender/hair/intern/HAIR_math.cpp b/source/blender/hair/intern/HAIR_math.cpp
new file mode 100644
index 0000000..a89036b
--- /dev/null
+++ b/source/blender/hair/intern/HAIR_math.cpp
@@ -0,0 +1,136 @@
+/*
+ * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ *                 Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <cstring>
+
+extern "C" {
+#include "BLI_utildefines.h"
+}
+
+#include "HAIR_math.h"
+
+HAIR_NAMESPACE_BEGIN
+
+static bool transform_matrix4_gj_inverse(float R[][4], float M[][4])
+{
+	/* forward elimination */
+	for(int i = 0; i < 4; i++) {
+		int pivot = i;
+		float pivotsize = M[i][i];
+
+		if(pivotsize < 0)
+			pivotsize = -pivotsize;
+
+		for(int j = i + 1; j < 4; j++) {
+			float tmp = M[j][i];
+
+			if(tmp < 0)
+				tmp = -tmp;
+
+			if(tmp > pivotsize) {
+				pivot = j;
+				pivotsize = tmp;
+			}
+		}
+
+		if(UNLIKELY(pivotsize == 0.0f))
+			return false;
+
+		if(pivot != i) {
+			for(int j = 0; j < 4; j++) {
+				float tmp;
+
+				tmp = M[i][j];
+				M[i][j] = M[pivot][j];
+				M[pivot][j] = tmp;
+
+				tmp = R[i][j];
+				R[i][j] = R[pivot][j];
+				R[pivot][j] = tmp;
+			}
+		}
+
+		for(int j = i + 1; j < 4; j++) {
+			float f = M[j][i] / M[i][i];
+
+			for(int k = 0; k < 4; k++) {
+				M[j][k] -= f*M[i][k];
+				R[j][k] -= f*R[i][k];
+			}
+		}
+	}
+
+	/* backward substitution */
+	for(int i = 3; i >= 0; --i) {
+		float f;
+
+		if(UNLIKELY((f = M[i][i]) == 0.0f))
+			return false;
+
+		for(int j = 0; j < 4; j++) {
+			M[i][j] /= f;
+			R[i][j] /= f;
+		}
+
+		for(int j = 0; j < i; j++) {
+			f = M[j][i];
+
+			for(int k = 0; k < 4; k++) {
+				M[j][k] -= f*M[i][k];
+				R[j][k] -= f*R[i][k];
+			}
+		}
+	}
+
+	return true;
+}
+
+Transform transform_inverse(const Transform& tfm)
+{
+	Transform tfmR = Transform::Identity;
+	float M[4][4], R[4][4];
+
+	memcpy(R, &tfmR, sizeof(R));
+	memcpy(M, &tfm, sizeof(M));
+
+	if(UNLIKELY(!transform_matrix4_gj_inverse(R, M))) {
+		/* matrix is degenerate (e.g. 0 scale on some axis), ideally we should
+		 * never be in this situation, but try to invert it anyway with tweak */
+		M[0][0] += 1e-8f;
+		M[1][1] += 1e-8f;
+		M[2][2] += 1e-8f;
+
+		if(UNLIKELY(!transform_matrix4_gj_inverse(R, M))) {
+			return Transform::Identity;
+		}
+	}
+
+	memcpy(&tfmR, R, sizeof(R));
+
+	return tfmR;
+}
+
+HAIR_NAMESPACE_END
diff --git a/source/blender/hair/intern/HAIR_math.h b/source/blender/hair/intern/HAIR_math.h
index 6ff4d94..d9167c6 100644
--- a/source/blender/hair/intern/HAIR_math.h
+++ b/source/blender/hair/intern/HAIR_math.h
@@ -49,7 +49,33 @@ __forceinline float max_ff(float a, float b)
 	return a > b ? a : b;
 }
 
-/* standard arithmetic */
+/* vector arithmetic */
+
+__forceinline float2 operator + (const float2 &a, const float2 &b)
+{
+	return float2(a.x + b.x, a.y + b.y);
+}
+
+__forceinline float2 operator - (const float2 &a, const float2 &b)
+{
+	return float2(a.x - b.x, a.y - b.y);
+}
+
+__forceinline float2 operator * (float fac, const float2 &a)
+{
+	return float2(fac * a.x, fac * a.y);
+}
+
+__forceinline float2 operator * (const float2 &a, float fac)
+{
+	return float2(a.x * fac, a.y * fac);
+}
+
+__forceinline float2 operator / (const float2 &a, float d)
+{
+	return float2(a.x / d, a.y / d);
+}
+
 
 __forceinline float3 operator + (const float3 &a, const float3 &b)
 {
@@ -76,6 +102,32 @@ __forceinline float3 operator / (const float3 &a, float d)
 	return float3(a.x / d, a.y / d, a.z / d);
 }
 
+
+__forceinline float4 operator + (const float4 &a, const float4 &b)
+{
+	return float4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
+}
+
+__forceinline float4 operator - (const float4 &a, const float4 &b)
+{
+	return float4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
+}
+
+__forceinline float4 operator * (float fac, const float4 &a)
+{
+	return float4(fac * a.x, fac * a.y, fac * a.z, fac * a.w);
+}
+
+__forceinline float4 operator * (const float4 &a, float fac)
+{
+	return float4(a.x * fac, a.y * fac, a.z * fac, a.w * fac);
+}
+
+__forceinline float4 operator / (const float4 &a, float d)
+{
+	return float4(a.x / d, a.y / d, a.z / d, a.w / d);
+}
+
 /* vector functions */
 
 __forceinline float dot_v3_v3(const float3 &a, const float3 &b)
@@ -83,6 +135,11 @@ __forceinline float dot_v3_v3(const float3 &a, const float3 &b)
 	return a.x * b.x + a.y * b.y + a.z * b.z;
 }
 
+__forceinline float dot_v4_v4(const float4 &a, const float4 &b)
+{
+	return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
+}
+
 __forceinline float len_v3(const float3 &v)
 {
 	return sqrtf(dot_v3_v3(v, v));
@@ -95,6 +152,102 @@ __forceinline float normalize_v3_v3(float3 &r, const float3 &v)
 	return len;
 }
 
+/* matrix arithmetic */
+
+__forceinline Transform operator + (const Transform &a, const Transform &b)
+{
+	return Transform(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
+}
+
+__forceinline Transform operator - (const Transform &a, const Transform &b)
+{
+	return Transform(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
+}
+
+Transform transform_transpose(const Transform &tfm); /* forward declaration */
+
+__forceinline Transform operator * (const Transform &a, const Transform &b)
+{
+	Transform c = transform_transpose(b);
+	Transform t;
+
+	t.x = float4(dot_v4_v4(a.x, c.x), dot_v4_v4(a.x, c.y), dot_v4_v4(a.x, c.z), dot_v4_v4(a.x, c.w));
+	t.y = float4(dot_v4_v4(a.y, c.x), dot_v4_v4(a.y, c.y), dot_v4_v4(a.y, c.z), dot_v4_v4(a.y, c.w));
+	t.z = float4(dot_v4_v4(a.z, c.x), dot_v4_v4(a.z, c.y), dot_v4_v4(a.z, c.z), dot_v4_v4(a.z, c.w));
+	t.w = float4(dot_v4_v4(a.w, c.x), dot_v4_v4(a.w, c.y), dot_v4_v4(a.w, c.z), dot_v4_v4(a.w, c.w));
+
+	return t;
+}
+
+__forceinline

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list