Exemple #1
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);
                }
            }
        }
Exemple #2
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;
            }
        }