Example #1
0
 /// <summary>
 /// Calculates if varpdirection is 'lax' in respect to varpsource, meaning if it's 90 degrees around varpsource direction
 /// for example, right top is lax in respect to right, as is right down. Equally, left is lax in respect to left down, as is down.
 /// </summary>
 /// <param name="varpdirection">
 /// The direction we need to know the laxity of
 /// </param>
 /// <param name="varpsource">
 /// The source direction, to which varpdirection will be cast
 /// </param>
 /// <returns>
 /// True if varpdirection is lax in respect to varpsource
 /// </returns>
 private static bool metlaxdirection(enumcardinaldirections varpdirection, enumcardinaldirections varpsource)
 {
     bool varreturnvalue = false;
     //ignore the cases where parameters are none
     if (varpdirection != enumcardinaldirections.dirnone && varpsource != enumcardinaldirections.dirnone)  {
         //convert directions in integers
         int varlocaldirection = (int)varpdirection;
         int varplus = (int)varpsource;
         int varminus = (int)varpsource;
         varplus++;
         varminus--;
         //loop the values if they exceed the direction wheel limits
         if (varplus > 8)
             varplus = 1;
         if (varminus < 1)
             varminus = 8;
         //confront the values
         if (varlocaldirection == (int)varpsource || varlocaldirection == varplus || varlocaldirection == varminus) {
             varreturnvalue = true;
         }
     }
     return varreturnvalue;
 }
Example #2
0
 /// <summary>
 /// This function will return a normalized Vector2 expressing the cardinal distance of a cardinal direction
 /// will be used to calculate displacement between two bones
 /// </summary>
 /// <param name="varpdirection">
 /// the source cardinal direction (left, right, top, etc.)
 /// </param>
 /// <returns>
 /// The displacement needed to move in varpdirection direction
 /// </returns>
 private static Vector2 metcardinaldistancefromdirection(enumcardinaldirections varpdirection)
 {
     Vector2 varreturnvalue = new Vector2();
     switch (varpdirection) {
         case enumcardinaldirections.dirup:
             varreturnvalue.x = 0;
             varreturnvalue.y = 1;
             break;
         case enumcardinaldirections.dirupright:
             varreturnvalue.x = 1;
             varreturnvalue.y = 1;
             break;
         case enumcardinaldirections.dirright:
             varreturnvalue.x = 1;
             varreturnvalue.y = 0;
             break;
         case enumcardinaldirections.dirdownright:
             varreturnvalue.x = 1;
             varreturnvalue.y = -1;
             break;
         case enumcardinaldirections.dirdown:
             varreturnvalue.x = 0;
             varreturnvalue.y = -1;
             break;
         case enumcardinaldirections.dirdownleft:
             varreturnvalue.x = -1;
             varreturnvalue.y = -1;
             break;
         case enumcardinaldirections.dirleft:
             varreturnvalue.x = -1;
             varreturnvalue.y = 0;
             break;
         case enumcardinaldirections.dirupleft:
             varreturnvalue.x = -1;
             varreturnvalue.y = 1;
             break;
         case enumcardinaldirections.dirnone:
             varreturnvalue = Vector2.zero;
             break;
         default:
             varreturnvalue = Vector2.zero;
             break;
     }
     return varreturnvalue;
 }
