瀏覽代碼

Finished IK documentation

TheComet 8 年之前
父節點
當前提交
8f4b77aa34
共有 1 個文件被更改,包括 87 次插入13 次删除
  1. 87 13
      Docs/Reference.dox

+ 87 - 13
Docs/Reference.dox

@@ -2160,7 +2160,10 @@ create one by attaching the IKEffector component to a node.
 
 
 \code{.cpp}
 \code{.cpp}
 Node* handNode = modelNode->GetChild("Hand.R", true);
 Node* handNode = modelNode->GetChild("Hand.R", true);
-IKEffector* effector = handNode->CreateComponent<IKEffector>();
+
+IKEffector* effector = handNode->CreateComponent<IKEffector>();  // C++
+IKEffector@ effector = handNode.CreateComponent("IKEffector");   // AngelScript
+local effector = handNode:CreateComponent("IKEffector")          -- Lua
 \endcode
 \endcode
 
 
 You can then give the effector a target position (for example, the position of
 You can then give the effector a target position (for example, the position of
@@ -2168,7 +2171,9 @@ an apple) using  IKEffector::SetTargetPosition or you can tell the effector to
 automatically track  the  position  of  a node with IKEffector::SetTargetNode.
 automatically track  the  position  of  a node with IKEffector::SetTargetNode.
 
 
 \code{.cpp}
 \code{.cpp}
-effector->SetTargetPosition(appleNode->GetWorldPosition());
+effector->SetTargetPosition(appleNode->GetWorldPosition());  // C++
+effector.targetPosition = appleNode.worldPosition;           // AngelScript
+effector.targetPosition = appleNode.worldPosition            -- Lua
 \endcode
 \endcode
 
 
 If enabled, you  can also tell the effector to try and match a target rotation
 If enabled, you  can also tell the effector to try and match a target rotation
@@ -2186,6 +2191,8 @@ which   means  all  nodes  right  down  to  the  base   node   are   affected.
 
 
 \code{.cpp}
 \code{.cpp}
 effector->SetChainLength(2); // Humans have two bones in their arms
 effector->SetChainLength(2); // Humans have two bones in their arms
+effector.chainLength = 2;    // AngelScript
+effector.chainLength = 2     -- Lua
 \endcode
 \endcode
 
 
 Effectors have  a  \a  weight parameter (use IKEffector::SetWeight) indicating
 Effectors have  a  \a  weight parameter (use IKEffector::SetWeight) indicating
@@ -2196,8 +2203,8 @@ switch from animation to IK.
 
 
 \code{.cpp}
 \code{.cpp}
 effector->SetWeight(SomeSplineFunction());  // C++
 effector->SetWeight(SomeSplineFunction());  // C++
-effector.SetWeight(SomeSplineFunction());   // AngelScript
-effector:SetWeight(SomeSplineFunction());   // Lua
+effector.weight = SomeSplineFunction();     // AngelScript
+effector.weight = SomeSplineFunction();     -- Lua
 \endcode
 \endcode
 
 
 If you've played around with the weight parameter, you may  have  noticed that
 If you've played around with the weight parameter, you may  have  noticed that
@@ -2210,13 +2217,13 @@ IKEffector::SetFeature.
 \code{.cpp}
 \code{.cpp}
 effector->SetFeature(IKEffector::WEIGHT_NLERP, true);  // C++
 effector->SetFeature(IKEffector::WEIGHT_NLERP, true);  // C++
 effector.WEIGHT_NLERP = true;                          // AngelScript
 effector.WEIGHT_NLERP = true;                          // AngelScript
-effector.WEIGHT_NLERP = true                           // Lua
+effector.WEIGHT_NLERP = true                           -- Lua
 \endcode
 \endcode
 
 
 Note that the script  bindings  work  a little differently in this regard. The
 Note that the script  bindings  work  a little differently in this regard. The
 features can be enabled/disabled directly on the effector object as attributes
 features can be enabled/disabled directly on the effector object as attributes
 rather than  having  to  call  SetFeature. This is for convenience (but may be
 rather than  having  to  call  SetFeature. This is for convenience (but may be
-changed in the future due to inconsistency).
+changed in the future due to script API inconsistency).
 
 
 \section iksolvers Solvers
 \section iksolvers Solvers
 
 
@@ -2232,7 +2239,7 @@ You can create a solver by attaching an IKSolver component to a node:
 \code{.cpp}
 \code{.cpp}
 IKSolver* solver = modelNode->CreateComponent<IKSolver>();  // C++
 IKSolver* solver = modelNode->CreateComponent<IKSolver>();  // C++
 IKSolver@ solver = modelNode.CreateComponent("IKSolver");   // AngelScript
 IKSolver@ solver = modelNode.CreateComponent("IKSolver");   // AngelScript
-local solver = modelNode:CreateComponent("IKSolver")        // Lua
+local solver = modelNode:CreateComponent("IKSolver")        -- Lua
 \endcode
 \endcode
 
 
 The first thing  you'll  want to do is select the appropriate algorithm. As of
 The first thing  you'll  want to do is select the appropriate algorithm. As of
@@ -2248,7 +2255,7 @@ You can set the algorithm using:
 \code{.cpp}
 \code{.cpp}
 solver->SetAlgorithm(IKSolver::FABRIK);  // C++
 solver->SetAlgorithm(IKSolver::FABRIK);  // C++
 solver.algorithm = IKAlgorithm::FABRIK;  // AngelScript
 solver.algorithm = IKAlgorithm::FABRIK;  // AngelScript
-solver.algorithm = IKSolver.FABRIK       // Lua
+solver.algorithm = IKSolver.FABRIK       -- Lua
 \endcode
 \endcode
 
 
 If  you chose an iterative algorithm, then you might also want  to  tweak  the
 If  you chose an iterative algorithm, then you might also want  to  tweak  the
@@ -2267,7 +2274,7 @@ solver->SetTolerance(0.02);       // Good value is 100th of your chain length.
 solver.maximumIterations = 20;    // AngelScript
 solver.maximumIterations = 20;    // AngelScript
 solver.tolerance = 0.02;
 solver.tolerance = 0.02;
 
 
-solver.maximumIterations = 20     // Lua
+solver.maximumIterations = 20     -- Lua
 solver.tolerance = 0.02
 solver.tolerance = 0.02
 \endcode
 \endcode
 
 
@@ -2293,9 +2300,9 @@ desired if you want to "hook in" right between when the animation has updated,
 but before inverse kinematics is calculated.
 but before inverse kinematics is calculated.
 
 
 \code{.cpp}
 \code{.cpp}
-solver->SetFeature(IKFeature::AUTO_SOLVE, false);  // C++
-solver.AUTO_SOLVE = false;                         // AngelScript
-solver.AUTO_SOLVE = false                          // Lua
+solver->SetFeature(IKSolver::AUTO_SOLVE, false);  // C++
+solver.AUTO_SOLVE = false;                        // AngelScript
+solver.AUTO_SOLVE = false                         -- Lua
 \endcode
 \endcode
 
 
 And here's how you manually invoke the solver.
 And here's how you manually invoke the solver.
@@ -2330,12 +2337,79 @@ function HandleSceneDrawableUpdateFinished(eventType, eventData)
 end
 end
 \endcode
 \endcode
 
 
-\subsection iksolverjointrotations JOINT_ROTATIONS
+\subsection iksolverjointrotations IKSolver::JOINT_ROTATIONS
+
+\code{.cpp}
+solver->SetFeature(IKSolver::JOINT_ROTATIONS, false);  // C++
+solver.JOINT_ROTATIONS = false;                        // AngelScript
+solver.JOINT_ROTATIONS = false                         -- Lua
+\endcode
+
+This is should be enabled if you are using IK on skinned models (or  otherwise
+node structures that  need rotations). If you don't care about node rotations,
+you   can   disable   this   feature   and  get  a  small  performance  boost.
+
+When disabled, all nodes will simply keep their  original  orientation  in the
+world, only their positions will change.
+
+The solver calculates  joint  rotations  after  the  solution has converged by
+comparing the solved tree with the original tree as a  way  to  compute  delta
+angles.  These  are  then  multiplied by the original rotations to obtain  the
+final joint rotations.
 
 
 \subsection iksolvertargetrotations TARGET_ROTATIONS
 \subsection iksolvertargetrotations TARGET_ROTATIONS
 
 
+\code{.cpp}
+solver->SetFeature(IKSolver::TARGET_ROTATIONS, false);  // C++
+solver.TARGET_ROTATIONS = false;                        // AngelScript
+solver.TARGET_ROTATIONS = false                         -- Lua
+\endcode
+
+Enabling   this   will   cause   the  orientation   of   the   effector   node
+(IKEffector::SetTargetRotation)  to  be  considered during solving. This means
+that the effector node will try to match the rotation of the target as best as
+possible. If the target is out of reach or just within reach, the  chain  will
+reach out and start to ignore  the  target  rotation in favour of reaching its
+target.
+
+Disabling this feature causes IKEffector::SetTargetRotation to have no effect.
+
 \subsection iksolvertrees UPDATE_ORIGINAL_POSE, UPDATE_ACTIVE_POSE, and USE_ORIGINAL_POSE
 \subsection iksolvertrees UPDATE_ORIGINAL_POSE, UPDATE_ACTIVE_POSE, and USE_ORIGINAL_POSE
 
 
+These options can be quite confusing to understand.
+
+The solver actually stores \a two  \a trees, not one. There is an \a active \a
+tree, which is kind of like the "workbench". The  solver  uses the active tree
+for its initial condition but also writes the solution  back  into  the active
+tree (i.e. the tree is solved in-place, rather than cloning).
+
+Then  there  is the \a original \a tree, which is set once during creation and
+then never changed (at least not by default).
+
+You can control which tree the solver should use for its initial condition. If
+you   enable   USE_ORIGINAL_POSE,  then  the  solver  will  first   copy   all
+positions/rotations  from  the original  tree  into  the  active  tree  before
+solving. Thus,  the  solution  will  tend  to  "snap  back"  into its original
+configuration if it can.
+
+If you disable USE_ORIGINAL_POSE, then  the  solver  will  use the active tree
+instead. The active tree will contain whatever pose was solved last. Thus, the
+solution will tend to be more "continuous".
+
+Very important: Note that the active tree is NOT updated  by Urho3D unless you
+enable  UPDATE_ACTIVE_POSE (this is enabled by default). If UPDATE_ACTIVE_POSE
+is disabled, then any nodes that have moved outside of IKSolver's control will
+effectively be \a ignored.  Thus,  if  your model is animated, you very likely
+want this enabled.
+
+UPDATE_ORIGINAL_POSE  isn't   really  required,  but  is  here  for  debugging
+purposes. You can update the original  pose either by enabling this feature or
+by explicitely calling IKSolver::ApplySceneToOriginalPose.
+
+\subsection iksolverconstraints CONSTRAINTS
+
+This feature is not yet implemented and is planned for a future release.
+
 \page UI User interface
 \page UI User interface
 
 
 Urho3D implements a simple, hierarchical user interface system based on rectangular elements. The elements provided are:
 Urho3D implements a simple, hierarchical user interface system based on rectangular elements. The elements provided are: