Преглед изворни кода

Update initial pose every frame to support animated models

TheComet пре 8 година
родитељ
комит
1b780a219f
3 измењених фајлова са 36 додато и 9 уклоњено
  1. 0 8
      Source/Urho3D/IK/IK.h
  2. 31 1
      Source/Urho3D/IK/IKSolver.cpp
  3. 5 0
      Source/Urho3D/IK/IKSolver.h

+ 0 - 8
Source/Urho3D/IK/IK.h

@@ -22,18 +22,10 @@
 
 /*
  * TODO IK todo
- *  - Initial pose is not saved when saving scene in editor. Instead, the
- *    solved state of the chain(s) are saved.
  *  - Target angle in addition to target position -> use weighted angles
  *    approach
- *  - Add an IKEffector weight parameter, so the user can specify
- *    (between [0..1]) how much influence the solved chains have.
- *  - Add support for enabling/disabling initial pose to support animated
- *    models as well as scene nodes.
  *  - Pole targets?
  *  - Add support for manually updating initial pose.
- *  - Add support for having the initial pose update every time it's solved
- *    -> incremental solving so to speak.
  *  - Apply bullet constraints to joints.
  *  - Script bindings.
  *  - Optimise.

+ 31 - 1
Source/Urho3D/IK/IKSolver.cpp

@@ -73,7 +73,8 @@ static bool ChildrenHaveEffector(const Node* node)
 IKSolver::IKSolver(Context* context) :
     Component(context),
     solver_(NULL),
-    solverTreeNeedsRebuild_(false)
+    solverTreeNeedsRebuild_(false),
+    updateInitialPose_(false)
 {
     context_->RequireIK();
 
@@ -117,6 +118,7 @@ void IKSolver::RegisterObject(Context* context)
     URHO3D_ACCESSOR_ATTRIBUTE("Convergence Tolerance", GetTolerance, SetTolerance, float, 0.001, AM_DEFAULT);
     URHO3D_ACCESSOR_ATTRIBUTE("Calculate Angles", DoCalculateFinalAngles, SetCalculateFinalAngles, bool, true, AM_DEFAULT);
     URHO3D_ACCESSOR_ATTRIBUTE("Continuous Solving", DoSkipReset, SetSkipReset, bool, false, AM_DEFAULT);
+    URHO3D_ACCESSOR_ATTRIBUTE("Update Initial Pose", DoUpdateInitialPose, SetUpdateInitialPose, bool, false, AM_DEFAULT);
 }
 
 // ----------------------------------------------------------------------------
@@ -197,6 +199,18 @@ void IKSolver::SetSkipReset(bool enable)
         solver_->flags |= SOLVER_SKIP_RESET;
 }
 
+// ----------------------------------------------------------------------------
+bool IKSolver::DoUpdateInitialPose() const
+{
+    return updateInitialPose_;
+}
+
+// ----------------------------------------------------------------------------
+void IKSolver::SetUpdateInitialPose(bool enable)
+{
+    updateInitialPose_ = enable;
+}
+
 // ----------------------------------------------------------------------------
 void IKSolver::MarkSolverTreeDirty()
 {
@@ -220,6 +234,9 @@ void IKSolver::Solve()
         solverTreeNeedsRebuild_ = false;
     }
 
+    if (updateInitialPose_)
+        UpdateInitialPose();
+
     for(PODVector<IKEffector*>::ConstIterator it = effectorList_.Begin(); it != effectorList_.End(); ++it)
     {
         (*it)->UpdateTargetNodePosition();
@@ -242,6 +259,19 @@ void IKSolver::ResetToInitialPose()
     ik_solver_iterate_tree(solver_);
 }
 
+// ----------------------------------------------------------------------------
+static void UpdateInitialPoseCallback(ik_node_t* ikNode)
+{
+    Node* node = (Node*)ikNode->user_data;
+    ikNode->rotation = QuatUrho2IK(node->GetWorldRotation());
+    ikNode->position = Vec3Urho2IK(node->GetWorldPosition());
+}
+void IKSolver::UpdateInitialPose()
+{
+    solver_->apply_result = UpdateInitialPoseCallback;
+    ik_solver_iterate_tree(solver_);
+}
+
 // ----------------------------------------------------------------------------
 /*
  * This next section maintains the internal list of effector nodes. Whenever

+ 5 - 0
Source/Urho3D/IK/IKSolver.h

@@ -116,11 +116,15 @@ public:
     bool DoSkipReset() const;
     void SetSkipReset(bool enable);
 
+    bool DoUpdateInitialPose() const;
+    void SetUpdateInitialPose(bool enable);
+
     /// Causes the solver tree to be rebuilt before solving the next time.
     void MarkSolverTreeDirty();
 
     void Solve();
     void ResetToInitialPose();
+    void UpdateInitialPose();
 
     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
 
@@ -141,6 +145,7 @@ private:
     ik_solver_t* solver_;
     Algorithm algorithm_;
     bool solverTreeNeedsRebuild_;
+    bool updateInitialPose_;
 };
 
 } // namespace Urho3D