POV-Ray : Newsgroups : povray.general : [3.8] Forward And Backward Reaching Inverse Kinematics Server Time: 14 Dec 2018 14:48:57 GMT
  [3.8] Forward And Backward Reaching Inverse Kinematics (Message 1 to 8 of 8)  
From: ingo
Subject: [3.8] Forward And Backward Reaching Inverse Kinematics
Date: 1 Dec 2018 11:14:24
Message: <XnsA9AB7C841FAFAseed7@news.povray.org>
Did a quick search but nothing showed up for POV-Ray & FABRIK. So here's 
my first attempt at the most basic version. Next steps will be more 
complex skeletons with multiple ends and then joint constraints. I hope 
that the latter can nicely done with the trace function.

Dictionaries are nice.

//==
// Pov-Ray   : 3.8
// Scene File: FABRIK.inc
// Author    : Ingo Janssen
// Date      : 01-12-2018
// Version   : 1a
//--
// Forward And Backward Reaching Inverse Kinematics (FABRIK) by Andreas 
Aristidou.
// http://www.andreasaristidou.com/FABRIK.html
// http://www.andreasaristidou.com/publications/papers/FABRIK.pdf
// 
http://www.andreasaristidou.com/publications/papers/Extending_FABRIK_wit
h_Model_C%CE%BFnstraints.pdf
// Excellent code inspiration & guide, by unknown author:
// https://developer.roblox.com/articles/Inverse-Kinematics-for-
Animation#FABRIK
//

#version 3.8;

#macro FABRIK(VecArr, VecTarget)
  // init
  #local self = dictionary {
    ["Joints"]      : VecArr,
    ["_O"]          : VecArr[0],
    // should be replaced by SetTarget
    ["Target"]      : VecTarget,
    // use .SetTarget(vec) to set a new target and iterate
    // still to be done somehowe.
    ["SetTarget"]   : false, 
    ["Tolerance"]   : 0.1,
    ["MaxIter"]     : 100,
    ["_M"]          : false,
    ["_N"]          : false,
    ["_Reachable"]  : false,
    ["_Lengths"]    : false,
    ["_TotalLength"]: false,
  };
  #local self._N = dimension_size(self.Joints, 1);
  #local self._M = self._N-1; //max index of array

  #macro LengthsArr()
    //#debug "LengthsArr :\n"
    #local Lengths = array[self._N-1];
    #local i = 0;
    #while (i < (self._N-1))
      #local Lengths[i] = vlength(self.Joints[i]-self.Joints[i+1]);
      //#debug concat("i : ",str(i,0,0)," len : ",str(Lengths
[i],0,3),"\n")
      #local i = i + 1; 
    #end
    Lengths
  #end
  #local self._Lengths = LengthsArr();   

  #macro LengthsSum()    
    //#debug "LengthsSum :\n"
    #local Length = 0;
    #local i = 0;
    #while (i < dimension_size(self._Lengths,1))
       #local Length = Length + self._Lengths[i];
       //#debug concat("i : ",str(i,0,0)," len : ",str(self._Lengths
[i],0,3)," sum : ",str(Length,0,3),"\n")
       #local i = i + 1;
    #end
    Length        
  #end 
  #local self._TotalLength = LengthsSum();

  #macro Reach ()
    #debug "Reach : "
    #if (vlength(self._O-self.Target) > self._TotalLength)
      #local Reachable = false;
      #debug "False\n"
    #else
      #local Reachable = true;
      #debug "True\n"
    #end
    Reachable 
  #end
  #local self._Reachable = Reach();

  #macro Backwards(Joints)
    #debug "  Backwards :\n"
    #local Joints[self._M] = self.Target;
    #for (i, self._M-1, 0, -1)
      #local l = self._Lengths[i]/vlength(Joints[i+1]-Joints[i]);
      #local Pos =  (1-l) * Joints[i+1] + l * Joints[i];
      #local Joints[i] = Pos;
      #debug concat("    i : ",str(i,0,0)," pos : ", vstr
