2
0
Эх сурвалжийг харах

Setting the algorithm creates a new solver

TheComet 8 жил өмнө
parent
commit
067785d022

+ 8 - 1
Source/Urho3D/IK/IKEffector.cpp

@@ -55,8 +55,9 @@ void IKEffector::RegisterObject(Context* context)
 {
     context->RegisterFactory<IKEffector>(IK_CATEGORY);
 
-    URHO3D_ACCESSOR_ATTRIBUTE("Chain Length", GetChainLength, SetChainLength, unsigned, true, AM_DEFAULT);
+    URHO3D_ACCESSOR_ATTRIBUTE("Target Position", GetTargetPosition, SetTargetPosition, Vector3, Vector3::ZERO, AM_DEFAULT);
     URHO3D_ACCESSOR_ATTRIBUTE("Target Node", GetTargetName, SetTargetName, String, String::EMPTY, AM_DEFAULT);
+    URHO3D_ACCESSOR_ATTRIBUTE("Chain Length", GetChainLength, SetChainLength, unsigned, true, AM_DEFAULT);
 }
 
 // ----------------------------------------------------------------------------
@@ -93,6 +94,12 @@ void IKEffector::SetTargetName(const String& nodeName)
     targetNode_ = NULL;
 }
 
+// ----------------------------------------------------------------------------
+const Vector3& IKEffector::GetTargetPosition() const
+{
+    return targetPosition_;
+}
+
 // ----------------------------------------------------------------------------
 void IKEffector::SetTargetPosition(const Vector3& targetPosition)
 {

+ 1 - 0
Source/Urho3D/IK/IKEffector.h

@@ -80,6 +80,7 @@ public:
      */
     void SetTargetName(const String& nodeName);
 
+    const Vector3& GetTargetPosition() const;
     void SetTargetPosition(const Vector3& targetPosition);
 
     void UpdateTargetNodePosition();

+ 34 - 16
Source/Urho3D/IK/IKSolver.cpp

@@ -60,10 +60,24 @@ static Vector3 Vec3IK2Urho(const vec3_t* ik)
 {
     return Vector3(ik->v.x, ik->v.y, ik->v.z);
 }
+static quat_t QuatUrho2IK(const Quaternion& urho)
+{
+    quat_t ret;
+    ret.q.x = urho.x_;
+    ret.q.y = urho.y_;
+    ret.q.z = urho.z_;
+    ret.q.w = urho.w_;
+    return ret;
+}
+static Quaternion QuatIK2Urho(const quat_t* ik)
+{
+    return Quaternion(ik->q.w, ik->q.x, ik->q.y, ik->q.z);
+}
 static ik_node_t* CreateIKNode(const Node* node)
 {
     ik_node_t* ikNode = ik_node_create(node->GetID());
     ikNode->position = Vec3Urho2IK(node->GetWorldPosition());
+    ikNode->rotation = QuatUrho2IK(node->GetWorldRotation());
     ikNode->user_data = (void*)node;
     return ikNode;
 }
@@ -82,13 +96,8 @@ static bool ChildrenHaveEffector(const Node* node)
 static void ApplyResultCallback(ik_node_t* ikNode, vec3_t position, quat_t rotation)
 {
     Node* node = (Node*)ikNode->user_data;
-    node->SetWorldPosition(Vec3IK2Urho(&ikNode->solved_position));
-    node->SetWorldRotation(Quaternion(
-        rotation.q.w,
-        rotation.q.x,
-        rotation.q.y,
-        rotation.q.z
-    ));
+    node->SetWorldRotation(QuatIK2Urho(&rotation));
+    //node->SetWorldPosition(Vec3IK2Urho(&position));
 }
 
 // ----------------------------------------------------------------------------
@@ -98,10 +107,8 @@ IKSolver::IKSolver(Context* context) :
     solverTreeNeedsRebuild_(false)
 {
     context_->RequireIK();
-    solver_ = ik_solver_create(SOLVER_FABRIK);
-    solver_->apply_result = ApplyResultCallback;
-    solver_->build_mode = SOLVER_EXCLUDE_ROOT;
-    ik_log_register_listener(HandleIKLog);
+
+    SetAlgorithm(FABRIK);
 
     SubscribeToEvent(E_COMPONENTADDED,              URHO3D_HANDLER(IKSolver, HandleComponentAdded));
     SubscribeToEvent(E_COMPONENTREMOVED,            URHO3D_HANDLER(IKSolver, HandleComponentRemoved));
@@ -136,22 +143,33 @@ void IKSolver::RegisterObject(Context* context)
         NULL
     };
 
-    URHO3D_ACCESSOR_ATTRIBUTE("Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
     URHO3D_ENUM_ACCESSOR_ATTRIBUTE("Algorithm", GetAlgorithm, SetAlgorithm, Algorithm, algorithmNames, SOLVER_FABRIK, AM_DEFAULT);
-    URHO3D_ACCESSOR_ATTRIBUTE("Max Iterations", GetMaximumIterations, SetMaximumIterations, unsigned, 1000, AM_DEFAULT);
-    URHO3D_ACCESSOR_ATTRIBUTE("Convergence Tolerance", GetTolerance, SetTolerance, float, 0.1f, AM_DEFAULT);
+    URHO3D_ACCESSOR_ATTRIBUTE("Max Iterations", GetMaximumIterations, SetMaximumIterations, unsigned, 20, AM_DEFAULT);
+    URHO3D_ACCESSOR_ATTRIBUTE("Convergence Tolerance", GetTolerance, SetTolerance, float, 0.001, AM_DEFAULT);
 }
 
 // ----------------------------------------------------------------------------
 void IKSolver::SetAlgorithm(IKSolver::Algorithm algorithm)
 {
-    URHO3D_LOGERROR("Failed to set algorithm: Not implemented");
+    algorithm_ = algorithm;
+
+    if (solver_ != NULL)
+        ik_solver_destroy(solver_);
+
+    switch (algorithm_)
+    {
+        case FABRIK: solver_ = ik_solver_create(SOLVER_FABRIK); break;
+    }
+
+    solver_->apply_result = ApplyResultCallback;
+    solver_->build_mode = SOLVER_EXCLUDE_ROOT;
+    ik_log_register_listener(HandleIKLog);
 }
 
 // ----------------------------------------------------------------------------
 IKSolver::Algorithm IKSolver::GetAlgorithm() const
 {
-    return FABRIK;
+    return algorithm_;
 }
 
 // ----------------------------------------------------------------------------

+ 4 - 2
Source/Urho3D/IK/IKSolver.h

@@ -46,9 +46,10 @@ public:
 
     enum Algorithm
     {
-        FABRIK,
+        FABRIK
+        /* not implemented yet
         JACOBIAN_INVERSE,
-        JACOBIAN_TRANSPOSE
+        JACOBIAN_TRANSPOSE*/
     };
 
     /// Construct an IK root component.
@@ -128,6 +129,7 @@ private:
 
     PODVector<IKEffector*> effectorList_;
     ik_solver_t* solver_;
+    Algorithm algorithm_;
     bool solverTreeNeedsRebuild_;
 };