[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12383] branches/cloth/blender: svn merge -r 12347:12382 https://svn.blender.org/svnroot/bf-blender/trunk/ blender

Daniel Genrich daniel.genrich at gmx.net
Wed Oct 24 19:20:54 CEST 2007


Revision: 12383
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12383
Author:   genscher
Date:     2007-10-24 19:20:53 +0200 (Wed, 24 Oct 2007)

Log Message:
-----------
svn merge -r 12347:12382 https://svn.blender.org/svnroot/bf-blender/trunk/blender

Modified Paths:
--------------
    branches/cloth/blender/intern/bmfont/intern/BMF_BitmapFont.cpp
    branches/cloth/blender/intern/iksolver/extern/IK_solver.h
    branches/cloth/blender/intern/iksolver/intern/IK_QJacobian.cpp
    branches/cloth/blender/intern/iksolver/intern/IK_QJacobian.h
    branches/cloth/blender/intern/iksolver/intern/IK_QJacobianSolver.cpp
    branches/cloth/blender/intern/iksolver/intern/IK_QJacobianSolver.h
    branches/cloth/blender/intern/iksolver/intern/IK_QSegment.cpp
    branches/cloth/blender/intern/iksolver/intern/IK_QSegment.h
    branches/cloth/blender/intern/iksolver/intern/IK_QTask.h
    branches/cloth/blender/intern/iksolver/intern/IK_Solver.cpp
    branches/cloth/blender/release/scripts/mesh_unfolder.py
    branches/cloth/blender/source/blender/blenkernel/BKE_constraint.h
    branches/cloth/blender/source/blender/blenkernel/intern/armature.c
    branches/cloth/blender/source/blender/blenkernel/intern/constraint.c
    branches/cloth/blender/source/blender/blenkernel/intern/image.c
    branches/cloth/blender/source/blender/blenkernel/intern/mesh.c
    branches/cloth/blender/source/blender/blenloader/intern/readfile.c
    branches/cloth/blender/source/blender/blenloader/intern/writefile.c
    branches/cloth/blender/source/blender/imbuf/intern/rectop.c
    branches/cloth/blender/source/blender/include/BIF_editseq.h
    branches/cloth/blender/source/blender/include/BIF_usiblender.h
    branches/cloth/blender/source/blender/include/butspace.h
    branches/cloth/blender/source/blender/makesdna/DNA_constraint_types.h
    branches/cloth/blender/source/blender/makesdna/DNA_scene_types.h
    branches/cloth/blender/source/blender/makesdna/DNA_world_types.h
    branches/cloth/blender/source/blender/python/BPY_interface.c
    branches/cloth/blender/source/blender/python/api2_2x/Blender.c
    branches/cloth/blender/source/blender/render/intern/source/rayshade.c
    branches/cloth/blender/source/blender/src/buttons_editing.c
    branches/cloth/blender/source/blender/src/buttons_object.c
    branches/cloth/blender/source/blender/src/buttons_scene.c
    branches/cloth/blender/source/blender/src/buttons_shading.c
    branches/cloth/blender/source/blender/src/drawobject.c
    branches/cloth/blender/source/blender/src/drawseq.c
    branches/cloth/blender/source/blender/src/editconstraint.c
    branches/cloth/blender/source/blender/src/editmesh_mods.c
    branches/cloth/blender/source/blender/src/editobject.c
    branches/cloth/blender/source/blender/src/editseq.c
    branches/cloth/blender/source/blender/src/header_info.c
    branches/cloth/blender/source/blender/src/header_seq.c
    branches/cloth/blender/source/blender/src/header_view3d.c
    branches/cloth/blender/source/blender/src/space.c
    branches/cloth/blender/source/blender/src/toets.c
    branches/cloth/blender/source/blender/src/usiblender.c
    branches/cloth/blender/source/creator/creator.c

Modified: branches/cloth/blender/intern/bmfont/intern/BMF_BitmapFont.cpp
===================================================================
--- branches/cloth/blender/intern/bmfont/intern/BMF_BitmapFont.cpp	2007-10-24 17:13:13 UTC (rev 12382)
+++ branches/cloth/blender/intern/bmfont/intern/BMF_BitmapFont.cpp	2007-10-24 17:20:53 UTC (rev 12383)
@@ -241,8 +241,6 @@
 }
 
 #define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
