public static void UpdateRACFemaleDNABones(UMAData umaData, UMASkeleton skeleton)
    {
        if (RACHumanFemaleDNAConverterBehaviour.customisation == null)
            RACHumanFemaleDNAConverterBehaviour.customisation = GameObject.FindObjectOfType(typeof(RACCustomization)) as RACCustomization;

        HumanFemaleDNAConverterBehaviour.UpdateUMAFemaleDNABones (umaData, skeleton);

        List<RACModifiableControl> controls = RACHumanFemaleDNAConverterBehaviour.customisation.ControlList;

        for (int iSliderIndex = 0; iSliderIndex < controls.Count; ++iSliderIndex)
        {
            RACModifiableControl curControl = controls[iSliderIndex];

            for (int iBodyPartIndex = 0; iBodyPartIndex < curControl.modifiedBodyParts.Length; ++iBodyPartIndex)
            {
                int skeletonStringToHash = UMASkeleton.StringToHash(curControl.modifiedBodyParts[iBodyPartIndex]);

                //Get the starting information
                Vector3 startingInformation = Vector3.zero;
                if (curControl.sliderStyle == RACModifiableControl.SliderStyle.POSITION)
                {
                    startingInformation = skeleton.GetPosition(skeletonStringToHash);

                    Vector3 scale = skeleton.GetScale(skeletonStringToHash);

                    //Modify it
                    if (curControl.effectsX)
                        startingInformation.x += curControl.sliderControl.actualValue*(1/scale.x);
                    if (curControl.effectsY)
                        startingInformation.y += curControl.sliderControl.actualValue*(1/scale.y);
                    if (curControl.effectsZ)
                        startingInformation.z += curControl.sliderControl.actualValue*(1/scale.z);

                    skeleton.SetPosition(skeletonStringToHash, startingInformation);
                }
                else if (curControl.sliderStyle == RACModifiableControl.SliderStyle.SCALE)
                {
                    startingInformation = skeleton.GetScale(skeletonStringToHash);

                    //Modify it
                    if (curControl.effectsX)
                        startingInformation.x = curControl.sliderControl.actualValue;
                    if (curControl.effectsY)
                        startingInformation.y = curControl.sliderControl.actualValue;
                    if (curControl.effectsZ)
                        startingInformation.z = curControl.sliderControl.actualValue;

                    skeleton.SetScale(skeletonStringToHash, startingInformation);
                }
            }
        }
    }
コード例 #2
0
 public void AdjustScale(UMASkeleton skeleton)
 {
     if (_adjustScale)
     {
         if (skeleton.HasBone(scaleBoneHash))
         {
             var   liveScaleResult   = _liveScale != -1f ? _liveScale : _scale;
             float finalOverallScale = skeleton.GetScale(_scaleBoneHash).x *liveScaleResult;                     //hmm why does this work- its supposed to be +
             skeleton.SetScale(_scaleBoneHash, new Vector3(finalOverallScale, finalOverallScale, finalOverallScale));
         }
     }
 }