(3,Pos,",",0,3),"\n")
    #end
    Joints
  #end
 
  #macro Forward(Joints)
    #debug "  Forward :\n"
    // set first point back to its original position
    #local Joints[0] = self._O; 
    #for (i, 0, self._M-1, 1)
      #local l = self._Lengths[i]/vlength(Joints[i+1]-Joints[i]);
      #local Pos =  (1-l) * Joints[i] + l * Joints[i+1];
      #local Joints[i+1] = Pos;
      #debug concat("    i : ",str(i,0,0)," pos : ", vstr
(3,Pos,",",0,3),"\n")
    #end
    Joints
  #end
 
  #macro Stretch(Joints)
    #debug "Stretch :\n"
    #for (i, 0, self._M-1, 1)
      #local l = self._Lengths[i]/vlength(self.Target-Joints[i]);  
      #local Joints[i+1] = (1-l) * Joints[i] + l * self.Target;
      #debug concat("i : ",str(i,0,0), " pos : ", vstr(3,Joints[i+
1],",",0,3),"\n")
    #end
    Joints   
  #end
 
  #macro Solve(Joints)
   #debug "Solving :\n"
   #if (self._Reachable = false)
      #local Joints = Stretch(Joints);
    #else
      #local itercount = 0;
      #local dif = vlength(self.Joints[self._M] - self.Target); 
      #while (dif > self.Tolerance)
        #debug concat("  dif : ",str(dif,0,3)," iter : ",str
(itercount,0,0),"\n")         
        #local Joints = Backwards(Joints);
        #local Joints = Forward(Joints);
        #local dif = vlength(Joints[self._M] - self.Target);
        #local itercount = itercount + 1;
        #if (itercount > self.MaxIter)
          #local dif = 0;
        #end
      #end
      #debug concat("\n  dif : ",str(dif,0,3)," end iter\n\n")         
    #end
    Joints
  #end 
  #local self.Joints = Solve(self.Joints)

  self
#end  

//==
// testscene
//
#global_settings {assumed_gamma 1.0 }
#default {pigment{rgb 1} finish{ ambient 0.2 diffuse 0.9 }} 
light_source{<1000,1000,-1000>, rgb 1}
plane{-z,0 pigment{checker rgb 0.8 rgb 0.5}}
camera {location <0, 4.5,-15> look_at <0,4.5,0>}

#macro Connect(Arr, RGB)
  #local l = dimension_size(Arr,1);
  #local i = 0;
  union{
    #while (i < l-1)
      sphere{Arr[i],0.2 pigment{rgb RGB}}
      cylinder{Arr[i],Arr[i+1],0.1  pigment{rgb RGB}}
      #local i=i+1;
    #end
    sphere{Arr[l-1],0.2 pigment{rgb <0,1,0>}}
  }
#end

#declare S = array[10]{
  <0,0,0>,<1,1,0>,<2,2,0>,
  <3,3,0>,<4,4,0>,<5,5,0>,
  <6,6,0>,<7,7,0>,<8,8,0>,
  <9,9,0>
};

#for (i,9,-9,-1)
  #declare T = <i,9,0>;
  #declare Spine = FABRIK(S, T);
  Connect(Spine.Joints, <1,0,0>)
#end


Post a reply to this message

From: ingo
Subject: Re: [3.8] Forward And Backward Reaching Inverse Kinematics
Date: 1 Dec 2018 16:18:41
Message: <XnsA9ABB01AD9149seed7@news.povray.org>
An updated version. Can now initialise the FABRIK without giving a 
target. Add a target with 

#declare Spine = FABRIK(somearraywithvectorsthatarejoints);
#declare Spine.Target = SetTarget(Spine, T);
and it calculates the new positions of the joints

ingo

