/// <summary>
        /// Uniformly randomizes each value in the DNA.
        /// </summary>
        /// <param name="data">UMA data.</param>
        public void RandomizeDNA(UMAData data)
        {
            if (dnaConverter == null)
            {
                return;
            }

            UMADnaBase dna = data.GetDna(dnaConverter.DNATypeHash);

            if (dna == null)
            {
                return;
            }

            int entryCount = dna.Count;

            if (means.Length != entryCount)
            {
                Debug.LogWarning("Range settings out of sync with DNA, cannot apply!");
                return;
            }

            if ((values == null) || (values.Length != entryCount))
            {
                values = new float[entryCount];
            }

            for (int i = 0; i < entryCount; i++)
            {
                values[i] = means[i] + (Random.value - 0.5f) * spreads[i];
            }

            dna.Values = values;
        }
        public void OnDnaApplied(UMAData umaData)
        {
            var umaDna = umaData.GetDna <UMADnaHumanoid>();

            if (umaDna == null)
            {
                Debug.LogError("Failed to add Capsule Collider to: " + umaData.name);
                return;
            }

            var rigid = umaData.gameObject.GetComponent <Rigidbody>();

            if (rigid == null)
            {
                rigid = umaData.gameObject.AddComponent <Rigidbody>();
            }
            rigid.constraints = RigidbodyConstraints.FreezeRotation;
            rigid.mass        = umaData.characterMass;

            var capsule = umaData.gameObject.GetComponent <CapsuleCollider>();

            if (capsule == null)
            {
                capsule = umaData.gameObject.AddComponent <CapsuleCollider>();
            }
            capsule.radius = umaData.characterRadius;
            capsule.height = umaData.characterHeight;
            capsule.center = new Vector3(0, capsule.height * 0.5f - 0.04f, 0);
        }
Beispiel #3
0
        /// <summary>
        /// Apply the overall scale modifications according to the given dna (determined by the dnaTypeHash)
        /// </summary>
        /// <param name="umaData"></param>
        /// <param name="skeleton"></param>
        /// <param name="dnaTypeHash"></param>
        public override void ApplyDNA(UMAData umaData, UMASkeleton skeleton, int dnaTypeHash)
        {
            if (this.converterController == null /*|| this.converterController.converterBehaviour == null*/ || _overallScaleModifiers.Count == 0)
            {
                return;
            }
            var umaDna = (DynamicUMADnaBase)umaData.GetDna(dnaTypeHash);
            //master weight determines how much we modify the converters base scale to our new value, 1 its fully overridden, 0 its left as it is
            var masterWeightCalc = masterWeight.GetWeight(umaDna);

            if (masterWeightCalc == 0f)
            {
                return;
            }

            float baseScale = this.converterController.baseScale;

            //Each modifier wants to change the base scale to its overall scale value depending on how stronly its dna(s) are applied
            //so we need to accumulate the differences each one wants to make rather than the full value
            float evaluatedScale = 0f;
            float evaluatedDiff  = 0f;

            for (int i = 0; i < _overallScaleModifiers.Count; i++)
            {
                evaluatedDiff += ((_overallScaleModifiers[i].overallScale - baseScale) * _overallScaleModifiers[i].GetEvaluatedDNA(umaDna));
            }
            //add the combined differences to the base scale
            evaluatedScale = baseScale + evaluatedDiff;
            //lerp to that result based on the masterWeightCalc
            float newScale = Mathf.Lerp(baseScale, evaluatedScale, masterWeightCalc);

            this.converterController.liveScale = newScale;
        }
Beispiel #4
0
        /// <summary>
        /// Calls ApplyDNA on all this convertersControllers plugins (aka converters) that apply dna at the standard time
        /// </summary>
        /// <param name="umaData">The umaData on the avatar</param>
        /// <param name="skeleton">The avatars skeleton</param>
        /// <param name="dnaTypeHash">The dnaTypeHash that this converters behaviour is using</param>
        public void ApplyDNA(UMAData umaData, UMASkeleton skeleton)
        {
            UMADnaBase umaDna = null;

            //reset the live scale on the overallModifiers ready for any adjustments any plugins might make
            liveScale = -1;

            //Add this ApplyHeightMassRadius method to this umaDatas CharacterUpdated event so that HeightMassRadius and bounds BaseCharacterModifiers get applied after all ConverterControllers on this character
            umaData.OnCharacterBeforeUpdated += ApplyHeightMassRadius;
            //Add this ApplyAdjustScale method to this umaDatas DnaUpdated event so that we adjust the global scale just after all other dna adjustments
            umaData.OnCharacterBeforeDnaUpdated += ApplyAdjustScale;

            //fixDNAPrefabs- do we need to deal with 'reset' as dnaconverterBehaviour used to do? If so wouldn't we just apply all the plugins with MasterWeight set to 0?
            //if (!asReset)
            //{
            umaDna = umaData.GetDna(DNATypeHash);
            //Make the DNAAssets match if they dont already, can happen when some parts are in bundles and others arent
            if (((DynamicUMADnaBase)umaDna).dnaAsset != DNAAsset)
            {
                ((DynamicUMADnaBase)umaDna).dnaAsset = DNAAsset;
            }
            //}
            for (int i = 0; i < _applyDNAPlugins.Count; i++)
            {
                _applyDNAPlugins[i].ApplyDNA(umaData, skeleton, DNATypeHash);
            }
            //_overallModifiers.UpdateCharacter(umaData, skeleton, false);
            ApplyDnaCallbackDelegates(umaData);
        }
