[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12450] trunk/blender:

Brecht Van Lommel brechtvanlommel at pandora.be
Thu Nov 1 13:40:46 CET 2007


Revision: 12450
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12450
Author:   blendix
Date:     2007-11-01 13:40:46 +0100 (Thu, 01 Nov 2007)

Log Message:
-----------

IK
==

Solving is now done independent of scale, by scaling the chain to have a
size of about 1.0. This solves some issues with small or big chains, and
also makes the IK stretch setting independent of scale. The latter breaks
backwards compatibility somewhat, but is an improvement over what it did
before.

Modified Paths:
--------------
    trunk/blender/intern/iksolver/intern/IK_QJacobianSolver.cpp
    trunk/blender/intern/iksolver/intern/IK_QJacobianSolver.h
    trunk/blender/intern/iksolver/intern/IK_QSegment.cpp
    trunk/blender/intern/iksolver/intern/IK_QSegment.h
    trunk/blender/intern/iksolver/intern/IK_QTask.h
    trunk/blender/intern/iksolver/intern/IK_Solver.cpp
    trunk/blender/source/blender/blenkernel/intern/armature.c

Modified: trunk/blender/intern/iksolver/intern/IK_QJacobianSolver.cpp
===================================================================
--- trunk/blender/intern/iksolver/intern/IK_QJacobianSolver.cpp	2007-11-01 11:40:56 UTC (rev 12449)
+++ trunk/blender/intern/iksolver/intern/IK_QJacobianSolver.cpp	2007-11-01 12:40:46 UTC (rev 12450)
@@ -42,6 +42,36 @@
 	m_rootmatrix.setIdentity();
 }
 
+MT_Scalar IK_QJacobianSolver::ComputeScale()
+{
+	std::vector<IK_QSegment*>::iterator seg;
+	float length = 0.0f;
+
+	for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
+		length += (*seg)->MaxExtension();
+	
+	if(length == 0.0f)
+		return 1.0f;
+	else
+		return 1.0f/length;
+}
+
+void IK_QJacobianSolver::Scale(float scale, std::list<IK_QTask*>& tasks)
+{
+	std::list<IK_QTask*>::iterator task;
+	std::vector<IK_QSegment*>::iterator seg;
+
+	for (task = tasks.begin(); task != tasks.end(); task++)
+		(*task)->Scale(scale);
+
+	for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
+		(*seg)->Scale(scale);
+	
+	m_rootmatrix.getOrigin() *= scale;
+	m_goal *= scale;
+	m_polegoal *= scale;
+}
+
 void IK_QJacobianSolver::AddSegmentList(IK_QSegment *seg)
 {
 	m_segments.push_back(seg);
@@ -293,9 +323,12 @@
 	const int max_iterations
 )
 {
+	float scale = ComputeScale();
 	bool solved = false;
 	//double dt = analyze_time();
 
+	Scale(scale, tasks);
+
 	ConstrainPoleVector(root, tasks);
 
 	root->UpdateTransform(m_rootmatrix);
@@ -346,15 +379,14 @@
 		if (norm < 1e-3) {
 			solved = true;
 			break;
-			//analyze_add_run(iterations, analyze_time()-dt);
-
-			return true;
 		}
 	}
 
 	if(m_poleconstraint)
 		root->PrependBasis(m_rootmatrix.getBasis());
 
+	Scale(1.0f/scale, tasks);
+
 	//analyze_add_run(max_iterations, analyze_time()-dt);
 
 	return solved;

Modified: trunk/blender/intern/iksolver/intern/IK_QJacobianSolver.h
===================================================================
--- trunk/blender/intern/iksolver/intern/IK_QJacobianSolver.h	2007-11-01 11:40:56 UTC (rev 12449)
+++ trunk/blender/intern/iksolver/intern/IK_QJacobianSolver.h	2007-11-01 12:40:46 UTC (rev 12450)
@@ -75,6 +75,9 @@
 	bool UpdateAngles(MT_Scalar& norm);
 	void ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask*>& tasks);
 
+	MT_Scalar ComputeScale();
+	void Scale(float scale, std::list<IK_QTask*>& tasks);
+
 private:
 
 	IK_QJacobian m_jacobian;

Modified: trunk/blender/intern/iksolver/intern/IK_QSegment.cpp
===================================================================
--- trunk/blender/intern/iksolver/intern/IK_QSegment.cpp	2007-11-01 11:40:56 UTC (rev 12449)
+++ trunk/blender/intern/iksolver/intern/IK_QSegment.cpp	2007-11-01 12:40:46 UTC (rev 12450)
@@ -343,6 +343,16 @@
 	m_basis = m_rest_basis.inverse() * mat * m_rest_basis * m_basis;
 }
 
