[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20307] branches/ge_dev: iTaSC: working code for building persistent simulation scene.
Benoit Bolsee
benoit.bolsee at online.be
Wed May 20 22:39:18 CEST 2009
Revision: 20307
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20307
Author: ben2610
Date: 2009-05-20 22:39:18 +0200 (Wed, 20 May 2009)
Log Message:
-----------
iTaSC: working code for building persistent simulation scene. Nothing to be seen yet because the simulation is not executed, but I'm getting there. Still missing from the scene: joint limit and stiffness.
Modified Paths:
--------------
branches/ge_dev/intern/itasc/ConstraintSet.hpp
branches/ge_dev/intern/itasc/Scene.hpp
branches/ge_dev/intern/itasc/make/msvc_9_0/itasc.vcproj
branches/ge_dev/projectfiles_vc9/blender/blender.sln
branches/ge_dev/source/blender/ikplugin/intern/itasc_plugin.cpp
branches/ge_dev/source/blender/src/buttons_object.c
Modified: branches/ge_dev/intern/itasc/ConstraintSet.hpp
===================================================================
--- branches/ge_dev/intern/itasc/ConstraintSet.hpp 2009-05-20 18:37:28 UTC (rev 20306)
+++ branches/ge_dev/intern/itasc/ConstraintSet.hpp 2009-05-20 20:39:18 UTC (rev 20307)
@@ -84,6 +84,8 @@
ConstraintSet();
virtual ~ConstraintSet();
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+
virtual bool registerCallback(ConstraintCallback _function, void* _param)
{
m_constraintCallback = _function;
Modified: branches/ge_dev/intern/itasc/Scene.hpp
===================================================================
--- branches/ge_dev/intern/itasc/Scene.hpp 2009-05-20 18:37:28 UTC (rev 20306)
+++ branches/ge_dev/intern/itasc/Scene.hpp 2009-05-20 20:39:18 UTC (rev 20307)
@@ -32,6 +32,8 @@
bool initialize();
bool update(double timestamp, double timestep, unsigned int numsubstep=1, bool reiterate=false);
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+
private:
e_matrix m_A,m_B,m_Atemp,m_Wq,m_Jf,m_Jq,m_Ju,m_Cf,m_Cq,m_Jf_inv;
e_matrix6 m_Vf,m_Uf;
Modified: branches/ge_dev/intern/itasc/make/msvc_9_0/itasc.vcproj
===================================================================
--- branches/ge_dev/intern/itasc/make/msvc_9_0/itasc.vcproj 2009-05-20 18:37:28 UTC (rev 20306)
+++ branches/ge_dev/intern/itasc/make/msvc_9_0/itasc.vcproj 2009-05-20 20:39:18 UTC (rev 20307)
@@ -48,11 +48,13 @@
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- EnableEnhancedInstructionSet="2"
+ RuntimeLibrary="1"
+ EnableEnhancedInstructionSet="0"
FloatingPointModel="2"
UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
WarningLevel="3"
+ CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@@ -116,12 +118,14 @@
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\..\..\..\extern\Eigen2"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
- RuntimeLibrary="2"
+ RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="2"
UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
WarningLevel="3"
+ CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
Modified: branches/ge_dev/projectfiles_vc9/blender/blender.sln
===================================================================
--- branches/ge_dev/projectfiles_vc9/blender/blender.sln 2009-05-20 18:37:28 UTC (rev 20306)
+++ branches/ge_dev/projectfiles_vc9/blender/blender.sln 2009-05-20 20:39:18 UTC (rev 20307)
@@ -316,6 +316,7 @@
{98330220-47A6-42E0-9DE4-AD0FF5D204D6} = {98330220-47A6-42E0-9DE4-AD0FF5D204D6}
{C66F722C-46BE-40C9-ABAE-2EAC7A697EB8} = {C66F722C-46BE-40C9-ABAE-2EAC7A697EB8}
{FAF46346-65CC-4DB2-85C4-B99826F79D0C} = {FAF46346-65CC-4DB2-85C4-B99826F79D0C}
+ {59567A5B-F63A-4A5C-B33A-0A45C300F4DC} = {59567A5B-F63A-4A5C-B33A-0A45C300F4DC}
{B093415D-C0F6-4E76-8F5A-6BC1917BCE9E} = {B093415D-C0F6-4E76-8F5A-6BC1917BCE9E}
{E784098D-3ED8-433A-9353-9679415DDDC5} = {E784098D-3ED8-433A-9353-9679415DDDC5}
{76D90B92-ECC7-409C-9F98-A8814B90F3C0} = {76D90B92-ECC7-409C-9F98-A8814B90F3C0}
Modified: branches/ge_dev/source/blender/ikplugin/intern/itasc_plugin.cpp
===================================================================
--- branches/ge_dev/source/blender/ikplugin/intern/itasc_plugin.cpp 2009-05-20 18:37:28 UTC (rev 20306)
+++ branches/ge_dev/source/blender/ikplugin/intern/itasc_plugin.cpp 2009-05-20 20:39:18 UTC (rev 20307)
@@ -46,7 +46,13 @@
#include "itasc_plugin.h"
+// iTaSC headers
#include "Armature.hpp"
+#include "MovingFrame.hpp"
+#include "CopyPose.hpp"
+#include "WSDLSSolver.hpp"
+#include "Scene.hpp"
+#include "Cache.hpp"
// Structure pointed by bArmature.ikdata
// It contains everything needed to simulate the armatures
@@ -56,16 +62,99 @@
struct IK_Scene* first;
};
+typedef float Vector3[3];
+typedef float Vector4[4];
+
+// one structure for each target in the scene
+struct IK_Target
+{
+ iTaSC::MovingFrame* target;
+ iTaSC::ConstraintSet* constraint;
+ struct bConstraint* blenderConstraint;
+ std::string targetName;
+ std::string constraintName;
+ int ee; //end effector number
+ KDL::Frame eeRest; //end effector initial pose relative to armature
+
+ IK_Target() {
+ target = NULL;
+ constraint = NULL;
+ blenderConstraint = NULL;
+ ee = 0;
+ targetName.reserve(32);
+ constraintName.reserve(32);
+ }
+ ~IK_Target() {
+ if (constraint)
+ delete constraint;
+ if (target)
+ delete target;
+ }
+};
+
struct IK_Scene
{
IK_Scene* next;
- bPoseChannel* chan;
+ int numchan; // number of channel in pchan
+ bPoseChannel** pchan; // list of pose in tree, same index as bones and parents
iTaSC::Armature* armature;
iTaSC::Cache* cache;
iTaSC::Scene* scene;
- std::vector<iTaSC::ConstraintSet*> constraints;
+ iTaSC::MovingFrame* base;
+ iTaSC::WSDLSSolver* solver;
+
+ std::vector<std::string> bones; // bones[i] = segment name of the joint from which we get the bone i tail and head
+ std::vector<IK_Target*> targets;
+
+ IK_Scene() {
+ next = NULL;
+ pchan = NULL;
+ armature = NULL;
+ cache = NULL;
+ scene = NULL;
+ base = NULL;
+ solver = NULL;
+ }
+
+ ~IK_Scene() {
+ if (pchan)
+ MEM_freeN(pchan);
+ // delete scene first
+ if (scene)
+ delete scene;
+ for(std::vector<IK_Target*>::iterator it = targets.begin(); it != targets.end(); ++it)
+ delete (*it);
+ targets.clear();
+ if (solver)
+ delete solver;
+ if (armature)
+ delete armature;
+ if (base)
+ delete base;
+ // delete cache last
+ if (cache)
+ delete cache;
+ }
};
+enum IK_SegmentFlag {
+ IK_XDOF = 1,
+ IK_YDOF = 2,
+ IK_ZDOF = 4,
+ IK_TRANS_XDOF = 8,
+ IK_TRANS_YDOF = 16,
+ IK_TRANS_ZDOF = 32
+};
+
+enum IK_SegmentAxis {
+ IK_X = 0,
+ IK_Y = 1,
+ IK_Z = 2,
+ IK_TRANS_X = 3,
+ IK_TRANS_Y = 4,
+ IK_TRANS_Z = 5
+};
+
int initialize_scene(Object *ob, bPoseChannel *pchan_tip)
{
bPoseChannel *curchan, *pchan_root=NULL, *chanlist[256], **oldchan;
@@ -120,14 +209,15 @@
if ((pchan_root->flag & POSE_CHAIN) && pchan_root->iktree.first == NULL) return 0;
// now that we know how many segment we have, set the flag
- for (rootbone = segcount, segcount = 0, curchan = pchan_tip; segcount < rootbone; curchan=curchan->parent)
+ for (rootbone = segcount, segcount = 0, curchan = pchan_tip; segcount < rootbone; segcount++, curchan=curchan->parent) {
+ chanlist[segcount]=curchan;
curchan->flag |= POSE_CHAIN;
+ }
/* setup the chain data */
/* create a target */
target= (PoseTarget*)MEM_callocN(sizeof(PoseTarget), "posetarget");
target->con= con;
- pchan_tip->flag &= ~POSE_CHAIN;
// by contruction there can be only one tree per channel and each channel can be part of at most one tree.
tree = (PoseTree*)pchan_root->iktree.first;
@@ -197,26 +287,458 @@
return treecount;
}
+static IK_Data* get_ikdata(bArmature *arm)
+{
+ if (arm->ikdata)
+ return (IK_Data*)arm->ikdata;
+ arm->ikdata = MEM_callocN(sizeof(IK_Data), "iTaSC ikdata");
+ // init ikdata if needed
+ return (IK_Data*)arm->ikdata;
+}
+static double EulerAngleFromMatrix(const KDL::Rotation& R, int axis)
+{
+ double t = sqrt(R(0,0)*R(0,0) + R(0,1)*R(0,1));
+
+ if (t > 16.0*KDL::epsilon) {
+ if (axis == 0) return -atan2(R(1,2), R(2,2));
+ else if(axis == 1) return atan2(-R(0,2), t);
+ else return -atan2(R(0,1), R(0,0));
+ } else {
+ if (axis == 0) return -atan2(-R(2,1), R(1,1));
+ else if(axis == 1) return atan2(-R(0,2), t);
+ else return 0.0f;
+ }
+}
+
+static double ComputeTwist(const KDL::Rotation& R)
+{
+ // qy and qw are the y and w components of the quaternion from R
+ double qy = R(0,2) - R(2,0);
+ double qw = R(0,0) + R(1,1) + R(2,2) + 1;
+
+ double tau = 2*atan2(qy, qw);
+
+ return tau;
+}
+
+static void RemoveEulerAngleFromMatrix(KDL::Rotation& R, double angle, int axis)
+{
+ // compute twist parameter
+ KDL::Rotation T;
+ switch (axis) {
+ case 0:
+ T = KDL::Rotation::RotX(-angle);
+ break;
+ case 1:
+ T = KDL::Rotation::RotY(-angle);
+ break;
+ case 2:
+ T = KDL::Rotation::RotZ(-angle);
+ break;
+ default:
+ return;
+ }
+ // remove angle
+ R = R*T;
+}
+
+static void GetEulerXZY(const KDL::Rotation& R, double& X,double& Z,double& Y)
+{
+ if (fabs(R(0,1)) > 1.0 - KDL::epsilon ) {
+ X = -KDL::sign(R(0,1)) * KDL::atan2(R(1,2), R(1,0));
+ Z = -KDL::sign(R(0,1)) * KDL::PI / 2;
+ Y = 0.0 ;
+ } else {
+ X = KDL::atan2(R(2,1), R(1,1));
+ Z = KDL::atan2(-R(0,1), sqrt( KDL::sqr(R(0,0)) + KDL::sqr(R(0,2))));
+ Y = KDL::atan2(R(0,2), R(0,0));
+ }
+}
+
+static bool target_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Frame& current, iTaSC::Frame& next, void *param)
+{
+ IK_Target* target = (IK_Target*)param;
+ // compute next target position
+ // get target matrix from constraint.
+ return false;
+}
+
+static bool base_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Frame& current, iTaSC::Frame& next, void *param)
+{
+ IK_Scene* ikscene = (IK_Scene*)param;
+ // compute next armature base pose
+ // algorithm:
+ // ikscene->pchan[0] is the root channel of the tree
+ // if it has a parent, get the pose matrix from it and replace [3] by parent pchan->tail
+ // then multiply by the armature matrix to get ikscene->armature base position
+ return false;
+}
+
+static IK_Scene* convert_tree(Object *ob, bPoseChannel *pchan)
+{
+ PoseTree *tree = (PoseTree*)pchan->iktree.first;
+ PoseTarget *target;
+ bKinematicConstraint *condata;
+ iTaSC::Armature* arm;
+ iTaSC::Scene* scene;
+ IK_Scene* ikscene;
+ Bone *bone;
+ int a, flag, hasstretch=0;
+ float length;
+ bool ret = true;
+ float restpose[3][3];
+
+ if (tree->totchannel == 0)
+ return NULL;
+
+ ikscene = new IK_Scene;
+ arm = new iTaSC::Armature();
+ scene = new iTaSC::Scene();
+ ikscene->pchan = (bPoseChannel**)MEM_mallocN(sizeof(void*)*tree->totchannel, "iTaSC chan list");
+ ikscene->numchan = tree->totchannel;
+ ikscene->armature = arm;
+ ikscene->scene = scene;
+ ikscene->cache = new iTaSC::Cache();;
+ ikscene->solver = new iTaSC::WSDLSSolver();
+ ikscene->bones.resize(tree->totchannel);
+
+ std::string joint;
+ std::string root("root");
+ std::string parent;
+ // assume uniform scaling and take Y scale as general scale for the armature
+ float scale = VecLength(ob->obmat[1]);
+ double X, Y, Z;
+
+ for(a=0; a<tree->totchannel; a++) {
+ pchan= tree->pchan[a];
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list