Beispiel #5
0
        /// <summary>
        /// Randomizes each value in the DNA using a Gaussian distribution.
        /// </summary>
        /// <param name="data">UMA data.</param>
        public void RandomizeDNAGaussian(UMAData data)
        {
            if (dnaConverter == null)
            {
                return;
            }

            UMADnaBase dna = data.GetDna(dnaConverter.DNATypeHash);

            if (dna == null)
            {
                return;
            }

            int entryCount = dna.Count;

            if (values == null)
            {
                values = new float[entryCount];
            }

            for (int i = 0; i < entryCount; i++)
            {
                if (i < means.Length)
                {
                    values[i] = UMAUtils.GaussianRandom(means[i], deviations[i]);
                }
            }

            dna.Values = values;
        }
        /// <summary>
        /// Randomizes each value in the DNA using a Gaussian distribution.
        /// </summary>
        /// <param name="data">UMA data.</param>
        public void RandomizeDNAGaussian(UMAData data)
        {
            if (dnaConverter == null)
            {
                return;
            }

            UMADnaBase dna = data.GetDna(dnaConverter.DNATypeHash);

            if (dna == null)
            {
                return;
            }

            int entryCount = dna.Count;

            if (means.Length != entryCount)
            {
                Debug.LogWarning("Range settings out of sync with DNA, cannot apply!");
                return;
            }

            if (values == null)
            {
                values = new float[entryCount];
            }

            for (int i = 0; i < entryCount; i++)
            {
                values[i] = UMAUtils.GaussianRandom(means[i], deviations[i]);
            }

            dna.Values = values;
        }
        public void ApplyDNA(UMAData data, UMASkeleton skeleton)
        {
            if (morphSet == null)
            {
                Debug.LogError("Missing morph set asset for: " + this.name);
                return;
            }

            UMADnaBase activeDNA = data.GetDna(this.dnaTypeHash);

            if (activeDNA == null)
            {
                Debug.LogError("Could not get DNA values for: " + this.name);
                return;
            }

            if (morphSet.startingPose != null)
            {
                morphSet.startingPose.ApplyPose(skeleton, 1f);
            }
            if (!String.IsNullOrEmpty(morphSet.startingBlendShape))
            {
                data.SetBlendShape(morphSet.startingBlendShape, 1f);
            }

            if (activeDNA.Count == morphSet.dnaMorphs.Length)
            {
                float[] dnaValues = activeDNA.Values;
                for (int i = 0; i < dnaValues.Length; i++)
                {
                    float dnaValue = dnaValues[i];
                    MorphSetDnaAsset.DNAMorphSet morph = morphSet.dnaMorphs[i];

                    ApplyMorph(dnaValue, data, skeleton, morph);
                }
            }
            else
            {
                Debug.LogWarning("DNA length mismatch, trying names. This is SLOW!");
                string[] dnaNames = activeDNA.Names;
                for (int i = 0; i < morphSet.dnaMorphs.Length; i++)
                {
                    if (String.IsNullOrEmpty(morphSet.dnaMorphs[i].dnaEntryName))
                    {
                        continue;
                    }

                    int dnaIndex = System.Array.IndexOf(dnaNames, morphSet.dnaMorphs[i].dnaEntryName);
                    if (dnaIndex < 0)
                    {
                        continue;
                    }

                    float dnaValue = activeDNA.GetValue(dnaIndex);
                    MorphSetDnaAsset.DNAMorphSet morph = morphSet.dnaMorphs[i];

                    ApplyMorph(dnaValue, data, skeleton, morph);
                }
            }
        }
        /// <summary>
        /// Apply the DNA information about eye spacing to a skeleton.
        /// </summary>
        /// <param name="umaData">The character data.</param>
        /// <param name="skeleton">Skeleton.</param>
        public static void UpdateTutorialBones(UMAData umaData, UMASkeleton skeleton)
        {
            var umaDna = umaData.GetDna <UMADnaTutorial>();

            float spacing = (umaDna.eyeSpacing - 0.5f) * 0.01f;

            skeleton.SetPositionRelative(UMAUtils.StringToHash("LeftEye"), new Vector3(0f, -spacing, 0f));
            skeleton.SetPositionRelative(UMAUtils.StringToHash("RightEye"), new Vector3(0f, spacing, 0f));
        }
Beispiel #9
0
        /// <summary>
        /// Apply the blendshape modifications according to the given dna (determined by the dnaTypeHash)
        /// </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);

            for (int i = 0; i < _blendshapeDNAConverters.Count; i++)
            {
                _blendshapeDNAConverters[i].ApplyDNA(umaData, skeleton, umaDna, masterWeightCalc);
            }
        }
Beispiel #10
0
            public void ApplyDNA(UMAData umaData, UMASkeleton skeleton, int dnaTypeHash, float masterWeight = 1f)
            {
                _liveShapeWeight = _startingShapeWeight;

                //dna weight superceeds startingWeight if it exists
                if (_modifyingDNA.UsedDNANames.Count > 0)
                {
                    _activeDNA       = (DynamicUMADnaBase)umaData.GetDna(dnaTypeHash);
                    _liveShapeWeight = _modifyingDNA.Evaluate(_activeDNA);
                }
                _liveShapeWeight = _liveShapeWeight * masterWeight;
                _liveShapeWeight = Mathf.Clamp(_liveShapeWeight, 0f, 1f);

                umaData.SetBlendShape(_blendshapeToApply, _liveShapeWeight);
            }
Beispiel #11
0
        public void ApplyDnaCallbackDelegates(UMAData umaData)
        {
            if (_dnaCallbackDelegates.Count == 0)
            {
                return;
            }
            UMADnaBase umaDna;

            //need to use the typehash
            umaDna = umaData.GetDna(DNATypeHash);
            if (umaDna.Count == 0)
            {
                return;
            }
            foreach (KeyValuePair <string, List <UnityAction <string, float> > > kp in _dnaCallbackDelegates)
            {
                for (int i = 0; i < kp.Value.Count; i++)
                {
                    kp.Value[i].Invoke(kp.Key, (umaDna as DynamicUMADna).GetValue(kp.Key, true));
                }
            }
        }
Beispiel #12
0
        /// <summary>
        /// Uniformly randomizes each value in the DNA.
        /// </summary>
        /// <param name="data">UMA data.</param>
        public void RandomizeDNA(UMAData data)
        {
            if (dnaConverter == null)
            {
                return;
            }

            UMADnaBase dna = data.GetDna(dnaConverter.DNATypeHash);

            if (dna == null)
            {
                return;
            }

            int entryCount = dna.Count;


            for (int i = 0; i < means.Length; i++)
            {
                dna.SetValue(i, means[i] + (Random.value - 0.5f) * spreads[i]);
            }
        }
            public void ApplyDNA(UMAData umaData, UMASkeleton skeleton, int dnaTypeHash, float masterWeight = 1f)
            {
                if (_poseToApply == null)
                {
                    if (Debug.isDebugBuild)
                    {
                        Debug.LogWarning(umaData.gameObject.name + " had an invalid or empty pose set in its BonePoseDNAConverters in its DNAConverterController");
                    }
                    return;
                }
                _livePoseWeight = _startingPoseWeight;

                //dna weight superceeds startingWeight if it exists
                if (_modifyingDNA.UsedDNANames.Count > 0)
                {
                    _activeDNA      = (DynamicUMADnaBase)umaData.GetDna(dnaTypeHash);
                    _livePoseWeight = _modifyingDNA.Evaluate(_activeDNA);
                }
                _livePoseWeight = _livePoseWeight * masterWeight;
                _livePoseWeight = Mathf.Clamp(_livePoseWeight, 0f, 1f);

                _poseToApply.ApplyPose(skeleton, _livePoseWeight);
            }