//==
// Pov-Ray   : 3.8
// Scene File: FABRIK.inc
// Author    : Ingo Janssen
// Date      : 01-12-2018
// Version   : 1a1
//--
// Forward And Backward Reaching Inverse Kinematics (FABRIK) by Andreas 
Aristidou.
// http://www.andreasaristidou.com/FABRIK.html
// http://www.andreasaristidou.com/publications/papers/FABRIK.pdf
// 
http://www.andreasaristidou.com/publications/papers/Extending_FABRIK_wit
h_Model_C%CE%BFnstraints.pdf
// Excellent code inspiration & guide, by unknown author:
// https://developer.roblox.com/articles/Inverse-Kinematics-for-
Animation#FABRIK
//

#version 3.8;

#macro FABRIK(VecArr)
  #local self = dictionary {};

  #macro Init(self, VecArr)
    #macro LengthsArr(self, VecArr)
      #local self._Lengths = array[self._N-1];
      #local i = 0;
      #while (i < (self._N-1))
        #local self._Lengths[i] = vlength(VecArr[i]-VecArr[i+1]);
        #local i = i + 1; 
      #end
    #end
    
    #macro LengthsSum(self)    
      #local self._Length = 0;
      #local i = 0;
      #while (i < dimension_size(self._Lengths,1))
         #local self._Length = self._Length + self._Lengths[i];
         #local i = i + 1;
      #end
    #end
    
    #local self.Joints = VecArr;
    #local self.Tolerance = 0.1;
    #local self.MaxIter = 100;
    #local self._O = VecArr[0];
    #local self._N = dimension_size(VecArr, 1);
    #local self._M = self._N-1; //max index of array
    LengthsArr(self, VecArr)
    LengthsSum(self)
  #end
  Init(self, VecArr)

  // internals
  
  #macro _Reach(self)
    #debug "Reach : "
    #if (vlength(self._O-self.Target) > self._Length)
      #local self._Reachable = false;
      #debug "False\n"
    #else
      #local self._Reachable = true;
      #debug "True\n"
    #end
  #end

  #macro _Backwards(self)
    #debug "  Backwards :\n"
    #local self.Joints[self._M] = self.Target;
    #for (i, self._M-1, 0, -1)
      #local l = self._Lengths[i]/vlength(self.Joints[i+1]-self.Joints
[i]);
      #local Pos =  (1-l) * self.Joints[i+1] + l * self.Joints[i];
      #local self.Joints[i] = Pos;
      #debug concat("    i : ",str(i,0,0)," pos : ", vstr
(3,Pos,",",0,3),"\n")
    #end
  #end
 
  #macro _Forward(self)
    #debug "  Forward :\n"
    // set first point back to its original position
    #local self.Joints[0] = self._O; 
    #for (i, 0, self._M-1, 1)
      #local l = self._Lengths[i]/vlength(self.Joints[i+1]-self.Joints
[i]);
      #local Pos =  (1-l) * self.Joints[i] + l * self.Joints[i+1];
      #local self.Joints[i+1] = Pos;
      #debug concat("    i : ",str(i,0,0)," pos : ", vstr
(3,Pos,",",0,3),"\n")
    #end
  #end
 
  #macro _Stretch(self)
    #debug "Stretch :\n"
    #for (i, 0, self._M-1, 1)
      #local l = self._Lengths[i]/vlength(self.Target-self.Joints[i]);  
      #local self.Joints[i+1] = (1-l) * self.Joints[i] + l * 
self.Target;
      #debug concat("i : ",str(i,0,0), " pos : ", vstr(3,self.Joints[i+
1],",",0,3),"\n")
    #end
  #end
 
  #macro _Solve(self)
    #debug "Solving :\n"
    #if (self._Reachable = false)
      _Stretch(self)
    #else
      #local itercount = 0;
      #local dif = vlength(self.Joints[self._M] - self.Target); 
      #while (dif > self.Tolerance)
        #debug concat("  dif : ",str(dif,0,3)," iter : ",str