-
-
 void BMF_BitmapFont::DrawStringBuf(char *str, int posx, int posy, float *col, unsigned char *buf, float *fbuf, int w, int h)
 {
 	int x, y;
@@ -255,11 +253,11 @@
 	posy -= m_fontData->ymin;
 	
 	if (buf) {
-		unsigned char colch[3];
+		unsigned char colch[4];
 		unsigned char *max, *pixel;
 		unsigned char c;
 		
-		for (x=0; x<3; x++) {
+		for (x=0; x<4; x++) {
 			colch[x] = FTOCHAR(col[x]);
 		}
 		
@@ -279,6 +277,8 @@
 								pixel[0] = colch[0];
 								pixel[1] = colch[1];
 								pixel[2] = colch[2];
+								pixel[4] = 1; /*colch[3];*/
+								
 							}
 						}
 					}
@@ -310,6 +310,7 @@
 								pixel[0] = col[0];
 								pixel[1] = col[1];
 								pixel[2] = col[2];
+								pixel[3] = 1; /*col[3];*/
 							}
 						}
 					}

Modified: branches/cloth/blender/intern/iksolver/extern/IK_solver.h
===================================================================
--- branches/cloth/blender/intern/iksolver/extern/IK_solver.h	2007-10-24 17:13:13 UTC (rev 12382)
+++ branches/cloth/blender/intern/iksolver/extern/IK_solver.h	2007-10-24 17:20:53 UTC (rev 12383)
@@ -158,6 +158,8 @@
 
 void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float weight);
 void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[][3], float weight);
+void IK_SolverSetPoleVectorConstraint(IK_Solver *solver, IK_Segment *tip, float goal[3], float polegoal[3], float poleangle, int getangle);
+float IK_SolverGetPoleAngle(IK_Solver *solver);
 
 int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations);
 

Modified: branches/cloth/blender/intern/iksolver/intern/IK_QJacobian.cpp
===================================================================
--- branches/cloth/blender/intern/iksolver/intern/IK_QJacobian.cpp	2007-10-24 17:13:13 UTC (rev 12382)
+++ branches/cloth/blender/intern/iksolver/intern/IK_QJacobian.cpp	2007-10-24 17:20:53 UTC (rev 12383)
@@ -42,11 +42,10 @@
 {
 }
 
-void IK_QJacobian::ArmMatrices(int dof, int task_size, int tasks)
+void IK_QJacobian::ArmMatrices(int dof, int task_size)
 {
 	m_dof = dof;
 	m_task_size = task_size;
-	m_tasks = tasks;
 
 	m_jacobian.newsize(task_size, dof);
 	m_jacobian = 0;

Modified: branches/cloth/blender/intern/iksolver/intern/IK_QJacobian.h
===================================================================
--- branches/cloth/blender/intern/iksolver/intern/IK_QJacobian.h	2007-10-24 17:13:13 UTC (rev 12382)
+++ branches/cloth/blender/intern/iksolver/intern/IK_QJacobian.h	2007-10-24 17:20:53 UTC (rev 12383)
@@ -49,7 +49,7 @@
 	~IK_QJacobian();
 
 	// Call once to initialize
-	void ArmMatrices(int dof, int task_size, int tasks);
+	void ArmMatrices(int dof, int task_size);
 	void SetDoFWeight(int dof, MT_Scalar weight);
 
 	// Iteratively called
@@ -75,7 +75,7 @@
 	void InvertSDLS();
 	void InvertDLS();
 
-	int m_dof, m_task_size, m_tasks;
+	int m_dof, m_task_size;
 	bool m_transpose;
 
 	// the jacobian matrix and it's null space projector

Modified: branches/cloth/blender/intern/iksolver/intern/IK_QJacobianSolver.cpp
===================================================================
--- branches/cloth/blender/intern/iksolver/intern/IK_QJacobianSolver.cpp	2007-10-24 17:13:13 UTC (rev 12382)
+++ branches/cloth/blender/intern/iksolver/intern/IK_QJacobianSolver.cpp	2007-10-24 17:20:53 UTC (rev 12383)
@@ -32,7 +32,16 @@
 
 #include <stdio.h>
 #include "IK_QJacobianSolver.h"
+#include "MT_Quaternion.h"
 
+//#include "analyze.h"
+IK_QJacobianSolver::IK_QJacobianSolver()
+{
+	m_poleconstraint = false;
+	m_getpoleangle = false;
+	m_rootmatrix.setIdentity();
+}
+
 void IK_QJacobianSolver::AddSegmentList(IK_QSegment *seg)
 {
 	m_segments.push_back(seg);
@@ -47,7 +56,7 @@
 	m_segments.clear();
 	AddSegmentList(root);
 
-	// assing each segment a unique id for the jacobian
+	// assign each segment a unique id for the jacobian
 	std::vector<IK_QSegment*>::iterator seg;
 	int num_dof = 0;
 
@@ -105,9 +114,9 @@
 	}
 
 	// set matrix sizes
-	m_jacobian.ArmMatrices(num_dof, primary_size, primary);
+	m_jacobian.ArmMatrices(num_dof, primary_size);
 	if (secondary > 0)
-		m_jacobian_sub.ArmMatrices(num_dof, secondary_size, secondary);
+		m_jacobian_sub.ArmMatrices(num_dof, secondary_size);
 
 	// set dof weights
 	int i;
@@ -119,6 +128,109 @@
 	return true;
 }
 