Beispiel #14
0
        /// <summary>
        /// Calls ApplyDNA on all this convertersControllers plugins (aka converters) that apply dna during the pre-pass
        /// </summary>
        /// <param name="umaData">The umaData on the avatar</param>
        /// <param name="skeleton">The avatars skeleton</param>
        /// <param name="dnaTypeHash">The dnaTypeHash that this converters behaviour is using</param>
        public void ApplyDNAPrepass(UMAData umaData, UMASkeleton skeleton)
        {
            if (!_prepared)
            {
                Prepare();
            }

            UMADnaBase umaDna = umaData.GetDna(DNATypeHash);

            //Make the DNAAssets match if they dont already, can happen when some parts are in bundles and others arent
            if (((DynamicUMADnaBase)umaDna).dnaAsset != DNAAsset && DNAAsset != null)
            {
                ((DynamicUMADnaBase)umaDna).dnaAsset = DNAAsset;
            }

            if (_applyDNAPrepassPlugins.Count > 0)
            {
                for (int i = 0; i < _applyDNAPrepassPlugins.Count; i++)
                {
                    _applyDNAPrepassPlugins[i].ApplyDNA(umaData, skeleton, DNATypeHash);
                }
            }
        }
        public void ApplyDNA(UMAData data, UMASkeleton skeleton)
        {
            UMADnaBase activeDNA = data.GetDna(this.dnaTypeHash);

            if (activeDNA == null)
            {
                Debug.LogError("Could not get DNA values for: " + this.name);
                return;
            }

            if (startingPose != null)
            {
                startingPose.ApplyPose(skeleton, 1f);
            }

            if (activeDNA.Count == dnaPoses.Length)
            {
                float[] dnaValues = activeDNA.Values;
                for (int i = 0; i < dnaValues.Length; i++)
                {
                    float dnaValue = dnaValues[i];
                    if ((dnaValue > 0.5f) && (dnaPoses[i].poseOne != null))
                    {
                        float poseWeight = (dnaValue - 0.5f) * 2f;
                        dnaPoses[i].poseOne.ApplyPose(skeleton, poseWeight);
                    }
                    else if ((dnaValue < 0.5f) && (dnaPoses[i].poseZero != null))
                    {
                        float poseWeight = (0.5f - dnaValue) * 2f;
                        dnaPoses[i].poseOne.ApplyPose(skeleton, poseWeight);
                    }
                }
            }
            else
            {
                Debug.LogWarning("DNA length mismatch, trying names. This is SLOW!");
                string[] dnaNames = activeDNA.Names;
                for (int i = 0; i < dnaPoses.Length; i++)
                {
                    if ((dnaPoses[i].dnaEntryName == null) || (dnaPoses[i].dnaEntryName.Length == 0))
                    {
                        continue;
                    }

                    int dnaIndex = System.Array.IndexOf(dnaNames, dnaPoses[i].dnaEntryName);
                    if (dnaIndex < 0)
                    {
                        continue;
                    }

                    float dnaValue = activeDNA.GetValue(dnaIndex);
                    if ((dnaValue > 0.5f) && (dnaPoses[i].poseOne != null))
                    {
                        float poseWeight = (dnaValue - 0.5f) * 2f;
                        dnaPoses[i].poseOne.ApplyPose(skeleton, poseWeight);
                    }
                    else if ((dnaValue < 0.5f) && (dnaPoses[i].poseZero != null))
                    {
                        float poseWeight = (0.5f - dnaValue) * 2f;
                        dnaPoses[i].poseOne.ApplyPose(skeleton, poseWeight);
                    }
                }
            }
        }
Beispiel #16
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);
                }
            }
        }