(itercount,0,0),"\n")         
        _Backwards(self)
        _Forward(self)
        #local dif = vlength(self.Joints[self._M] - self.Target);
        #local itercount = itercount + 1;
        #if (itercount > self.MaxIter)
          #local dif = 0;
        #end
      #end
      #debug concat("\n  dif : ",str(dif,0,3)," end iter\n\n")         
    #end
    true
  #end 
  
  // external
  #macro SetTarget (self, Target)
    #local self.Target = Target;
    _Reach(self)
    _Solve(self)
  #end
  
  self
#end  



//==
// testscene
//
#global_settings {assumed_gamma 1.0 }
#default {pigment{rgb 1} finish{ ambient 0.2 diffuse 0.9 }} 
light_source{<1000,1000,-1000>, rgb 1}
plane{-z,0 pigment{checker rgb 0.8 rgb 0.5}}
camera {location <0, 0,-20> look_at <0,0,0>}

#macro Connect(Arr, RGB, r)
  #local l = dimension_size(Arr,1);
  #local i = 0;
  union{
    #while (i < l-1)
      sphere{Arr[i],r pigment{rgb RGB}}
      cylinder{Arr[i],Arr[i+1],r/2  pigment{rgb RGB}}
      #local i=i+1;
    #end
    sphere{Arr[l-1],r pigment{rgb <0,1,0>}}
  }
#end

#declare S = array[10]{
  <0,0,0>,<1,1,0>,<2,2,0>,
  <3,3,0>,<4,4,0>,<5,5,0>,
  <6,6,0>,<7,7,0>,<8,8,0>,
  <9,9,0>
};


#declare Spine = FABRIK(S);
#macro Draw(T)
  #declare Spine.Target = SetTarget(Spine, T);
  Connect(Spine.Joints, <0,0,1>, 0.2)
#end
#for (i,0,3,1)
  #switch(i)
    #case(0)
      #for (n,9,-9,-1)
        #declare T = <n,9,0>;
        Draw(T)
      #end
    #break
    #case(1)
      #for (n,9,-9,-1)
        #declare T = <-9,n,0>;
        Draw(T)
      #end
    #break
    #case(2)
      #for (n,-9,9,1)
        #declare T = <n,-9,0>;
        Draw(T)
      #end
    #break
    #case(3)
      #for (n,-9,9,1)
        #declare T = <9,n,0>;
        Draw(T)
      #end
    #break
  #end
  
#end


Post a reply to this message

From: Stephen
Subject: Re: [3.8] Forward And Backward Reaching Inverse Kinematics
Date: 1 Dec 2018 17:45:53
Message: <5c02c8d1@news.povray.org>
On 01/12/2018 16:18, ingo wrote:
> // Forward And Backward Reaching Inverse Kinematics (FABRIK) by Andreas
> Aristidou.
> //http://www.andreasaristidou.com/FABRIK.html

Very interesting. I also took a look at your you tube channel with the 
motion capture. Again very interesting. About 15 years ago I downloaded 
about 400 BVH files from MIT. Who opened the course data to the public. 
I could have used your methods for cleaning up the foot slippage and 
joint deformities. That was a lot of work in Poser, before exporting the 
meshes to PoseRay then into Mesh2 for Pov.
Please keep us updated with your work.


-- 

Regards
     Stephen


Post a reply to this message

From: ingo
Subject: Re: [3.8] Forward And Backward Reaching Inverse Kinematics
Date: 1 Dec 2018 18:37:11
Message: <XnsA9ABC79532498seed7@news.povray.org>
in news:5c02c8d1@news.povray.org Stephen wrote:

> On 01/12/2018 16:18, ingo wrote:
>> // Forward And Backward Reaching Inverse Kinematics (FABRIK) by
>> Andreas Aristidou.
>> //http://www.andreasaristidou.com/FABRIK.html
> 
> Very interesting. I also took a look at your you tube channel with
> the motion capture.

