Revision: 21152
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21152
Author:   ben2610
Date:     2009-06-25 13:57:19 +0200 (Thu, 25 Jun 2009)

Log Message:
-----------
iTaSC: implement 2DoF Swing joint, connect iTaSC cache reset to BKE point 
cache. Fix bug in KDL on Vector2 Norm. Add Helper functions GetValue to get 
vector coordinates from KDL.

Modified Paths:
--------------
    branches/ge_dev/intern/itasc/Armature.cpp
    branches/ge_dev/intern/itasc/Cache.cpp
    branches/ge_dev/intern/itasc/Cache.hpp
    branches/ge_dev/intern/itasc/kdl/frames.cpp
    branches/ge_dev/intern/itasc/kdl/frames.hpp
    branches/ge_dev/intern/itasc/kdl/frames.inl
    branches/ge_dev/intern/itasc/kdl/joint.cpp
    branches/ge_dev/intern/itasc/kdl/joint.hpp
    branches/ge_dev/intern/itasc/kdl/segment.cpp
    branches/ge_dev/intern/itasc/kdl/segment.hpp
    branches/ge_dev/intern/itasc/kdl/treejnttojacsolver.cpp
    branches/ge_dev/source/blender/blenkernel/intern/pointcache.c
    branches/ge_dev/source/blender/ikplugin/BIK_api.h
    branches/ge_dev/source/blender/ikplugin/intern/ikplugin_api.c
    branches/ge_dev/source/blender/ikplugin/intern/ikplugin_api.h
    branches/ge_dev/source/blender/ikplugin/intern/itasc_plugin.cpp
    branches/ge_dev/source/blender/ikplugin/intern/itasc_plugin.h

