[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