Not my channel Stephen, I just stumbled over Andreas' work yesterday and 
implemented it in POV-Ray (peeking a lot at other code), well, just a part 
of it for now.

Cheers,

ingo


Post a reply to this message

From: Stephen
Subject: Re: [3.8] Forward And Backward Reaching Inverse Kinematics
Date: 2 Dec 2018 04:51:52
Message: <5c0364e8$1@news.povray.org>
On 01/12/2018 18:37, ingo wrote:
> in news:5c02c8d1@news.povray.org Stephen wrote:
> 
>> On 01/12/2018 16:18, ingo wrote:
>>> // Forward And Backward Reaching Inverse Kinematics (FABRIK) by
>>> Andreas Aristidou.
>>> //http://www.andreasaristidou.com/FABRIK.html
>>
>> Very interesting. I also took a look at your you tube channel with
>> the motion capture.
> 
> Not my channel Stephen, I just stumbled over Andreas' work yesterday and
> implemented it in POV-Ray (peeking a lot at other code), well, just a part
> of it for now.
> 

My oops then. :)
Good luck with your IK project.


-- 

Regards
     Stephen


Post a reply to this message

From: And
Subject: Re: [3.8] Forward And Backward Reaching Inverse Kinematics
Date: 2 Dec 2018 10:55:00
Message: <web.5c03b9b475ee21eb25503a850@news.povray.org>
ingo <ing### [at] tagpovrayorg> wrote:
> in news:5c02c8d1@news.povray.org Stephen wrote:
>
> > On 01/12/2018 16:18, ingo wrote:
> >> // Forward And Backward Reaching Inverse Kinematics (FABRIK) by
> >> Andreas Aristidou.
> >> //http://www.andreasaristidou.com/FABRIK.html
> >
> > Very interesting. I also took a look at your you tube channel with
> > the motion capture.
>


interest


Post a reply to this message

From: ingo
Subject: Re: [3.8] Forward And Backward Reaching Inverse Kinematics
Date: 5 Dec 2018 08:49:16
Message: <XnsA9AF63E8912FBseed7@news.povray.org>
Another update. Before implementing more complex structures, I made it 
possible to solve multiple independen IK's with one Fabrik 'object'

ingo

----%<----%<----%<----%<----%<----
//==
// Pov-Ray   : 3.8
// Scene File: FABRIK.inc
// Author    : Ingo Janssen
// Date      : 01-12-2018
// Rev Date  : 05-12-2018
// Version   : 1a2
//--
// Forward And Backward Reaching Inverse Kinematics (FABRIK) by Andreas 
Aristidou.
// http://www.andreasaristidou.com/FABRIK.html
// http://www.andreasaristidou.com/publications/papers/FABRIK.pdf
// 
http://www.andreasaristidou.com/publications/papers/Extending_FABRIK_wit
h_Model_C%CE%BFnstraints.pdf
// Excellent code inspiration & guide, by unknown author:
// https://developer.roblox.com/articles/Inverse-Kinematics-for-
Animation#FABRIK
// 

#version 3.8;

//==
// macros starting with an underscore should not be called 'from the 
outside'.
// only chains mentioned in the process dictionary will be initialised
// absence of the process dictionary will result in an error
//
// The FABRIK macro needs a rather complex datastructure as input, to be 
explained later.
// Create an 'instance' of the Fabrik 'object': #declare S = FABRIK(F); 
where F is the 
// datastructure. Fabrik 'returns' an updated/initialised version of the 
input structure. 
// 
// To run the IK solver use SetTarget(S, T) where S is the afore 
mentioned insatance of 
// Fabrik and T a datastructure holding the target(s)
//
#macro FABRIK(self)
  #ifndef (self.Proc)
    #error "\nNo Process 'Proc' dictionary defined\n"
  #end
  
  // add FABRIK global defaults, they can be overridden by adding a 