Example #3
0
    /// <summary>
    /// This recursive function will return the first sub bone of varproot that is found along varpdirection, to determine if the sub bone
    /// pertains to a certain limb or not. The function will deal with cohincident bones and multi branched sub bones.
    /// </summary>
    /// <param name="varpdirection">
    /// The cardinal direction of the search (top, left, right, etc.)
    /// </param>
    /// <param name="varproot">
    /// The source bone which will be used as reference for the direction of search
    /// </param>
    /// <param name="varporigin">
    /// Recursion helper. Will be equal to varproot in the method call.
    /// </param>
    /// <returns>
    /// The reference to the most suitable bone in respect to varproot, along varpdirection
    /// </returns>
    private static Transform metfindvalidcardinalcandidate(enumcardinaldirections varpdirection, Transform varproot, Transform varporigin)
    {
        Transform varreturnvalue = varproot;
        Transform varcurrentcandidate = null;
        Transform varcurrentcandidatehasvalidsubbones = null;
        Transform varlastcandidate = null;
        Transform varlastcandidatehasvalidsubbones = null;
        enumcardinaldirections vardirection;

        //iterate only if the starting bone is not null
        if (varproot != null) {
            foreach (Transform varsubbone in varproot) {
                //store the last valid candidate for successive testing
                varlastcandidate = varcurrentcandidate;
                varlastcandidatehasvalidsubbones = varcurrentcandidatehasvalidsubbones;
                //calculate the cardinal direction (up, left, upleft, right, etc.) between the origin and the current sub bone
                vardirection = metcardinaldirection(metcardinaldistance(varporigin,varsubbone));
                //if the direction is not the desired one, we issue a new recursive call to be sure that there's no sub bone
                //which is actually in the required direction (rules out cohincident bone heads and same direction sub bones)
                if (vardirection != varpdirection) {
                    varcurrentcandidate = metfindvalidcardinalcandidate(varpdirection, varsubbone, varporigin);
                }
                //this sub bone's direction is the one we're looking for so we store it as the current valid candidate
                if (vardirection == varpdirection) {
                    varcurrentcandidate = varsubbone;
                    varcurrentcandidatehasvalidsubbones = metfindvalidcardinalcandidate(varpdirection, varcurrentcandidate, varporigin);
                }
                //return value decision check if we have a current candidate
                if (varcurrentcandidate != null) {
                    //we have a current candidate check if we already have a return value candidate
                    if (varlastcandidate != null) {
                        //we have both a return value candidate and a new value candidate. check if these candidates have
                        //valid origin direction sub bones
                        //the last candidate has no valid direction sub bones, but the new candidate does
                        if (varlastcandidatehasvalidsubbones == null && varcurrentcandidatehasvalidsubbones != null) {
                            //the return value candidate is overwritten with the current candidate
                            varreturnvalue = varcurrentcandidate;
                        }
                        //both candidates have sub bones in the required direction.
                        if (varlastcandidatehasvalidsubbones != null && varcurrentcandidatehasvalidsubbones != null) {
                             //We rule out the fittest candidate by counting both candidates sub bones
                            if (metcountsubbones(varlastcandidate) < metcountsubbones(varcurrentcandidate)) {
                                varreturnvalue = varcurrentcandidate;
                            }
                        }
                        //both candidates have no sub bones in the required direction
                        if (varlastcandidatehasvalidsubbones == null && varcurrentcandidatehasvalidsubbones == null) {
                            if (varpdirection == enumcardinaldirections.dirup)
                                //specific head case related to single bone-head armatures
                                if (varcurrentcandidate.childCount == 0)
                                    varreturnvalue = varcurrentcandidate;
                        }
                    }
                    //we have a current candidate and no return value candidate
                    else
                        //the return vaulue candidate becomes the current candidate
                        varreturnvalue = varcurrentcandidate;
                }
            }
            //we effectively found no valid candidates since the return value equals the starting bone, so we null the result
            if (varreturnvalue == varproot) {
                varreturnvalue = null;
            }
        }
        return varreturnvalue;
    }