コード例 #3
0
        /// <summary>
        /// Apply the modifiers using the given dna (determined by the typehash)
        /// </summary>
        /// <param name="umaData"></param>
        /// <param name="skeleton"></param>
        /// <param name="dnaTypeHash"></param>
        public override void ApplyDNA(UMAData umaData, UMASkeleton skeleton, int dnaTypeHash)
        {
            var umaDna           = umaData.GetDna(dnaTypeHash);
            var masterWeightCalc = masterWeight.GetWeight(umaDna);

            if (masterWeightCalc == 0f)
            {
                return;
            }
            for (int i = 0; i < _skeletonModifiers.Count; i++)
            {
                _skeletonModifiers[i].umaDNA = umaDna;

                var thisHash = (_skeletonModifiers[i].hash != 0) ? _skeletonModifiers[i].hash : UMAUtils.StringToHash(_skeletonModifiers[i].hashName);

                //check skeleton has the bone we want to change
                if (!skeleton.HasBone(thisHash))
                {
                    //Debug.LogWarning("You were trying to apply skeleton modifications to a bone that didn't exist (" + _skeletonModifiers[i].hashName + ") on " + umaData.gameObject.name);
                    continue;
                }

                //With these ValueX.x is the calculated value and ValueX.y is min and ValueX.z is max
                var thisValueX = _skeletonModifiers[i].CalculateValueX(umaDna);
                var thisValueY = _skeletonModifiers[i].CalculateValueY(umaDna);
                var thisValueZ = _skeletonModifiers[i].CalculateValueZ(umaDna);

                if (_skeletonModifiers[i].property == SkeletonModifier.SkeletonPropType.Position)
                {
                    skeleton.SetPositionRelative(thisHash,
                                                 new Vector3(
                                                     Mathf.Clamp(thisValueX.x, thisValueX.y, thisValueX.z),
                                                     Mathf.Clamp(thisValueY.x, thisValueY.y, thisValueY.z),
                                                     Mathf.Clamp(thisValueZ.x, thisValueZ.y, thisValueZ.z)), masterWeightCalc);
                }
                else if (_skeletonModifiers[i].property == SkeletonModifier.SkeletonPropType.Rotation)
                {
                    skeleton.SetRotationRelative(thisHash,
                                                 Quaternion.Euler(new Vector3(
                                                                      Mathf.Clamp(thisValueX.x, thisValueX.y, thisValueX.z),
                                                                      Mathf.Clamp(thisValueY.x, thisValueY.y, thisValueY.z),
                                                                      Mathf.Clamp(thisValueZ.x, thisValueZ.y, thisValueZ.z))), masterWeightCalc);
                }
                else if (_skeletonModifiers[i].property == SkeletonModifier.SkeletonPropType.Scale)
                {
                    //If there are two sets of skeletonModifiers and both are at 50% it needs to apply them both but the result should be cumulative
                    //so we need to work out the difference this one is making, weight that and add it to the current scale of the bone
                    var scale = new Vector3(
                        Mathf.Clamp(thisValueX.x, thisValueX.y, thisValueX.z),
                        Mathf.Clamp(thisValueY.x, thisValueY.y, thisValueY.z),
                        Mathf.Clamp(thisValueZ.x, thisValueZ.y, thisValueZ.z));
                    //we cant use val.value here because the initial values always need to be applied
                    var defaultVal = SkeletonModifier.skelAddDefaults[SkeletonModifier.SkeletonPropType.Scale].x;
                    var scaleDiff  = new Vector3(scale.x - defaultVal,
                                                 scale.y - defaultVal,
                                                 scale.z - defaultVal);
                    var weightedScaleDiff = scaleDiff * masterWeightCalc;
                    var fullScale         = skeleton.GetScale(_skeletonModifiers[i].hash) + weightedScaleDiff;
                    skeleton.SetScale(thisHash, fullScale);
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Updates the characterHeightMassRadius after all other changes have been made by the converters
        /// </summary>
        private void UpdateCharacterHeightMassRadius(UMAData umaData, UMASkeleton skeleton, Bounds newBounds)
        {
            float charHeight = newBounds.size.y;
            float charWidth  = newBounds.size.x;

            if (umaData.umaRecipe.raceData.umaTarget == RaceData.UMATarget.Humanoid)
            {
                //adjusting is only about tweaking the result
                if (_adjustHeight || _adjustRadius)
                {
                    float chinHeight = 0f;
                    float headHeight = 0f;
                    float headWidth  = 0f;

                    UpdateMechanimBoneDict(umaData, skeleton);

                    //character needs to be moved into the root again with no rotation applied
                    var  umaTransform        = umaData.transform;
                    var  originalParent      = umaData.transform.parent;
                    var  originalRot         = umaData.transform.localRotation;
                    var  originalPos         = umaData.transform.localPosition;
                    var  umaCollider         = umaData.gameObject.GetComponent <Collider>();
                    bool prevColliderEnabled = umaCollider != null ? umaCollider.enabled : false;

                    //if there is a collider, disable it before we move anything
                    if (umaCollider)
                    {
                        umaCollider.enabled = false;
                    }

                    umaTransform.SetParent(null, false);
                    umaTransform.localRotation = Quaternion.identity;
                    umaTransform.localPosition = Vector3.zero;

                    if (_adjustHeight)
                    {
                        //Classically a human is apprx 7.5 heads tall, but we only know the height to the base of the head bone
                        //usually head bone is actually usually in line with the lips, making the base of the chin, 1/3rd down the neck
                        //so if we have the optional neck bone use that to estimate the base of the chin
                        chinHeight = skeleton.GetRelativePosition(_mechanimBoneDict["Head"]).y;
                        if (skeleton.BoneExists(_mechanimBoneDict["Neck"]))
                        {
                            chinHeight = skeleton.GetRelativePosition(_mechanimBoneDict["Neck"]).y + (((skeleton.GetRelativePosition(_mechanimBoneDict["Head"]).y - skeleton.GetRelativePosition(_mechanimBoneDict["Neck"]).y) / 3f) * 2f);
                        }
                        //apply the headRatio (by default this is 7.5)
                        chinHeight = (chinHeight / 6.5f) * (_headRatio - 1);
                        //so classically chinbase is 6.5 headHeights from the floor so headHeight is..
                        headHeight = (chinHeight / (_headRatio - 1));
                        //but bobble headed charcaters (toons), children or dwarves etc have bigger heads proportionally
                        //so their overall height will greater than (chinHeight / 6.5) * 7.5
                        //If we have the eyes we can use those to calculate the size of the head better because classically the distance from the chin to the eyes will be half the head height
                        if (skeleton.BoneExists(_mechanimBoneDict["LeftEye"]) || skeleton.BoneExists(_mechanimBoneDict["RightEye"]))
                        {
                            var eyeHeight = 0f;
                            //if we have both eyes get the average
                            if (skeleton.BoneExists(_mechanimBoneDict["LeftEye"]) && skeleton.BoneExists(_mechanimBoneDict["RightEye"]))
                            {
                                eyeHeight = (skeleton.GetRelativePosition(_mechanimBoneDict["LeftEye"]).y + skeleton.GetRelativePosition(_mechanimBoneDict["RightEye"]).y) / 2f;
                            }
                            else if (skeleton.BoneExists(_mechanimBoneDict["LeftEye"]))
                            {
                                eyeHeight = skeleton.GetRelativePosition(_mechanimBoneDict["LeftEye"]).y;
                            }
                            else if (skeleton.BoneExists(_mechanimBoneDict["RightEye"]))
                            {
                                eyeHeight = skeleton.GetRelativePosition(_mechanimBoneDict["RightEye"]).y;
                            }

                            headHeight = ((eyeHeight - chinHeight) * 2f);
                            //because we do this the actual headRatio doesnt *feel* right
                            //i.e. with toon the head ratio is more like 3, but the correct value for calcs is 6.5
                            //I'd prefer it if these calcs made 3 deliver the correct result
                        }

                        //So finally
                        //Debug.Log("chinHeight was " + chinHeight+" headHeight was "+headHeight);
                        //Debug.Log("Classical Height from Head = " + (headHeight * 7.5f));
                        //Debug.Log("Classical Height from Chin = " + ((chinHeight / 6.5f) * 7.5f));
                        charHeight = chinHeight + headHeight;
                    }

                    if (_adjustRadius)
                    {
                        float shouldersWidth = Mathf.Abs(skeleton.GetRelativePosition(_mechanimBoneDict["LeftUpperArm"]).x - skeleton.GetRelativePosition(_mechanimBoneDict["RightUpperArm"]).x);
                        //Also female charcaters tend to have hips wider than their shoulders, so check that
                        float hipsWidth = Mathf.Abs(skeleton.GetRelativePosition(_mechanimBoneDict["LeftUpperLeg"]).x - skeleton.GetRelativePosition(_mechanimBoneDict["RightUpperLeg"]).x);
                        //the outerWidth of the hips is larger than this because the thigh muscles are so big so make this 1/3rd bigger
                        hipsWidth = (hipsWidth / 2) * 3;

                        //classically the width of the body is 3* headwidth for a strong character so headwidth will be
                        headWidth = shouldersWidth / 2.75f;
                        //but bobble headed charcaters (toons), children or dwarves etc have bigger heads proportionally and the head can be wider than the shoulders
                        //so if we have eye bones use them to calculate head with
                        if (skeleton.BoneExists(_mechanimBoneDict["LeftEye"]) && skeleton.BoneExists(_mechanimBoneDict["RightEye"]))
                        {
                            //clasically a face is 5* the width of the eyes where the distance between the pupils is 2 * eye width
                            var eyeWidth = Mathf.Abs(skeleton.GetRelativePosition(_mechanimBoneDict["LeftEye"]).x - skeleton.GetRelativePosition(_mechanimBoneDict["RightEye"]).x) / 2;
                            headWidth = eyeWidth * 5f;
                        }
                        charWidth = (shouldersWidth > headWidth || hipsWidth > headWidth) ? (shouldersWidth > hipsWidth ? shouldersWidth : hipsWidth) : headWidth;
                        //we might also want to take into account the z depth between the hips and the head,
                        //because if the character has been made into a horse or something it might be on all fours (and still be mechanim.Humanoid [if that even works!])
                        //capsule colliders break down in this scenario though (switch race to SkyCar to see what I mean), so would we want to change the orientation of the collider or the type?
                        //does the collider orientation have any impact on physics?
                    }
                    //Set the UMA back
                    umaTransform.SetParent(originalParent, false);
                    umaTransform.localRotation = originalRot;
                    umaTransform.localPosition = originalPos;

                    //set any collider to its original setting
                    if (umaCollider)
                    {
                        umaCollider.enabled = prevColliderEnabled;
                    }
                }
            }
            else             //if its a car or a castle or whatever use the bounds
            {
                charHeight = newBounds.size.y;
                charWidth  = newBounds.size.x;
            }

            //get the scale of the overall scale bone if set
            float overallScale = 1f;

            if (skeleton.GetBoneTransform(_scaleBoneHash) != null)
            {
                overallScale = (skeleton.GetScale(_scaleBoneHash)).x;
            }

            if (_adjustHeight)
            {
                //characterHeight is what we calculated plus any radius y the user has added
                umaData.characterHeight = charHeight * (1 + (_radiusAdjustY * 2));
            }
            else
            {
                umaData.characterHeight = charHeight;
            }

            if (_adjustRadius)
            {
                //characterRadius is the average of the width we calculated plus the z-depth from the bounds / 2
                //we need to include the new _radiusAdjust.y (which is now an adjust for the z axis as radiusAdjustY is now its own field (used for heightAdjust)
                umaData.characterRadius = (charWidth + newBounds.size.z * (_radiusAdjust.x * 2)) / 2;
                //Debug.Log("BCM umaData.characterRadius[" + umaData.characterRadius + "] = (charWidth[" + charWidth + "] + newBounds.size.z[" + newBounds.size.z + "] * (radiusAdjust.x[" + _radiusAdjust.x + "] * 2)) / 2;");
            }
            else
            {
                umaData.characterRadius = (charWidth + newBounds.size.z) / 2;
            }

            if (_adjustMass)
            {
                //characterMass is... what? still dont understand this quite
                var massZModified = (umaData.characterRadius * 2) * overallScale;
                var massYModified = ((1 + _radiusAdjustY) * 0.5f) * overallScale;
                umaData.characterMass = (_massAdjust.x * overallScale) + _massAdjust.y * massYModified + _massAdjust.z * massZModified;
            }
            else
            {
                //HUMANMALE umaData.characterMass[66.68236] = raceMass[50] * overallScale[0.907451] + 28f * umaDna.upperWeight[0.5019608] + 22f * umaDna.lowerWeight[0.3176471]
                umaData.characterMass = 66.68236f;                //? Thats the result
            }
            //in the fixed UMA converters HumanMales mass is actually less than HumanFemales, with this thats solved
            //but the characters are lighter than stock by a about 5 when at they standard size and heaver than stock by about 7 when at max height
            //I dont know how much this matters? It can easily be fixed by tweaking the calcs, I just dont know what the numbers mean again...

            //Debug.Log(umaData.transform.gameObject.name + " umaData.characterMass was "+ umaData.characterMass+" characterHeight was " + umaData.characterHeight + " characterRadius was " + umaData.characterRadius);

#if UNITY_EDITOR
            /*if (_heightDebugToolsEnabled)
             *      AddDebugBoxes(umaData, chinHeight, headHeight, headWidth);
             * else
             *      RemoveDebugBoxes(umaData);*/
#endif
        }