Default
  // dictionary to a Chain dictionary. The Chain dict is checked first 
for
  // these values, if not available the 'global' ones are used. 
  #local self.Default = dictionary {
    ["Tolerance"] : 0.1,
    ["MaxIter"] : 100
  }
  
  #macro _Init(self)
    #macro _Lengths(self, Chain)
      #local self[Chain]._Lengths = array[self[Chain]._N-1];
      #local self[Chain]._Length = 0;
      #local i = 0;
      #while (i < (self[Chain]._N-1))
        #local self[Chain]._Lengths[i] = vlength(self[Chain].Joint[i]-
self[Chain].Joint[i+1]);
        #local self[Chain]._Length = self[Chain]._Length + self[Chain].
_Lengths[i];
        #local i = i + 1; 
      #end
    #end
    
    #for (i,0,dimension_size(self.Proc,1)-1,1)
      #ifdef (self[self.Proc[i]].Joint)
        #local Chain = self.Proc[i];
        #debug concat("init chain : ", Chain, "\n")
        #local self[Chain]._O = self[Chain].Joint[0];
        #local self[Chain]._N = dimension_size(self[Chain].Joint, 1);
        #local self[Chain]._M = self[Chain]._N-1; //max index of array
        _Lengths(self, Chain)
      #end
    #end
  #end
  _Init(self)

  // internals  
  #macro _Reach(self, Chain) //SimpleSolver & EndPoint
    #debug "Reach : "
    #if (vlength(self[Chain]._O - self[Chain].Target) > self[Chain].
_Length)
      #local self[Chain]._Reachable = false;
      #debug "False\n"
    #else
      #local self[Chain]._Reachable = true;
      #debug "True\n"
    #end
  #end

  #macro _Backwards(self, Chain)
    #debug "  Backwards :\n"
    #local self[Chain].Joint[self[Chain]._M] = self[Chain].Target;
    #for (i, self[Chain]._M-1, 0, -1)
      #local l = self[Chain]._Lengths[i]/vlength(self[Chain].Joint[i+1]-
self[Chain].Joint[i]);
      #local Pos =  (1-l) * self[Chain].Joint[i+1] + l * self
[Chain].Joint[i];
      //if constraint
      //check constraint
      //if not within constraint adjust Pos
      //2B done
      #local self[Chain].Joint[i] = Pos;
      #debug concat("    i : ",str(i,0,0)," pos : ", vstr
(3,Pos,",",0,3),"\n")
    #end
  #end

  #macro _Forward(self, Chain)
    #debug "  Forward :\n"
    // set first point back to its original position
    #local self[Chain].Joint[0] = self[Chain]._O; 
    #for (i, 0, self[Chain]._M-1, 1)
      #local l = self[Chain]._Lengths[i]/vlength(self[Chain].Joint[i+1]-
self[Chain].Joint[i]);
      #local Pos =  (1-l) * self[Chain].Joint[i] + l * self[Chain].Joint
[i+1];
      //if constraint
      //check constraint
      //if not within constraint adjust Pos
      //2B done
      #local self[Chain].Joint[i+1] = Pos;
      #debug concat("    i : ",str(i,0,0)," pos : ", vstr
(3,Pos,",",0,3),"\n")
    #end
  #end

  #macro _Stretch(self, Chain)
    #debug "Stretch :\n"
    #for (i, 0, self[Chain]._M-1, 1)
      #local l = self[Chain]._Lengths[i]/vlength(self[Chain].Target-self
[Chain].Joint[i]);  
      #local self[Chain].Joint[i+1] = (1-l) * self[Chain].Joint[i] + l * 
self[Chain].Target;
      #debug concat("i : ",str(i,0,0), " pos : ", vstr(3,self
[Chain].Joint[i+1],",",0,3),"\n")
    #end
  #end

  #macro _SolveSimple(self, Chain)
    #debug "Solving :\n"
    #if (self[Chain]._Reachable = false)
      _Stretch(self, Chain)
    #else
      #local itercount = 0;
      #local dif = vlength(self[Chain].Joint[self[Chain]._M] - self