+void IK_QJacobianSolver::SetPoleVectorConstraint(IK_QSegment *tip, MT_Vector3& goal, MT_Vector3& polegoal, float poleangle, bool getangle)
+{
+	m_poleconstraint = true;
+	m_poletip = tip;
+	m_goal = goal;
+	m_polegoal = polegoal;
+	m_poleangle = (getangle)? 0.0f: poleangle;
+	m_getpoleangle = getangle;
+}
+
+static MT_Scalar safe_acos(MT_Scalar f)
+{
+	// acos that does not return NaN with rounding errors
+	if (f <= -1.0f) return MT_PI;
+	else if (f >= 1.0f) return 0.0;
+	else return acos(f);
+}
+
+static MT_Vector3 normalize(const MT_Vector3& v)
+{
+	// a sane normalize function that doesn't give (1, 0, 0) in case
+	// of a zero length vector, like MT_Vector3.normalize
+	MT_Scalar len = v.length();
+	return MT_fuzzyZero(len)?  MT_Vector3(0, 0, 0): v/len;
+}
+
+static float angle(const MT_Vector3& v1, const MT_Vector3& v2)
+{
+	return safe_acos(v1.dot(v2));
+}
+
+void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask*>& tasks)
+{
+	// this function will be called before and after solving. calling it before
+	// solving gives predictable solutions by rotating towards the solution,
+	// and calling it afterwards ensures the solution is exact.
+
+	if(!m_poleconstraint)
+		return;
+	
+	// disable pole vector constraint in case of multiple position tasks
+	std::list<IK_QTask*>::iterator task;
+	int positiontasks = 0;
+
+	for (task = tasks.begin(); task != tasks.end(); task++)
+		if((*task)->PositionTask())
+			positiontasks++;
+	
+	if (positiontasks >= 2) {
+		m_poleconstraint = false;
+		return;
+	}
+
+	// get positions and rotations
+	root->UpdateTransform(m_rootmatrix);
+
+	const MT_Vector3 rootpos = root->GlobalStart();
+	const MT_Vector3 endpos = m_poletip->GlobalEnd();
+	const MT_Matrix3x3& rootbasis = root->GlobalTransform().getBasis();
+
+	// construct "lookat" matrices (like gluLookAt), based on a direction and
+	// an up vector, with the direction going from the root to the end effector
+	// and the up vector going from the root to the pole constraint position.
+	MT_Vector3 dir = normalize(endpos - rootpos);
+	MT_Vector3 rootx= rootbasis.getColumn(0);
+	MT_Vector3 rootz= rootbasis.getColumn(2);
+	MT_Vector3 up = rootx*cos(m_poleangle) + rootz*sin(m_poleangle);
+
+	// in post, don't rotate towards the goal but only correct the pole up
+	MT_Vector3 poledir = (m_getpoleangle)? dir: normalize(m_goal - rootpos);
+	MT_Vector3 poleup = normalize(m_polegoal - rootpos);
+
+	MT_Matrix3x3 mat, polemat;
+
+	mat[0] = normalize(MT_cross(dir, up));
+	mat[1] = MT_cross(mat[0], dir);
+	mat[2] = -dir;
+
+	polemat[0] = normalize(MT_cross(poledir, poleup));
+	polemat[1] = MT_cross(polemat[0], poledir);
+	polemat[2] = -poledir;
+
+	if(m_getpoleangle) {
+		// we compute the pole angle that to rotate towards the target
+		m_poleangle = angle(mat[1], polemat[1]);
+
+		if(rootz.dot(mat[1]*cos(m_poleangle) + mat[0]*sin(m_poleangle)) > 0.0f)
+			m_poleangle = -m_poleangle;
+
+		// solve again, with the pole angle we just computed
+		m_getpoleangle = false;
+		ConstrainPoleVector(root, tasks);
+	}
+	else {
+		// now we set as root matrix the difference between the current and
+		// desired rotation based on the pole vector constraint. we use
+		// transpose instead of inverse because we have orthogonal matrices
+		// anyway, and in case of a singular matrix we don't get NaN's.
+		MT_Transform trans(MT_Point3(0, 0, 0), polemat.transposed()*mat);
+		m_rootmatrix = trans*m_rootmatrix;
+	}
+}
+
 bool IK_QJacobianSolver::UpdateAngles(MT_Scalar& norm)
 {
 	// assing each segment a unique id for the jacobian
@@ -181,15 +293,17 @@
 	const int max_iterations
 )
 {
+	bool solved = false;
 	//double dt = analyze_time();
 
-	if (!Setup(root, tasks))
-		return false;
+	ConstrainPoleVector(root, tasks);
 
+	root->UpdateTransform(m_rootmatrix);
+
 	// iterate
 	for (int iterations = 0; iterations < max_iterations; iterations++) {
 		// update transform
-		root->UpdateTransform(MT_Transform::Identity());
+		root->UpdateTransform(m_rootmatrix);
 
 		std::list<IK_QTask*>::iterator task;
 
@@ -211,7 +325,7 @@
 					m_jacobian.SubTask(m_jacobian_sub);
 			}
 			catch (...) {
-				printf("IK Exception\n");
+				fprintf(stderr, "IK Exception\n");
 				return false;
 			}
 
@@ -230,12 +344,19 @@
 
 		// check for convergence
 		if (norm < 1e-3) {
+			solved = true;
+			break;
 			//analyze_add_run(iterations, analyze_time()-dt);
+
 			return true;
 		}
 	}
 