Beispiel #17
0
        public void UpdateDynamicUMADnaBones(UMAData umaData, UMASkeleton skeleton, bool asReset = false)
        {
            UMADnaBase umaDna;

            //need to use the typehash
            umaDna = umaData.GetDna(DNATypeHash);

            if (umaDna == null || asReset == true)
            {
                umaDna = null;
            }
            //Make the DNAAssets match if they dont already...
            if (umaDna != null)
            {
                if (((DynamicUMADnaBase)umaDna).dnaAsset != dnaAsset)
                {
                    ((DynamicUMADnaBase)umaDna).dnaAsset = dnaAsset;
                }
            }
            float overallScaleCalc = 0;

            //float lowerBackScale = 0;
            //bool overallScaleFound = false;
            //bool lowerBackScaleFound = false;

            for (int i = 0; i < skeletonModifiers.Count; i++)
            {
                skeletonModifiers[i].umaDNA = umaDna;
                var thisHash = (skeletonModifiers[i].hash != 0) ? skeletonModifiers[i].hash : GetHash(skeletonModifiers[i].hashName);
                //With these ValueX.x is the calculated value and ValueX.y is min and ValueX.z is max
                var thisValueX = skeletonModifiers[i].ValueX;
                var thisValueY = skeletonModifiers[i].ValueY;
                var thisValueZ = skeletonModifiers[i].ValueZ;
                if (skeletonModifiers[i].hashName == "Position" && skeletonModifiers[i].property == SkeletonModifier.SkeletonPropType.Scale)
                {
                    //TODO eli added something for overall scale to RaceData- whats that supposed to do?
                    var calcVal = thisValueX.x - skeletonModifiers[i].valuesX.val.value + overallScale;
                    overallScaleCalc = Mathf.Clamp(calcVal, thisValueX.y, thisValueX.z);
                    skeleton.SetScale(skeletonModifiers[i].hash, new Vector3(overallScaleCalc, overallScaleCalc, overallScaleCalc));
                    //overallScaleFound = true;
                    //Debug.Log("overallScaleCalc was " + overallScaleCalc);
                }

                /*else if (skeletonModifiers[i].hashName == "LowerBack" && skeletonModifiers[i].property == SkeletonModifier.SkeletonPropType.Scale)
                 * {
                 *  lowerBackScale = Mathf.Clamp(thisValueX.x, thisValueX.y, thisValueX.z);
                 *  skeleton.SetScale(skeletonModifiers[i].hash, new Vector3(lowerBackScale, lowerBackScale, lowerBackScale));
                 *  lowerBackScaleFound = true;
                 * }*/
                else 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)));
                }
                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))), 1f);
                }
                else if (skeletonModifiers[i].property == SkeletonModifier.SkeletonPropType.Scale)
                {
                    skeleton.SetScale(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)));
                }
            }
            if (startingPose != null && asReset == false)
            {
                for (int i = 0; i < startingPose.poses.Length; i++)
                {
                    skeleton.Morph(startingPose.poses[i].hash, startingPose.poses[i].position, startingPose.poses[i].scale, startingPose.poses[i].rotation, startingPoseWeight);
                }
            }
            //overall modifiers
            //Try to use updated Bounds to set the height.
            if (overallModifiersEnabled && umaData.myRenderer != null)
            {
                if (umaData.myRenderer.localBounds.size.y == 0)
                {
                    return;
                }
                var    currentSMROffscreenSetting = umaData.myRenderer.updateWhenOffscreen;
                Bounds newBounds;

                //for this to properly calculate if the character is in a scaled game object it needs to be moved into the root
                var umaTransform = umaData.transform;
                var oldParent    = umaTransform.parent;
                var originalRot  = umaTransform.localRotation;
                var originalPos  = umaTransform.localPosition;

                //we also need to disable any collider that is on it so it doesn't hit anything when its moved
                var  thisCollider        = umaData.gameObject.GetComponent <Collider>();
                bool thisColliderEnabled = false;
                if (thisCollider)
                {
                    thisColliderEnabled  = thisCollider.enabled;
                    thisCollider.enabled = false;
                }

                //Now move into the root
                umaTransform.SetParent(null, false);
                umaTransform.localRotation = Quaternion.identity;
                umaTransform.localPosition = Vector3.zero;

                //Do the calculations
                umaData.myRenderer.updateWhenOffscreen = true;
                newBounds = new Bounds(umaData.myRenderer.localBounds.center, umaData.myRenderer.localBounds.size);
                umaData.myRenderer.updateWhenOffscreen = currentSMROffscreenSetting;

                //move it back
                umaTransform.SetParent(oldParent, false);
                umaTransform.localRotation = originalRot;
                umaTransform.localPosition = originalPos;

                //set any collider to its original setting
                if (thisCollider)
                {
                    thisCollider.enabled = thisColliderEnabled;
                }

                //somehow the bounds end up beneath the floor i.e. newBounds.center.y - newBounds.extents.y is actually a minus number
                //tighten bounds fixes this
                if (tightenBounds)
                {
                    Vector3 newCenter = new Vector3(newBounds.center.x, newBounds.center.y, newBounds.center.z);
                    Vector3 newSize   = new Vector3(newBounds.size.x, newBounds.size.y, newBounds.size.z);
                    if (newBounds.center.y - newBounds.extents.y < 0)
                    {
                        var underAmount = newBounds.center.y - newBounds.extents.y;
                        newSize.y   = (newBounds.center.y * 2) - underAmount;
                        newCenter.y = newSize.y / 2;
                    }
                    Bounds modifiedBounds = new Bounds(newCenter, newSize);
                    newBounds = modifiedBounds;
                }
                //character height can be based on the resulting height
                umaData.characterHeight = newBounds.size.y * (1 + radiusAdjust.y);
                //radius could be based on the resulting width
                umaData.characterRadius = (newBounds.size.x * (radiusAdjust.x /*/2*/) + newBounds.size.z * (radiusAdjust.x /*/ 2*/)) / 2;
                //then base the mass on a compond of those two modified by the mass modifiers values
                var radiusAsDNA  = (umaData.characterRadius * 2) * overallScaleCalc;
                var radiusYAsDNA = ((1 + radiusAdjust.y) * 0.5f) * overallScaleCalc;
                umaData.characterMass = (massModifiers.x * overallScaleCalc) + massModifiers.y * radiusYAsDNA + massModifiers.z * radiusAsDNA;
                //add bounds padding if any was set
                if (boundsAdjust != Vector3.zero)
                {
                    newBounds.Expand(boundsAdjust);
                }
                //set the padded bounds
                umaData.myRenderer.localBounds = newBounds;
            }
        }
        public override void ApplyDNA(UMAData umaData, UMASkeleton skeleton, int dnaTypeHash)
        {
            //Add the reset listeners if we havent already
            //we need this because if 'fastGeneration' is false we may still get another loop
            //and we should not do this again if _dnaAppliedTo contains umaData.gameObject
            if (!_listenersAddedTo.Contains(umaData.gameObject))
            {
                umaData.CharacterUpdated.AddListener(ResetOnCharaterUpdated);
                _listenersAddedTo.Add(umaData.gameObject);
            }

            if (_dnaAppliedTo.Contains(umaData.gameObject))
            {
                return;
            }

            UMADnaBase activeDNA = umaData.GetDna(dnaTypeHash);

            if (activeDNA == null)
            {
                Debug.LogError("Could not get DNA values for: " + this.name);
                return;
            }
            var masterWeightCalc = masterWeight.GetWeight(activeDNA);

            if (masterWeightCalc == 0f)
            {
                return;
            }

            bool needsUpdate = false;

            for (int i = 0; i < _colorSets.Length; i++)
            {
                if (_colorSets[i].modifyingDNA.UsedDNANames.Count == 0 || string.IsNullOrEmpty(_colorSets[i].targetName))
                {
                    continue;
                }
                var targetOverlays = new List <OverlayData>();
                for (int si = 0; si < umaData.umaRecipe.slotDataList.Length; si++)
                {
                    var overlays = umaData.umaRecipe.slotDataList[si].GetOverlayList();
                    for (int oi = 0; oi < overlays.Count; oi++)
                    {
                        if (overlays[oi] != null)
                        {
                            //we can target specific Overlays or SharedColors now
                            if ((overlays[oi].colorData.IsASharedColor && overlays[oi].colorData.name == _colorSets[i].targetName) || overlays[oi].overlayName == _colorSets[i].targetName)
                            {
                                if (!targetOverlays.Contains(overlays[oi]))
                                {
                                    targetOverlays.Add(overlays[oi]);
                                }
                            }
                        }
                    }
                }
                if (targetOverlays.Count == 0)
                {
                    continue;
                }
                if (_colorSets[i].EvaluateAndApplyAdjustments(activeDNA, masterWeightCalc, targetOverlays))
                {
                    needsUpdate = true;
                }
            }

            if (needsUpdate)
            {
                umaData.isTextureDirty = true;
                umaData.isAtlasDirty   = true;
            }
            _dnaAppliedTo.Add(umaData.gameObject);
        }