+void IK_QSegment::Scale(float scale)
+{
+	m_start *= scale;
+	m_translation *= scale;
+	m_orig_translation *= scale;
+	m_global_start *= scale;
+	m_global_transform.getOrigin() *= scale;
+	m_max_extension *= scale;
+}
+
 // IK_QSphericalSegment
 
 IK_QSphericalSegment::IK_QSphericalSegment()
@@ -1026,3 +1036,17 @@
 	m_limit[axis]= true;
 }
 
+void IK_QTranslateSegment::Scale(float scale)
+{
+	int i;
+
+	IK_QSegment::Scale(scale);
+
+	for (i = 0; i < 3; i++) {
+		m_min[0] *= scale;
+		m_max[1] *= scale;
+	}
+
+	m_new_translation *= scale;
+}
+

Modified: trunk/blender/intern/iksolver/intern/IK_QSegment.h
===================================================================
--- trunk/blender/intern/iksolver/intern/IK_QSegment.h	2007-11-01 11:40:56 UTC (rev 12449)
+++ trunk/blender/intern/iksolver/intern/IK_QSegment.h	2007-11-01 12:40:46 UTC (rev 12450)
@@ -169,6 +169,9 @@
 	void PrependBasis(const MT_Matrix3x3& mat);
 	void Reset();
 
+	// scale
+	virtual void Scale(float scale);
+
 protected:
 
 	// num_DoF: number of degrees of freedom
@@ -335,6 +338,8 @@
 	void SetWeight(int axis, MT_Scalar weight);
 	void SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax);
 
+	void Scale(float scale);
+
 private:
 	int m_axis[3];
 	bool m_axis_enabled[3], m_limit[3];

Modified: trunk/blender/intern/iksolver/intern/IK_QTask.h
===================================================================
--- trunk/blender/intern/iksolver/intern/IK_QTask.h	2007-11-01 11:40:56 UTC (rev 12449)
+++ trunk/blender/intern/iksolver/intern/IK_QTask.h	2007-11-01 12:40:46 UTC (rev 12450)
@@ -77,6 +77,8 @@
 
 	virtual bool PositionTask() const { return false; }
 
+	virtual void Scale(float scale) {}
+
 protected:
 	int m_id;
 	int m_size;
@@ -100,6 +102,7 @@
 	MT_Scalar Distance() const;
 
 	bool PositionTask() const { return true; }
+	void Scale(float scale) { m_goal *= scale; m_clamp_length *= scale; }
 
 private:
 	MT_Vector3 m_goal;
@@ -137,6 +140,8 @@
 
 	MT_Scalar Distance() const;
 
+	void Scale(float scale) { m_goal_center *= scale; m_distance *= scale; }
+
 private:
 	MT_Scalar ComputeTotalMass(const IK_QSegment *segment);
 	MT_Vector3 ComputeCenter(const IK_QSegment *segment);

Modified: trunk/blender/intern/iksolver/intern/IK_Solver.cpp
===================================================================
--- trunk/blender/intern/iksolver/intern/IK_Solver.cpp	2007-11-01 11:40:56 UTC (rev 12449)
+++ trunk/blender/intern/iksolver/intern/IK_Solver.cpp	2007-11-01 12:40:46 UTC (rev 12450)
@@ -41,7 +41,7 @@
 
 class IK_QSolver {
 public:
-	IK_QSolver() {};
+	IK_QSolver() : root(NULL) {};
 
 	IK_QJacobianSolver solver;
 	IK_QSegment *root;
@@ -197,13 +197,12 @@
 	if (stiffness < 0.0)
 		return;
 	
-	if (stiffness > 0.99)
-		stiffness = 0.99;
+	if (stiffness > 0.999)
+		stiffness = 0.999;
 
 	IK_QSegment *qseg = (IK_QSegment*)seg;
 	MT_Scalar weight = 1.0-stiffness;
 
-
 	if (axis >= IK_TRANS_X) {
 		if(!qseg->Translational())
 			if(qseg->Composite() && qseg->Composite()->Translational())

Modified: trunk/blender/source/blender/blenkernel/intern/armature.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/armature.c	2007-11-01 11:40:56 UTC (rev 12449)
+++ trunk/blender/source/blender/blenkernel/intern/armature.c	2007-11-01 12:40:46 UTC (rev 12450)
@@ -1598,7 +1598,7 @@
 
 		if(tree->stretch && (pchan->ikstretch > 0.0)) {
 			float ikstretch = pchan->ikstretch*pchan->ikstretch;
-			IK_SetStiffness(seg, IK_TRANS_Y, MIN2(1.0-ikstretch, 0.99));
+			IK_SetStiffness(seg, IK_TRANS_Y, MIN2(1.0-ikstretch, 0.999));
 			IK_SetLimit(seg, IK_TRANS_Y, 0.001, 1e10);
 		}
 	}





More information about the Bf-blender-cvs mailing list