示例#1
0
// ----------------------------------------------------------------------------
ik_node_t* IKSolver::CreateIKNodeFromUrhoNode(const Node* node)
{
    ik_node_t* ikNode = ik_node_create(node->GetID());

    // Set initial position/rotation and pass in Node* as user data for later
    ikNode->original_position = Vec3Urho2IK(node->GetWorldPosition());
    ikNode->original_rotation = QuatUrho2IK(node->GetWorldRotation());
    ikNode->user_data = (void*)node;

    /*
     * If Urho's node has an effector, also create and attach one to the
     * library's node. At this point, the IKEffector component shouldn't be
     * holding a reference to any internal effector. Check this for debugging
     * purposes and log if it does.
     */
    IKEffector* effector = node->GetComponent<IKEffector>();
    if (effector != nullptr)
    {
#ifdef DEBUG
        if (effector->ikEffectorNode_ != NULL)
            URHO3D_LOGWARNINGF("[ik] IKEffector (attached to node \"%s\") has a reference to a possibly invalid internal effector. Should be NULL.", effector->GetNode()->GetName().CString());
#endif
        ik_effector_t* ikEffector = ik_effector_create();
        ik_node_attach_effector(ikNode, ikEffector); // ownership of effector

        effector->SetIKSolver(this);
        effector->SetIKEffectorNode(ikNode);
    }

    // Exact same deal with the constraint
    IKConstraint* constraint = node->GetComponent<IKConstraint>();
    if (constraint != nullptr)
    {
#ifdef DEBUG
        if (constraint->ikConstraintNode_ != NULL)
            URHO3D_LOGWARNINGF("[ik] IKConstraint (attached to node \"%s\") has a reference to a possibly invalid internal constraint. Should be NULL.", constraint->GetNode()->GetName().CString());
#endif

        constraint->SetIKConstraintNode(ikNode);
    }

    return ikNode;
}
示例#2
0
// ----------------------------------------------------------------------------
void IKSolver::BuildTreeToEffector(const Node* node)
{
    // Check if the component that was added is an IK effector. If not, then it
    // does not concern us.
    IKEffector* effector = static_cast<IKEffector*>(node->GetComponent<IKEffector>());
    if (effector == NULL || effector->GetType() != IKEffector::GetTypeStatic())
        return;

    // May need to build tree up to the node where this effector was added. Do
    // this by following the chain of parent nodes until we hit a node that
    // exists in the solver's tree. Then iterate backwards again and add each
    // missing node to the solver's tree.
    PODVector<const Node*> missingNodes;
    const Node* iterNode = node;
    ik_node_t* ikNode = ik_node_find_child(solver_->tree, node->GetID());
    while (ikNode == NULL)
    {
        missingNodes.Push(iterNode);
        iterNode = iterNode->GetParent();
        ikNode = ik_node_find_child(solver_->tree, iterNode->GetID());
    }
    while (missingNodes.Size() > 0)
    {
        iterNode = missingNodes.Back();
        missingNodes.Pop();
        ik_node_t* ikChildNode = CreateIKNode(iterNode);
        ik_node_add_child(ikNode, ikChildNode);
        ikNode = ikChildNode;
    }

    // The tip of the tree is the effector. The solver library has ownership of
    // the effector object, but our IKEffector object also needs to know about
    // it.
    ik_effector_t* ikEffector = ik_effector_create();
    ik_node_attach_effector(ikNode, ikEffector); // ownership of effector
    effector->SetIKEffector(ikEffector);           // "weak" reference to effector
    effector->SetIKSolver(this);
    effectorList_.Push(effector);

    MarkSolverTreeDirty();
}