Modified: branches/ge_dev/intern/itasc/Armature.cpp
===================================================================
--- branches/ge_dev/intern/itasc/Armature.cpp   2009-06-25 10:52:09 UTC (rev 
21151)
+++ branches/ge_dev/intern/itasc/Armature.cpp   2009-06-25 11:57:19 UTC (rev 
21152)
@@ -364,11 +364,18 @@
        for (unsigned int q_nr=0; q_nr<m_nq; ) {
                Joint_struct& joint = m_joints[q_nr];
                switch (joint.type) {
+               case KDL::Joint::Swing:
+                       {
+                               double* qdot=&m_qdotKdl(q_nr);
+                               double* q=&m_qKdl(q_nr);
+                               
(KDL::Rot(KDL::Vector(q[0],0.0,q[1]))*KDL::Rot(KDL::Vector(qdot[0],0.0,qdot[1])*timestamp.realTimestep)).GetXZRot().GetValue(q);
+                               break;
+                       }
                case KDL::Joint::Sphere:
                        {
                                double* qdot=&m_qdotKdl(q_nr);
                                double* q=&m_qKdl(q_nr);
-                               
(KDL::Rot(KDL::Vector(qdot)*timestamp.realTimestep)*KDL::Rot(KDL::Vector(q))).GetRot().GetValue(q);
+                               
(KDL::Rot(KDL::Vector(q))*KDL::Rot(KDL::Vector(qdot)*timestamp.realTimestep)).GetRot().GetValue(q);
                                break;
                        }
                default:

Modified: branches/ge_dev/intern/itasc/Cache.cpp
===================================================================
--- branches/ge_dev/intern/itasc/Cache.cpp      2009-06-25 10:52:09 UTC (rev 
21151)
+++ branches/ge_dev/intern/itasc/Cache.cpp      2009-06-25 11:57:19 UTC (rev 
21152)
@@ -305,6 +305,83 @@
        return 0;
 }
 
+void Cache::clearCacheFrom(const void *device, CacheTS timestamp)
+{
+       CacheMap::iterator it = (device) ? m_cache.find(device) : 
m_cache.begin();
+       CacheEntry *entry;
+       CacheChannel *channel;
+       CacheBuffer *buffer, *nextBuffer, *prevBuffer;
+       CacheItem *item, *prevItem, *nextItem;
+       unsigned int positionW, block;
+
+       while (it != m_cache.end()) {
+               entry = it->second;
+               for (unsigned int ch=0; ch<entry->m_count; ch++) {
+                       channel = &entry->m_channelArray[ch];
+                       if (channel->m_busy) {
+                               item = channel->findItemOrLater(timestamp, 
&buffer);
+                               if (item ) {
+                                       // this item and all later items will 
be removed, clear any later buffer
+                                       while ((nextBuffer = buffer->m_next) != 
NULL) {
+                                               buffer->m_next = 
nextBuffer->m_next;
+                                               free(nextBuffer);
+                                       }
+                                       positionW = 
CACHE_ITEM_POSITIONW(buffer,item);
+                                       if (positionW == 0) {
+                                               // this item is the first one 
of the buffer, remove the buffer completely
+                                               // first find the buffer just 
before it
+                                               nextBuffer = 
channel->m_firstBuffer;
+                                               prevBuffer = NULL;
+                                               while (nextBuffer != buffer) {
+                                                       prevBuffer = nextBuffer;
+                                                       nextBuffer = 
nextBuffer->m_next;
+                                                       // we must quit this 
loop before reaching the end of the list
+                                                       assert(nextBuffer);
+                                               }
+                                               free(buffer);
+                                               buffer = prevBuffer;
+                                               if (buffer == NULL)
+                                                       // this was also the 
first buffer
+                                                       channel->m_firstBuffer 
= NULL;
+                                       } else {
+                                               // removing this item means 
finding the previous item to make it the last one
+                                               block = 
positionW>>channel->m_positionToBlockShiftW;
+                                               if (block == 0) {
+                                                       // start from first 
item, we know it is not our item because positionW > 0
+                                                       prevItem = 
&buffer->m_firstItem;
+                                               } else {
+                                                       // no need to check the 
current block, it will point to our item or a later one
+                                                       // but the previous 
block will be a good start for sure.
+                                                       block--;
+                                                       prevItem = 
CACHE_BLOCK_ITEM_ADDR(channel,buffer,block);
+                                               }
+                                               while ((nextItem = 
CACHE_NEXT_ITEM(prevItem)) < item)
+                                                       prevItem = nextItem;
+                                               // we must have found our item
+                                               assert(nextItem==item);
+                                               // now set the buffer
+                                               buffer->m_lastItemPositionW = 
CACHE_ITEM_POSITIONW(buffer,prevItem);
+                                               buffer->m_firstFreePositionW = 
positionW;
+                                               buffer->m_lastTimestamp = 
buffer->m_firstTimestamp + prevItem->m_timeOffset;
+                                               block = 
buffer->m_lastItemPositionW>>channel->m_positionToBlockShiftW;
+                                               buffer->lookup[block].m_offsetW 
= buffer->m_lastItemPositionW&channel->m_positionToOffsetMaskW;
+                                               
buffer->lookup[block].m_timeOffset = prevItem->m_timeOffset;
+                                       }
+                                       // set the channel
+                                       channel->m_lastBuffer = buffer;
+                                       if (buffer) {
+                                               channel->m_lastTimestamp = 
buffer->m_lastTimestamp;
+                                               channel->m_lastItemPositionW = 
buffer->m_lastItemPositionW;
+                                       }
+                               }
+                       }
+               }
+               if (device)
+                       break;
+               ++it;
+       }
+}
+
 void *Cache::addCacheItem(const void *device, int id, unsigned int timestamp, 
void *data, unsigned int length)
 {
        CacheMap::iterator it = m_cache.find(device);

Modified: branches/ge_dev/intern/itasc/Cache.hpp
===================================================================
--- branches/ge_dev/intern/itasc/Cache.hpp      2009-06-25 10:52:09 UTC (rev 
21151)
+++ branches/ge_dev/intern/itasc/Cache.hpp      2009-06-25 11:57:19 UTC (rev 
21152)
@@ -101,6 +101,9 @@
        int deleteChannel(const void *device, int channel);
        /* delete all channels of a device and remove the device from the map */
        int deleteDevice(const void *device);
+       /* removes all cache items, leaving the special item at timestamp=0. 
+          if device=NULL, apply to all devices. */
+       void clearCacheFrom(const void *device, CacheTS timestamp);
 
        /* add a new cache item
           channel: the cache channel (as returned by AddChannel

Modified: branches/ge_dev/intern/itasc/kdl/frames.cpp
===================================================================
--- branches/ge_dev/intern/itasc/kdl/frames.cpp 2009-06-25 10:52:09 UTC (rev 
21151)
+++ branches/ge_dev/intern/itasc/kdl/frames.cpp 2009-06-25 11:57:19 UTC (rev 
21152)
@@ -83,10 +83,14 @@
 
 double Vector2::Norm() const
 {
-    if (fabs(data[0]) > fabs(data[1]) ) {
-        return data[0]*sqrt(1+sqr(data[1]/data[0]));
+    double tmp0 = fabs(data[0]);
+    double tmp1 = fabs(data[1]);
+    if (tmp0 >= tmp1) {
+               if (tmp1 == 0)
+                       return 0;
+        return tmp0*sqrt(1+sqr(tmp1/tmp0));
     } else {
-        return data[1]*sqrt(1+sqr(data[0]/data[1]));
+        return tmp1*sqrt(1+sqr(tmp0/tmp1));
     }
 }
 // makes v a unitvector and returns the norm of v.
@@ -320,6 +324,18 @@
        return axis * alfa;
      }
 
+Vector2 Rotation::GetXZRot() const
+{
+       // [0,1,0] x Y
+       Vector2 axis(data[7], -data[1]);
+       double norm = axis.Normalize();
+       if (norm < epsilon) {
+               norm = (data[4] < 0.0) ? PI : 0.0;
+       } else {
+               norm = acos(data[4]);
+       }
+       return axis*norm;
+}
 
 
 /** Returns the rotation angle around the equiv. axis

Modified: branches/ge_dev/intern/itasc/kdl/frames.hpp
===================================================================
--- branches/ge_dev/intern/itasc/kdl/frames.hpp 2009-06-25 10:52:09 UTC (rev 
21151)
+++ branches/ge_dev/intern/itasc/kdl/frames.hpp 2009-06-25 11:57:19 UTC (rev 
21152)
@@ -370,6 +370,10 @@
     //! and its norm is angle
     Vector GetRot() const;
 
+    //! Returns a 2D vector representing the equivalent rotation in the XZ 
plane that brings the
+    //! Y axis onto the Matrix Y axis and its norm is angle
+    Vector2 GetXZRot() const;
+
        /** Returns the rotation angle around the equiv. axis
         * @param axis the rotation axis is returned in this variable
         * @param eps :  in the case of angle == 0 : rot axis is undefined and 
choosen
@@ -917,6 +921,9 @@
      //! Access to elements, range checked when NDEBUG is not set, from 0..1
      inline double& operator() (int index);
 
+        //! store vector components in array
+        inline void GetValue(double* xy);
+
      inline void ReverseSign();
      inline Vector2& operator-=(const Vector2& arg);
      inline Vector2& operator +=(const Vector2& arg);

Modified: branches/ge_dev/intern/itasc/kdl/frames.inl
===================================================================
--- branches/ge_dev/intern/itasc/kdl/frames.inl 2009-06-25 10:52:09 UTC (rev 
21151)
+++ branches/ge_dev/intern/itasc/kdl/frames.inl 2009-06-25 11:57:19 UTC (rev 
21152)
@@ -757,6 +757,10 @@
     return *this;
 }
 
+IMETHOD void Vector2::GetValue(double* xy)
+{
+        xy[0]=data[0];xy[1]=data[1];
+}
 
 IMETHOD Vector2 operator +(const Vector2 & lhs,const Vector2& rhs)
 {

Modified: branches/ge_dev/intern/itasc/kdl/joint.cpp
===================================================================
--- branches/ge_dev/intern/itasc/kdl/joint.cpp  2009-06-25 10:52:09 UTC (rev 
21151)
+++ branches/ge_dev/intern/itasc/kdl/joint.cpp  2009-06-25 11:57:19 UTC (rev 
21152)
@@ -27,21 +27,11 @@
                  const double& _inertia, const double& _damping, const double& 
_stiffness):
         
type(_type),scale(_scale),offset(_offset),inertia(_inertia),damping(_damping),stiffness(_stiffness)
     {
-               // this constructor should not be used for sphere joint, assume 
no offset in basis
+               // for sphere and swing, offset is not used, assume no offset
     }
 
-    Joint::Joint(const JointType& _type, const double& _scale, const Rotation& 
_basis,
-                 const double& _inertia, const double& _damping, const double& 
_stiffness):
-        
type(_type),scale(_scale),offset(0.0),inertia(_inertia),damping(_damping),stiffness(_stiffness)
-    {
-               // this constructor should not be used for 1DOF joint
-               if (_type == Sphere) {
-                       basis = _basis;
-               }
-    }
-
     Joint::Joint(const Joint& in):
-       type(in.type),scale(in.scale),offset(in.offset),basis(in.basis),
+       type(in.type),scale(in.scale),offset(in.offset),
         inertia(in.inertia),damping(in.damping),stiffness(in.stiffness)
     {
     }
@@ -51,7 +41,6 @@
         type=in.type;
         scale=in.scale;
         offset=in.offset;
-               basis=in.basis;
         inertia=in.inertia;
         damping=in.damping;
         stiffness=in.stiffness;
@@ -88,8 +77,13 @@
                case Sphere:
                        // the joint angles represent a rotation vector 
expressed in the base frame of the joint
                        // (= the frame you get when there is no offset nor 
rotation)
-                       return Frame(Rot(Vector((&q)[0], (&q)[1], 
(&q)[2]))*basis);
+                       return Frame(Rot(Vector((&q)[0], (&q)[1], (&q)[2])));
                        break;
+               case Swing:
+                       // the joint angles represent a 2D rotation vector in 
the XZ planee of the base frame of the joint
+                       // (= the frame you get when there is no offset nor 
rotation)
+                       return Frame(Rot(Vector((&q)[0], 0.0, (&q)[1])));
+                       break;
         default:
             return Frame::Identity();
             break;
@@ -117,6 +111,14 @@
         case TransZ:
             return Twist(Vector(0.0,0.0,scale*qdot),Vector(0.0,0.0,0.0));
             break;
+               case Swing:
+                       switch (dof) {
+                       case 0:
+                               return 
Twist(Vector(0.0,0.0,0.0),Vector(scale*qdot,0.0,0.0));
+                       case 1:
+                               return 
Twist(Vector(0.0,0.0,0.0),Vector(0.0,0.0,scale*qdot));
+                       }
+            return Twist::Zero();
                case Sphere:

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to