+	if(m_poleconstraint)
+		root->PrependBasis(m_rootmatrix.getBasis());
+
 	//analyze_add_run(max_iterations, analyze_time()-dt);
-	return false;
+
+	return solved;
 }
 

Modified: branches/cloth/blender/intern/iksolver/intern/IK_QJacobianSolver.h
===================================================================
--- branches/cloth/blender/intern/iksolver/intern/IK_QJacobianSolver.h	2007-10-24 17:13:13 UTC (rev 12382)
+++ branches/cloth/blender/intern/iksolver/intern/IK_QJacobianSolver.h	2007-10-24 17:20:53 UTC (rev 12383)
@@ -43,6 +43,7 @@
 #include <list>
 
 #include "MT_Vector3.h"
+#include "MT_Transform.h"
 #include "IK_QJacobian.h"
 #include "IK_QSegment.h"
 #include "IK_QTask.h"
@@ -50,11 +51,18 @@
 class IK_QJacobianSolver
 {
 public:
-	IK_QJacobianSolver() {};
+	IK_QJacobianSolver();
 	~IK_QJacobianSolver() {};
 
+	// setup pole vector constraint
+	void SetPoleVectorConstraint(IK_QSegment *tip, MT_Vector3& goal,
+		MT_Vector3& polegoal, float poleangle, bool getangle);
+	float GetPoleAngle() { return m_poleangle; };
+
+	// call setup once before solving, if it fails don't solve
+	bool Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks);
+
 	// returns true if converged, false if max number of iterations was used
-
 	bool Solve(
 		IK_QSegment *root,
 		std::list<IK_QTask*> tasks,
@@ -64,8 +72,8 @@
 
 private:
 	void AddSegmentList(IK_QSegment *seg);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list