Beispiel #19
0
        /// <summary>
        /// Adjusts a skeleton to reflect the DNA values from UMA character data.
        /// </summary>
        /// <remarks>
        /// This will set the postion, rotation, and scale of the various adjustment
        /// bones used by the UMA human rigs to generate a unique character shape.
        /// Also calculates a somewhat realistic mass for the character and the
        /// height and radius of their default collider.
        /// </remarks>
        /// <param name="umaData">UMA data.</param>
        /// <param name="skeleton">Skeleton.</param>
        public static void UpdateUMAFemaleDNABones(UMAData umaData, UMASkeleton skeleton)
        {
            var umaDna = umaData.GetDna <UMADnaHumanoid>();

            skeleton.SetScale(headAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 1, 1),
                                  Mathf.Clamp(1 + (umaDna.headWidth - 0.5f) * 0.30f, 0.5f, 1.6f),
                                  Mathf.Clamp(1, 1, 1)));

            skeleton.SetScale(neckAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 0.6f, 2),
                                  Mathf.Clamp(1 + (umaDna.neckThickness - 0.5f) * 0.80f, 0.5f, 1.6f),
                                  Mathf.Clamp(1 + (umaDna.neckThickness - 0.5f) * 1.2f, 0.5f, 1.6f)));

            skeleton.SetScale(leftOuterBreastHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.breastSize - 0.5f) * 1.50f + (umaDna.upperWeight - 0.5f) * 0.10f, 0.6f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.breastSize - 0.5f) * 1.50f + (umaDna.upperWeight - 0.5f) * 0.10f, 0.6f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.breastSize - 0.5f) * 1.50f + (umaDna.upperWeight - 0.5f) * 0.10f, 0.6f, 1.5f)));
            skeleton.SetScale(rightOuterBreastHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.breastSize - 0.5f) * 1.50f + (umaDna.upperWeight - 0.5f) * 0.10f, 0.6f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.breastSize - 0.5f) * 1.50f + (umaDna.upperWeight - 0.5f) * 0.10f, 0.6f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.breastSize - 0.5f) * 1.50f + (umaDna.upperWeight - 0.5f) * 0.10f, 0.6f, 1.5f)));

            skeleton.SetScale(leftEyeHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.eyeSize - 0.5f) * 0.3f, 0.7f, 1.4f),
                                  Mathf.Clamp(1 + (umaDna.eyeSize - 0.5f) * 0.3f, 0.7f, 1.4f),
                                  Mathf.Clamp(1 + (umaDna.eyeSize - 0.5f) * 0.3f, 0.7f, 1.4f)));
            skeleton.SetScale(rightEyeHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.eyeSize - 0.5f) * 0.3f, 0.7f, 1.4f),
                                  Mathf.Clamp(1 + (umaDna.eyeSize - 0.5f) * 0.3f, 0.7f, 1.4f),
                                  Mathf.Clamp(1 + (umaDna.eyeSize - 0.5f) * 0.3f, 0.7f, 1.4f)));

            skeleton.SetRotation(leftEyeAdjustHash,
                                 Quaternion.Euler(new Vector3((umaDna.eyeRotation - 0.5f) * 20, 0, 0)));
            skeleton.SetRotation(rightEyeAdjustHash,
                                 Quaternion.Euler(new Vector3(-(umaDna.eyeRotation - 0.5f) * 20, 0, 0)));

            skeleton.SetScale(spine1AdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 0.6f, 2),
                                  Mathf.Clamp(1 + (umaDna.upperWeight - 0.5f) * 0.10f + (umaDna.upperMuscle - 0.5f) * 0.15f, 0.75f, 1.10f),
                                  Mathf.Clamp(1 + (umaDna.upperWeight - 0.5f) * 0.10f + (umaDna.upperMuscle - 0.5f) * 0.25f, 0.85f, 1.00f)));

            skeleton.SetScale(spineAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 0.6f, 2),
                                  Mathf.Clamp(1 + (umaDna.upperWeight - 0.5f) * 0.25f + (umaDna.upperMuscle - 0.5f) * 0.25f, 0.85f, 1.350f),
                                  Mathf.Clamp(1 + (umaDna.upperWeight - 0.5f) * 0.25f + (umaDna.upperMuscle - 0.5f) * 0.25f, 0.85f, 1.450f)));

            skeleton.SetScale(lowerBackBellyHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.belly - 0.5f) * 1.75f, 0.35f, 1.75f),
                                  Mathf.Clamp(1 + (umaDna.waist - 0.5f) * 1.75f, 0.35f, 1.75f),
                                  Mathf.Clamp(1 + (umaDna.belly - 0.5f) * 3.00f, 0.35f, 3.0f)));

            skeleton.SetScale(lowerBackAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.upperWeight - 0.5f) * 0.25f + (umaDna.lowerWeight - 0.5f) * 0.15f, 0.85f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.upperWeight - 0.5f) * 0.25f + (umaDna.lowerWeight - 0.5f) * 0.15f, 0.85f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.upperWeight - 0.5f) * 0.25f + (umaDna.lowerWeight - 0.5f) * 0.15f, 0.85f, 1.5f)));

            skeleton.SetScale(leftTrapeziusHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.upperMuscle - 0.5f) * 1.35f, 0.65f, 1.35f),
                                  Mathf.Clamp(1 + (umaDna.upperMuscle - 0.5f) * 1.35f, 0.65f, 1.35f),
                                  Mathf.Clamp(1 + (umaDna.upperMuscle - 0.5f) * 1.35f, 0.65f, 1.35f)));
            skeleton.SetScale(rightTrapeziusHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.upperMuscle - 0.5f) * 1.35f, 0.65f, 1.35f),
                                  Mathf.Clamp(1 + (umaDna.upperMuscle - 0.5f) * 1.35f, 0.65f, 1.35f),
                                  Mathf.Clamp(1 + (umaDna.upperMuscle - 0.5f) * 1.35f, 0.65f, 1.35f)));

            skeleton.SetScale(leftArmAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 0.6f, 2),
                                  Mathf.Clamp(1 + (umaDna.armWidth - 0.5f) * 0.65f, 0.65f, 1.65f),
                                  Mathf.Clamp(1 + (umaDna.armWidth - 0.5f) * 0.65f, 0.65f, 1.65f)));
            skeleton.SetScale(rightArmAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 0.6f, 2),
                                  Mathf.Clamp(1 + (umaDna.armWidth - 0.5f) * 0.65f, 0.65f, 1.65f),
                                  Mathf.Clamp(1 + (umaDna.armWidth - 0.5f) * 0.65f, 0.65f, 1.65f)));

            skeleton.SetScale(leftForeArmAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 0.6f, 2),
                                  Mathf.Clamp(1 + (umaDna.forearmWidth - 0.5f) * 0.65f, 0.75f, 1.25f),
                                  Mathf.Clamp(1 + (umaDna.forearmWidth - 0.5f) * 0.65f, 0.75f, 1.25f)));
            skeleton.SetScale(rightForeArmAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 0.6f, 2),
                                  Mathf.Clamp(1 + (umaDna.forearmWidth - 0.5f) * 0.65f, 0.75f, 1.25f),
                                  Mathf.Clamp(1 + (umaDna.forearmWidth - 0.5f) * 0.65f, 0.75f, 1.25f)));

            skeleton.SetScale(leftForeArmTwistAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 0.6f, 2),
                                  Mathf.Clamp(1 + (umaDna.forearmWidth - 0.5f) * 0.35f, 0.75f, 1.25f),
                                  Mathf.Clamp(1 + (umaDna.forearmWidth - 0.5f) * 0.35f, 0.75f, 1.25f)));
            skeleton.SetScale(rightForeArmTwistAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 0.6f, 2),
                                  Mathf.Clamp(1 + (umaDna.forearmWidth - 0.5f) * 0.35f, 0.75f, 1.25f),
                                  Mathf.Clamp(1 + (umaDna.forearmWidth - 0.5f) * 0.35f, 0.75f, 1.25f)));

            skeleton.SetScale(leftShoulderAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 0.6f, 2),
                                  Mathf.Clamp(1 + (umaDna.upperWeight - 0.5f) * 0.35f + (umaDna.upperMuscle - 0.5f) * 0.55f, 0.75f, 1.25f),
                                  Mathf.Clamp(1 + (umaDna.upperWeight - 0.5f) * 0.35f + (umaDna.upperMuscle - 0.5f) * 0.55f, 0.75f, 1.25f)));
            skeleton.SetScale(rightShoulderAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 0.6f, 2),
                                  Mathf.Clamp(1 + (umaDna.upperWeight - 0.5f) * 0.35f + (umaDna.upperMuscle - 0.5f) * 0.55f, 0.75f, 1.25f),
                                  Mathf.Clamp(1 + (umaDna.upperWeight - 0.5f) * 0.35f + (umaDna.upperMuscle - 0.5f) * 0.55f, 0.75f, 1.25f)));

            skeleton.SetScale(leftUpLegAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 0.6f, 2),
                                  Mathf.Clamp(1 + (umaDna.lowerWeight - 0.5f) * 0.65f + (umaDna.lowerMuscle - 0.5f) * 0.15f - (umaDna.legsSize - 0.5f), 0.45f, 1.35f),
                                  Mathf.Clamp(1 + (umaDna.lowerWeight - 0.5f) * 0.65f + (umaDna.lowerMuscle - 0.5f) * 0.15f - (umaDna.legsSize - 0.5f), 0.45f, 1.35f)));
            skeleton.SetScale(rightUpLegAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 0.6f, 2),
                                  Mathf.Clamp(1 + (umaDna.lowerWeight - 0.5f) * 0.65f + (umaDna.lowerMuscle - 0.5f) * 0.15f - (umaDna.legsSize - 0.5f), 0.45f, 1.35f),
                                  Mathf.Clamp(1 + (umaDna.lowerWeight - 0.5f) * 0.65f + (umaDna.lowerMuscle - 0.5f) * 0.15f - (umaDna.legsSize - 0.5f), 0.45f, 1.35f)));

            skeleton.SetScale(leftLegAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 0.6f, 2),
                                  Mathf.Clamp(1 + (umaDna.lowerWeight - 0.5f) * 0.15f + (umaDna.lowerMuscle - 0.5f) * 0.95f - (umaDna.legsSize - 0.5f), 0.65f, 1.45f),
                                  Mathf.Clamp(1 + (umaDna.lowerWeight - 0.5f) * 0.15f + (umaDna.lowerMuscle - 0.5f) * 0.75f - (umaDna.legsSize - 0.5f), 0.65f, 1.45f)));
            skeleton.SetScale(rightLegAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1, 0.6f, 2),
                                  Mathf.Clamp(1 + (umaDna.lowerWeight - 0.5f) * 0.15f + (umaDna.lowerMuscle - 0.5f) * 0.95f - (umaDna.legsSize - 0.5f), 0.65f, 1.45f),
                                  Mathf.Clamp(1 + (umaDna.lowerWeight - 0.5f) * 0.15f + (umaDna.lowerMuscle - 0.5f) * 0.75f - (umaDna.legsSize - 0.5f), 0.65f, 1.45f)));

            skeleton.SetScale(leftGluteusHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.gluteusSize - 0.5f) * 1.35f, 0.25f, 2.35f),
                                  Mathf.Clamp(1 + (umaDna.gluteusSize - 0.5f) * 1.35f, 0.25f, 2.35f),
                                  Mathf.Clamp(1 + (umaDna.gluteusSize - 0.5f) * 1.35f, 0.25f, 2.35f)));
            skeleton.SetScale(rightGluteusHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.gluteusSize - 0.5f) * 1.35f, 0.25f, 2.35f),
                                  Mathf.Clamp(1 + (umaDna.gluteusSize - 0.5f) * 1.35f, 0.25f, 2.35f),
                                  Mathf.Clamp(1 + (umaDna.gluteusSize - 0.5f) * 1.35f, 0.25f, 2.35f)));

            skeleton.SetScale(leftEarAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.earsSize - 0.5f) * 1.0f, 0.75f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.earsSize - 0.5f) * 1.0f, 0.75f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.earsSize - 0.5f) * 1.0f, 0.75f, 1.5f)));
            skeleton.SetScale(rightEarAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.earsSize - 0.5f) * 1.0f, 0.75f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.earsSize - 0.5f) * 1.0f, 0.75f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.earsSize - 0.5f) * 1.0f, 0.75f, 1.5f)));

            skeleton.SetPositionRelative(leftEarAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0 + (umaDna.headWidth - 0.5f) * -0.01f, -0.01f, 0.01f),
                                             Mathf.Clamp(0 + (umaDna.headWidth - 0.5f) * -0.03f, -0.03f, 0.03f),
                                             Mathf.Clamp(0 + (umaDna.earsPosition - 0.5f) * 0.02f, -0.02f, 0.02f)));
            skeleton.SetPositionRelative(rightEarAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0 + (umaDna.headWidth - 0.5f) * -0.01f, -0.01f, 0.01f),
                                             Mathf.Clamp(0 + (umaDna.headWidth - 0.5f) * 0.03f, -0.03f, 0.03f),
                                             Mathf.Clamp(0 + (umaDna.earsPosition - 0.5f) * 0.02f, -0.02f, 0.02f)));

            skeleton.SetRotation(leftEarAdjustHash,
                                 Quaternion.Euler(new Vector3(
                                                      Mathf.Clamp(0, -30, 80),
                                                      Mathf.Clamp(0, -30, 80),
                                                      Mathf.Clamp((umaDna.earsRotation - 0.5f) * 40, -15, 40))));
            skeleton.SetRotation(rightEarAdjustHash,
                                 Quaternion.Euler(new Vector3(
                                                      Mathf.Clamp(0, -30, 80),
                                                      Mathf.Clamp(0, -30, 80),
                                                      Mathf.Clamp((umaDna.earsRotation - 0.5f) * -40, -40, 15))));

            skeleton.SetScale(noseBaseAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.noseSize - 0.5f) * 1.5f, 0.4f, 3.0f),
                                  Mathf.Clamp(1 + (umaDna.noseSize - 0.5f) * 0.15f + (umaDna.noseWidth - 0.5f) * 1.0f, 0.25f, 3.0f),
                                  Mathf.Clamp(1 + (umaDna.noseSize - 0.5f) * 0.15f + (umaDna.noseFlatten - 0.5f) * 0.75f, 0.25f, 3.0f)));
            skeleton.SetScale(noseMiddleAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.noseCurve - 0.5f) * 1.9f + (umaDna.noseSize - 0.5f) * 1.0f, 0.5f, 3.0f),
                                  Mathf.Clamp(1 + (umaDna.noseCurve - 0.5f) * 0.15f + (umaDna.noseSize - 0.5f) * 0.25f + (umaDna.noseWidth - 0.5f) * 0.5f, 0.5f, 3.0f),
                                  Mathf.Clamp(1 + (umaDna.noseCurve - 0.5f) * 0.15f + (umaDna.noseSize - 0.5f) * 0.10f, 0.5f, 3.0f)));
            skeleton.SetRotation(noseBaseAdjustHash,
                                 Quaternion.Euler(new Vector3(
                                                      Mathf.Clamp(0, -30, 80),
                                                      Mathf.Clamp((umaDna.noseInclination - 0.5f) * 60, -60, 30),
                                                      Mathf.Clamp(0, -30, 80))));
            skeleton.SetPositionRelative(noseBaseAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0 + (umaDna.nosePronounced - 0.5f) * -0.0125f, -0.025f, 0.025f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.nosePosition - 0.5f) * 0.0125f, -0.025f, 0.025f)));
            skeleton.SetPositionRelative(noseMiddleAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0 + (umaDna.nosePronounced - 0.5f) * -0.006f, -0.012f, 0.012f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.nosePosition - 0.5f) * 0.007f, -0.015f, 0.015f)));

            skeleton.SetPositionRelative(leftNoseAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0 + (umaDna.nosePronounced - 0.5f) * -0.0125f, -0.025f, 0.025f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.nosePosition - 0.5f) * 0.0125f, -0.025f, 0.025f)));
            skeleton.SetPositionRelative(rightNoseAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0 + (umaDna.nosePronounced - 0.5f) * -0.0125f, -0.025f, 0.025f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.nosePosition - 0.5f) * 0.0125f, -0.025f, 0.025f)));

            skeleton.SetPositionRelative(upperLipsAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.nosePosition - 0.5f) * 0.0045f, -0.0045f, 0.0045f)));

            skeleton.SetScale(mandibleAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.chinPronounced - 0.5f) * 0.18f, 0.55f, 1.75f),
                                  Mathf.Clamp(1 + (umaDna.chinSize - 0.5f) * 1.3f, 0.75f, 1.3f),
                                  Mathf.Clamp(1, 0.4f, 1.5f)));
            skeleton.SetPositionRelative(mandibleAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -0.0125f, 0.0125f),
                                             Mathf.Clamp(0, -0.0125f, 0.0125f),
                                             Mathf.Clamp(0 + (umaDna.chinPosition - 0.5f) * 0.0075f, -0.0075f, 0.0075f)));

            skeleton.SetPositionRelative(leftLowMaxilarAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.jawsSize - 0.5f) * 0.025f, -0.025f, 0.025f),
                                             Mathf.Clamp(0 + (umaDna.jawsPosition - 0.5f) * 0.03f, -0.03f, 0.03f)));
            skeleton.SetPositionRelative(rightLowMaxilarAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.jawsSize - 0.5f) * -0.025f, -0.025f, 0.025f),
                                             Mathf.Clamp(0 + (umaDna.jawsPosition - 0.5f) * 0.03f, -0.03f, 0.03f)));

            skeleton.SetScale(leftCheekAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.cheekSize - 0.5f) * 1.05f, 0.35f, 2.05f),
                                  Mathf.Clamp(1 + (umaDna.cheekSize - 0.5f) * 1.05f, 0.35f, 2.05f),
                                  Mathf.Clamp(1 + (umaDna.cheekSize - 0.5f) * 1.05f, 0.35f, 2.05f)));
            skeleton.SetScale(rightCheekAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.cheekSize - 0.5f) * 1.05f, 0.35f, 2.05f),
                                  Mathf.Clamp(1 + (umaDna.cheekSize - 0.5f) * 1.05f, 0.35f, 2.05f),
                                  Mathf.Clamp(1 + (umaDna.cheekSize - 0.5f) * 1.05f, 0.35f, 2.05f)));
            skeleton.SetPositionRelative(leftCheekAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.cheekPosition - 0.5f) * 0.03f, -0.03f, 0.03f)));
            skeleton.SetPositionRelative(rightCheekAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.cheekPosition - 0.5f) * 0.03f, -0.03f, 0.03f)));

            skeleton.SetPositionRelative(leftLowCheekAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0 + (umaDna.lowCheekPronounced - 0.5f) * -0.035f, -0.07f, 0.035f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.lowCheekPosition - 0.5f) * 0.06f, -0.06f, 0.06f)));
            skeleton.SetPositionRelative(rightLowCheekAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0 + (umaDna.lowCheekPronounced - 0.5f) * -0.035f, -0.07f, 0.035f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.lowCheekPosition - 0.5f) * 0.06f, -0.06f, 0.06f)));

            skeleton.SetPositionRelative(noseTopAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0 + (umaDna.foreheadSize - 0.5f) * -0.015f, -0.025f, 0.005f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.foreheadPosition - 0.5f) * -0.025f + (umaDna.foreheadSize - 0.5f) * -0.0015f, -0.015f, 0.0025f)));

            skeleton.SetPositionRelative(leftEyebrowLowAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0 + (umaDna.foreheadSize - 0.5f) * -0.015f, -0.025f, 0.005f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.foreheadPosition - 0.5f) * -0.02f + (umaDna.foreheadSize - 0.5f) * -0.005f, -0.015f, 0.005f)));
            skeleton.SetPositionRelative(leftEyebrowMiddleAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0 + (umaDna.foreheadSize - 0.5f) * -0.015f, -0.025f, 0.005f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.foreheadPosition - 0.5f) * -0.04f + (umaDna.foreheadSize - 0.5f) * -0.005f, -0.025f, 0.005f)));
            skeleton.SetPositionRelative(leftEyebrowUpAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0 + (umaDna.foreheadSize - 0.5f) * -0.015f, -0.025f, 0.005f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.foreheadPosition - 0.5f) * -0.007f + (umaDna.foreheadSize - 0.5f) * -0.005f, -0.010f, 0.005f)));

            skeleton.SetPositionRelative(rightEyebrowLowAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0 + (umaDna.foreheadSize - 0.5f) * -0.015f, -0.025f, 0.005f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.foreheadPosition - 0.5f) * -0.02f + (umaDna.foreheadSize - 0.5f) * -0.005f, -0.015f, 0.005f)));
            skeleton.SetPositionRelative(rightEyebrowMiddleAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0 + (umaDna.foreheadSize - 0.5f) * -0.015f, -0.025f, 0.005f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.foreheadPosition - 0.5f) * -0.04f + (umaDna.foreheadSize - 0.5f) * -0.005f, -0.025f, 0.005f)));
            skeleton.SetPositionRelative(rightEyebrowUpAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0 + (umaDna.foreheadSize - 0.5f) * -0.015f, -0.025f, 0.005f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.foreheadPosition - 0.5f) * -0.007f + (umaDna.foreheadSize - 0.5f) * -0.005f, -0.010f, 0.005f)));

            skeleton.SetScale(lipsSuperiorAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.05f, 1.0f, 1.05f),
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.9f, 0.65f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.9f, 0.65f, 1.5f)));
            skeleton.SetScale(lipsInferiorAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.05f, 1.0f, 1.05f),
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 1.0f, 0.65f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 1.0f, 0.65f, 1.5f)));

            skeleton.SetScale(leftLipsSuperiorMiddleAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.05f, 1.0f, 1.05f),
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.9f, 0.65f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.9f, 0.65f, 1.5f)));
            skeleton.SetScale(rightLipsSuperiorMiddleAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.05f, 1.0f, 1.05f),
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.9f, 0.65f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.9f, 0.65f, 1.5f)));
            skeleton.SetScale(leftLipsInferiorAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.05f, 1.0f, 1.05f),
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.9f, 0.65f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.9f, 0.65f, 1.5f)));
            skeleton.SetScale(rightLipsInferiorAdjustHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.05f, 1.0f, 1.05f),
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.9f, 0.65f, 1.5f),
                                  Mathf.Clamp(1 + (umaDna.lipsSize - 0.5f) * 0.9f, 0.65f, 1.5f)));

            skeleton.SetPositionRelative(lipsInferiorAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.lipsSize - 0.5f) * -0.008f, -0.1f, 0.1f)));

            skeleton.SetPositionRelative(leftLipsAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.mouthSize - 0.5f) * 0.03f, -0.02f, 0.005f),
                                             Mathf.Clamp(0, -0.05f, 0.05f)));
            skeleton.SetPositionRelative(rightLipsAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.mouthSize - 0.5f) * -0.03f, -0.005f, 0.02f),
                                             Mathf.Clamp(0, -0.05f, 0.05f)));

            skeleton.SetPositionRelative(leftLipsSuperiorMiddleAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.mouthSize - 0.5f) * 0.007f, -0.02f, 0.005f),
                                             Mathf.Clamp(0, -0.05f, 0.05f)));
            skeleton.SetPositionRelative(rightLipsSuperiorMiddleAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.mouthSize - 0.5f) * -0.007f, -0.005f, 0.02f),
                                             Mathf.Clamp(0, -0.05f, 0.05f)));
            skeleton.SetPositionRelative(leftLipsInferiorAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.mouthSize - 0.5f) * 0.007f, -0.02f, 0.005f),
                                             Mathf.Clamp(0 + (umaDna.lipsSize - 0.5f) * -0.008f, -0.1f, 0.1f)));
            skeleton.SetPositionRelative(rightLipsInferiorAdjustHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -0.05f, 0.05f),
                                             Mathf.Clamp(0 + (umaDna.mouthSize - 0.5f) * -0.007f, -0.005f, 0.02f),
                                             Mathf.Clamp(0 + (umaDna.lipsSize - 0.5f) * -0.008f, -0.1f, 0.1f)));


            ////Bone structure change
            float overallScale = 0.81f + (umaDna.height - 0.5f) * 1.0f + (umaDna.legsSize - 0.5f) * 1.0f;

            overallScale = Mathf.Clamp(overallScale, 0.4f, 1.8f);
            skeleton.SetScale(positionHash, new Vector3(overallScale, overallScale, overallScale));

            skeleton.SetPositionRelative(positionHash,
                                         new Vector3(
                                             Mathf.Clamp((umaDna.feetSize - 0.5f) * -0.17f, -0.15f, 0.0675f),
                                             Mathf.Clamp(0, -10, 10),
                                             Mathf.Clamp(0, -10, 10)));

            float lowerBackScale = Mathf.Clamp(1 - (umaDna.legsSize - 0.5f) * 1.0f, 0.5f, 3.0f);

            skeleton.SetScale(lowerBackHash, new Vector3(lowerBackScale, lowerBackScale, lowerBackScale));

            skeleton.SetScale(headHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.headSize - 0.5f) * 2.0f, 0.5f, 2),
                                  Mathf.Clamp(1 + (umaDna.headSize - 0.5f) * 2.0f, 0.5f, 2),
                                  Mathf.Clamp(1 + (umaDna.headSize - 0.5f) * 2.0f, 0.5f, 2)));

            skeleton.SetScale(leftArmHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.armLength - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.armLength - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.armLength - 0.5f) * 2.0f, 0.5f, 2.0f)));
            skeleton.SetScale(rightArmHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.armLength - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.armLength - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.armLength - 0.5f) * 2.0f, 0.5f, 2.0f)));

            skeleton.SetScale(leftForeArmHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.forearmLength - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.forearmLength - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.forearmLength - 0.5f) * 2.0f, 0.5f, 2.0f)));
            skeleton.SetScale(rightForeArmHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.forearmLength - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.forearmLength - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.forearmLength - 0.5f) * 2.0f, 0.5f, 2.0f)));

            skeleton.SetScale(leftHandHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.handsSize - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.handsSize - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.handsSize - 0.5f) * 2.0f, 0.5f, 2.0f)));
            skeleton.SetScale(rightHandHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.handsSize - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.handsSize - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.handsSize - 0.5f) * 2.0f, 0.5f, 2.0f)));

            skeleton.SetScale(leftFootHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.feetSize - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.feetSize - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.feetSize - 0.5f) * 2.0f, 0.5f, 2.0f)));
            skeleton.SetScale(rightFootHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.feetSize - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.feetSize - 0.5f) * 2.0f, 0.5f, 2.0f),
                                  Mathf.Clamp(1 + (umaDna.feetSize - 0.5f) * 2.0f, 0.5f, 2.0f)));

            skeleton.SetPositionRelative(leftUpLegHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -10, 10),
                                             Mathf.Clamp((umaDna.legSeparation - 0.5f) * -0.15f + (umaDna.lowerWeight - 0.5f) * -0.035f + (umaDna.legsSize - 0.5f) * 0.1f, -0.055f, 0.055f),
                                             Mathf.Clamp(0, -10, 10)));
            skeleton.SetPositionRelative(rightUpLegHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -10, 10),
                                             Mathf.Clamp((umaDna.legSeparation - 0.5f) * 0.15f + (umaDna.lowerWeight - 0.5f) * 0.035f + (umaDna.legsSize - 0.5f) * -0.1f, -0.055f, 0.055f),
                                             Mathf.Clamp(0, -10, 10)));

            skeleton.SetPositionRelative(leftShoulderHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -10, 10),
                                             Mathf.Clamp((umaDna.upperMuscle - 0.5f) * -0.0235f, -0.025f, 0.015f),
                                             Mathf.Clamp(0, -10, 10)));
            skeleton.SetPositionRelative(rightShoulderHash,
                                         new Vector3(
                                             Mathf.Clamp(0, -10, 10),
                                             Mathf.Clamp((umaDna.upperMuscle - 0.5f) * 0.0235f, -0.015f, 0.025f),
                                             Mathf.Clamp(0, -10, 10)));

            skeleton.SetScale(mandibleHash,
                              new Vector3(
                                  Mathf.Clamp(1 + (umaDna.mandibleSize - 0.5f) * 0.35f, 0.35f, 1.35f),
                                  Mathf.Clamp(1 + (umaDna.mandibleSize - 0.5f) * 0.35f, 0.35f, 1.35f),
                                  Mathf.Clamp(1 + (umaDna.mandibleSize - 0.5f) * 0.35f, 0.35f, 1.35f)));

            float raceHeight = umaData.umaRecipe.raceData.raceHeight;
            float raceRadius = umaData.umaRecipe.raceData.raceRadius;
            float raceMass   = umaData.umaRecipe.raceData.raceMass;

            umaData.characterHeight = raceHeight * overallScale * (0.425f + 0.6f * lowerBackScale) + ((umaDna.feetSize - 0.5f) * 0.20f);
            umaData.characterRadius = raceRadius + ((umaDna.height - 0.5f) * 0.32f) + ((umaDna.upperMuscle - 0.5f) * 0.01f);
            umaData.characterMass   = raceMass * overallScale + 28f * umaDna.upperWeight + 22f * umaDna.lowerWeight;
        }