[Chain].Target); 
      #while (dif > self.Default.Tolerance)  //2B done also check chain 
local defaults
        #debug concat("  dif : ",str(dif,0,3)," iter : ",str
(itercount,0,0),"\n")         
        _Backwards(self, Chain)
        _Forward(self, Chain)
        #local dif = vlength(self[Chain].Joint[self[Chain]._M] - self
[Chain].Target);
        #local itercount = itercount + 1;
        #if (itercount > self.Default.MaxIter)//2B done also check chain 
local defaults
          #local dif = 0;
        #end
      #end
      #debug concat("\n  dif : ",str(dif,0,3)," end iter\n\n")         
    #end
  #end 

  // external
  #macro SetTarget (self, T)
    #for (i, 0, dimension_size(T.Index,1)-1,1)
      #local Chain = T.Index[i];
      #debug concat("set target : ", Chain, "\n")
      #local self[Chain].Target = T[Chain];
      _Reach(self, T.Index[i])
      _SolveSimple(self, T.Index[i])
    #end
  #end

  self
#end


/*test scene*/

#global_settings{assumed_gamma 1.0 }
#default{pigment{rgb 1} finish{ ambient 0.2 diffuse 0.9 }} 
light_source{<1000,1000,-1000>, rgb 1}
//plane{-z,0 pigment{checker rgb 0.8 rgb 0.5}}
camera{location <0,0,-8> look_at <0,0,0>}


// Two 'independent' chains
#declare F = dictionary{
  ["Proc"]: array[2]{"Base1", "Base2"},
  ["Base1"]   : dictionary {
      ["Joint"] : array[6]{<0,0,0>, < 0,1,0>, < 0,2,0>, < 0,3,0>, 
<0,4,0>, <0,5,0>},
  }
  ["Base2"]   : dictionary {
      ["Joint"] : array[6]{<0,0,0>, < 0,1,0>, < 0,2,0>, < 0,3,0>, 
<0,4,0>, <0,5,0>},
  }
};
#declare S = FABRIK(F);


#declare T = dictionary {
  ["Index"] : array[2]{"Base1", "Base2"},
  ["Base1"] : <4,0,0>,
  ["Base2"] : <-4,0,0>
}
SetTarget(S, T)

#for (i,0,dimension_size(S.Proc,1)-1,1)
  #ifdef (S[S.Proc[i]].Joint)
    #local Chain = S.Proc[i];
    #for (n,0,S[Chain]._M-1,1)    
      sphere{S[Chain].Joint[n], 0.2}
      cylinder{S[Chain].Joint[n],S[Chain].Joint[n+1],0.2}
    #end
    sphere{S[Chain].Joint[n], 0.2 pigment{rgb x}} //end points
  #end 
#end


Post a reply to this message

From: ingo
Subject: Re: [3.8] Forward And Backward Reaching Inverse Kinematics
Date: 10 Dec 2018 15:38:04
Message: <XnsA9B4A9371664Eseed7@news.povray.org>
Added an updated version in p.b.scene-files FABRIK IK
<XnsA9B4A7C06381seed7@news.povray.org>
http://news.povray.org/povray.binaries.scene-files/thread/%
3CXnsA9B4A7C06381seed7%40news.povray.org%3E/

Still needs a lot of work but the basics do work.

I have an implementation for moving other nodes than the end nodes but 
it's complicated to integrate. I have an implementation for movement 
restriction, simplified from what is in the paper. Closed loops is one I 
havn't looked at yet. 

Specifying the whole FABRIC dictionary as it is now is tedious and will be 
simplified. Most of the data there can be derived during initialisation,

ingo


Post a reply to this message

Copyright 2003-2008 Persistence of Vision Raytracer Pty. Ltd.