Example #4
0
    /// <summary>
    /// This is a recursive function responsible for storing a cardinal direction in the bones matrix. It'll basically memorize a complete body segment
    /// </summary>
    /// <param name="varpdirection">
    /// Cardinal direction of exploration (up, right, left, etc.)
    /// </param>
    /// <param name="varproottransform">
    /// The starting point of the exploration. The spine always starts at x varmatrixsize/2, y varmatrixsize/2
    /// </param>
    /// <param name="varporigin">
    /// Auxilliary exploration variable necessary for recursion. In method calls, needs be always equal to varproottransform
    /// </param>
    /// <param name="varpskip">
    /// Auxilliary recursion variable. It needs be false in all method calls, but will be set to true by the algorithm if the bone needs to be skipped rather than stored.
    /// </param>
    /// <param name="varpstoretopbottomspinelimits">
    /// Important variable that needs be true for the spine and false for the other body segments. Will memorize the top and bottom y coordinate of the relative bones.
    /// </param>
    /// <param name="varpstrict">
    /// If the value is true, the direction of the sub bones will need be exactly like varpdirection. If varpstric is false, a sub bone can be in a +45 -45 angle in respect to the root to still qualify as a good candidate for the body segment.
    /// </param>
    /// <returns>
    /// If there's an exploration error the return value will be 0, otherwise it'll be 1 in all other cases.
    /// </returns>
    private static int metstorecardinaldirectioninbonesmatrix(enumcardinaldirections varpdirection, Transform varproottransform, Transform varporigin, bool varpskip, bool varpstoretopbottomspinelimits, bool varpstrict)
    {
        int varreturnvalue = 1;
        int varcandidatebones = 0;
        enumcardinaldirections vardirection = enumcardinaldirections.dirnone;
        Transform varcandidate = null;
        Vector2 vardirectiontofollow = new Vector2();
        bool varlaxdirection = false;

        vardirectiontofollow = metcardinaldistancefromdirection(varpdirection);
        if (!varpskip) {
            metprint("Storing " + varproottransform.name + " x " + varcoordx + " y " + varcoordy,4);
            //we can't store the current bone since we exceeded the bones matrix limit
            if (varcoordx>=varmatrixsize || varcoordy>=varmatrixsize || varcoordx < 0 || varcoordy < 0)
                return 0;
            varbonesmatrix[varcoordy][varcoordx] = varproottransform;
            if (varpstoretopbottomspinelimits) {
                if (vartopboney > varcoordy)
                    vartopboney = varcoordy;
                if (varbottomboney < varcoordy)
                    varbottomboney = varcoordy;
            }
            varcoordx-=(int)vardirectiontofollow.x;
            varcoordy-=(int)vardirectiontofollow.y;
            varreturnvalue++;
        }
        //explore the current bone if it's a strict exploration, or otherwise only if the child cound is inferior to the sub bones exploration count limit in the options
        if (varproottransform.childCount < varmaxchildcount || varpstrict) {
            foreach (Transform varsubbone in varproottransform) {
                //determine the current direction between the current sub bone and the origin
                vardirection = metcardinaldirection(metcardinaldistance(varporigin,varsubbone));
                //if the direction is not the desired one, we proceed to further checks
                if (vardirection != varpdirection) {
                    varlaxdirection = true;
                    //check if the current direction is lax, and thus valid, in respect to the requested one
                    varlaxdirection = metlaxdirection(vardirection, varpdirection);
                    //if the current direction is acceptable, iterate a recursion with a request to store the current bone
                    if (varpstrict || !varlaxdirection) {
                        varreturnvalue = metstorecardinaldirectioninbonesmatrix(varpdirection, varsubbone, varporigin,true ,varpstoretopbottomspinelimits, varpstrict);
                    }
                    //the current direction is not acceptable. iterate a recursion skipping the current sub bone
                    else {
                        varreturnvalue = metstorecardinaldirectioninbonesmatrix(varpdirection, varsubbone, varporigin,false ,varpstoretopbottomspinelimits, varpstrict);
                    }
                    //there was an error storing the last bone. exit the function.
                    if (varreturnvalue == 0) {
                        return 0;
                    }
                }
                //we store the valid candidate in case the current direction is the one we're looking for
                if (vardirection == varpdirection) {
                    varcandidate = varsubbone;
                    varcandidatebones++;
                }
            }
        }
        //if we have more than one candidate, we need to find the most suitable one to store in the next iteration
        if (varcandidatebones>1) {
            varcandidate = null;
            //find the first direction sub bone for these candidates
            metprint("Find the first valid " + varpdirection.ToString() + " candidate for " + varproottransform,4);
            varcandidate = metfindvalidcardinalcandidate(varpdirection,varproottransform, varproottransform);
        }
        //we now have one valid candidate if it actually exists
        if (varcandidate != null) {
            //if the exploration is strict, setup the candidate as the origin for the next iteration (assures a geometrical 'straight line' in the bones matrix)
            if (varpstrict) {
                metstorecardinaldirectioninbonesmatrix(varpdirection, varcandidate, varcandidate, false, varpstoretopbottomspinelimits, varpstrict);
            }
            //if the exploration is lax, setup the origin as the origin for the next iteration (allows a segmented line for the limb structure. the bones matrix stays always straight)
            else {
                metstorecardinaldirectioninbonesmatrix(varpdirection, varcandidate, varporigin, false, varpstoretopbottomspinelimits, varpstrict);
            }
            varcurrentexplorationsize++;
        }
        return varreturnvalue;
    }