/*
     * This function calculates the default position using the parameters: Stride, Length and Height
     * This default position is an important anchor point used for new step point calculation.
     */
    private Vector3 calculateDefault()
    {
        float   diameter    = chainLength - minDistance;
        Vector3 rootRotAxis = rootJoint.getRotationAxis();

        //Be careful with the use of transform.up and rootjoint.getRotationAxis(). In my case they are equivalent with the exception of the right side being inverted.
        //However they can be different and this has to be noticed here. The code below is probably wrong for the general case.
        Vector3 normal = spider.transform.up;

        Vector3 toEnd = ikChain.getEndEffector().position - rootJoint.getRotationPoint();

        toEnd = Vector3.ProjectOnPlane(toEnd, normal).normalized;

        Vector3 pivot = spider.getColliderBottomPoint() + Vector3.ProjectOnPlane(rootJoint.getRotationPoint() - spider.transform.position, normal);

        Vector3 midOrient = Quaternion.AngleAxis(0.5f * (rootJoint.maxAngle + rootJoint.minAngle), rootRotAxis) * toEnd;

        //Set the following debug variables for the DOF Arc
        minOrient = spider.transform.InverseTransformDirection(Quaternion.AngleAxis(rootJoint.minAngle, rootRotAxis) * toEnd);
        maxOrient = spider.transform.InverseTransformDirection(Quaternion.AngleAxis(rootJoint.maxAngle, rootRotAxis) * toEnd);

        // Now set the default position using the given stride, length and height
        Vector3 defOrientation = Quaternion.AngleAxis(defaultOffsetStride * 0.5f * rootJoint.getAngleRange(), rootRotAxis) * midOrient;
        Vector3 def            = pivot;

        def += (minDistance + 0.5f * (1f + defaultOffsetLength) * diameter) * defOrientation;
        def += defaultOffsetHeight * 2f * spider.getColliderRadius() * rootRotAxis;
        return(spider.transform.InverseTransformPoint(def));
    }
Exemple #2
0
    // Solves the specific joint for the CCD solver
    private static void solveJointCCD(ref JointHinge joint, ref Transform endEffector, ref TargetInfo target, float singularityRadius, bool adjustToTargetNormal)
    {
        Vector3 rotPoint = joint.getRotationPoint();
        Vector3 rotAxis  = joint.getRotationAxis();
        Vector3 toEnd    = Vector3.ProjectOnPlane((endEffector.position - rotPoint), rotAxis);
        Vector3 toTarget = Vector3.ProjectOnPlane(target.position - rotPoint, rotAxis);

        // If singularity, skip.
        if (toTarget == Vector3.zero || toEnd == Vector3.zero)
        {
            return;
        }
        if (toTarget.magnitude < singularityRadius)
        {
            return;                                         // Here even if adjustToTargetNormal is on i might not adjust if target is in this radius.
        }
        //if (toEnd.magnitude < singularityRadius) return; Notsure if i want this?

        float angle;

        //This is a special case, where i want the foot, that is the last joint of the chain to adjust to the normal it hit
        if (adjustToTargetNormal)
        {
            angle = footAngleToNormal + 90.0f - Vector3.SignedAngle(Vector3.ProjectOnPlane(target.normal, rotAxis), toEnd, rotAxis);
        }
        else
        {
            angle = weight * joint.getWeight() * Vector3.SignedAngle(toEnd, toTarget, rotAxis);
        }
        joint.applyRotation(angle);
    }