void Init() { _avatar = GetComponent <DynamicCharacterAvatar>(); if (_avatar == null) { return; } _dna = _avatar.GetDNA(); _initialized = false; _skeleton = GetSkeleton(_avatar.activeRace.name); //Check if current skeleton is supported by jigglebone recipe and only run this code if the avatar has changed if (_skeleton != "other" && _currentAvatar != _avatar.activeRace.name) { _jigglers.Clear(); _currentAvatar = _avatar.activeRace.name; _renderer = GetComponentInChildren <SkinnedMeshRenderer>(); foreach (Transform bone in _renderer.bones) { //we are seeking by bone names so need the corresponding bone name from our supported skeletons if (bone.name == "LeftGluteus" || bone.name == "RightGluteus" || bone.name == "GluteusAdjust_L" || bone.name == "GluteusAdjust_R") { _jiggler = new JiggleElement(); _jigglers.Add(_jiggler); _jiggler.Bone = bone; _jiggler.BoneType = "butt"; _jiggler.BoneAxis = new Vector3(0, 0, -1); if (bone.name == "LeftGluteus" || bone.name == "RightGluteus") { _jiggler.UpDirection = new Vector3(1, 0, 0); _jiggler.ExtraRotation = _gender == "female" ? new Vector3(-67, 180, -90) : new Vector3(20, 45, -90); //Note male and female need different butt rotations. } else if (bone.name == "GluteusAdjust_L" || bone.name == "GluteusAdjust_R") { _jiggler.UpDirection = new Vector3(-1, 0, 0); _jiggler.ExtraRotation = new Vector3(-90, 0, 90); } UpdateJiggleBone(_jiggler); } } if (_jigglers.Count > 0) { _initialized = true; } } else if (_skeleton != "other") { for (int i = 0; i < _jigglers.Count; i++) { UpdateJiggleBone(_jigglers[i]); } _initialized = true; } }
void Init() { _avatar = GetComponent <DynamicCharacterAvatar>(); if (_avatar == null) { return; } _dna = _avatar.GetDNA(); _initialized = false; _skeleton = GetSkeleton(_avatar.activeRace.name); //Check if current skeleton is supported by jigglebone recipe and only run this code if the avatar has changed if (_skeleton != "other" && _currentAvatar != _avatar.activeRace.name) { _jigglers.Clear(); _currentAvatar = _avatar.activeRace.name; _renderer = GetComponentInChildren <SkinnedMeshRenderer>(); foreach (Transform bone in _renderer.bones) { //we are seeking by bone names so need the corresponding bone name from our supported skeletons if (bone.name == "LeftOuterBreast" || bone.name == "RightOuterBreast" || bone.name == "PectoralAdjust_L" || bone.name == "PectoralAdjust_R") { _jiggler = new JiggleElement(); _jigglers.Add(_jiggler); _jiggler.Bone = bone; _jiggler.BoneType = "breast"; //_jiggler.ExtraRotation.y = _jiggler.Bone.name == "LeftInnerBreast" ? 5 : -5; if (_skeleton == "Standard") { _jiggler.ExtraRotation = new Vector3(70, 0, -104); _jiggler.ExtraRotation.z = _jiggler.Bone.name == "LeftOuterBreast" ? -76 : -104; } else if (_skeleton == "o3n") { _jiggler.ExtraRotation = bone.name == "PectoralAdjust_L" ? new Vector3(45, 0, -67) : new Vector3(45, 0, -113); } UpdateJiggleBone(_jiggler); } } if (_jigglers.Count > 0) { _initialized = true; } } else if (_skeleton != "other") { for (int i = 0; i < _jigglers.Count; i++) { UpdateJiggleBone(_jigglers[i]); } _initialized = true; } }
public void UpdateJiggleBone(JiggleElement jiggler) { if (jiggler.Bone.name == "LeftGluteus" || jiggler.Bone.name == "RightGluteus" || jiggler.Bone.name == "GluteusAdjust_L" || jiggler.Bone.name == "GluteusAdjust_R") { jiggler.Stiffness = _buttStiffness; jiggler.Mass = _buttMass; jiggler.Damping = _buttDamping; jiggler.Gravity = _buttGravity; jiggler.SquashAndStretch = _buttSquashAndStretch; jiggler.FrontStretch = _buttFrontStretch; jiggler.SideStretch = _buttSideStretch; jiggler.AnatomyScaleFactor = _dna["gluteusSize"].Get() * 2; InitializeBone(_jiggler); } }
public void UpdateJiggleBone(JiggleElement jiggler) { if (jiggler.Bone.name == "LeftOuterBreast" || jiggler.Bone.name == "RightOuterBreast" || jiggler.Bone.name == "PectoralAdjust_L" || jiggler.Bone.name == "PectoralAdjust_R") { jiggler.Stiffness = _breastStiffness; jiggler.Mass = _breastMass; jiggler.Damping = _breastDamping; jiggler.Gravity = _breastGravity; jiggler.SquashAndStretch = _breastSquashAndStretch; jiggler.FrontStretch = _breastFrontStretch; jiggler.SideStretch = _breastSideStretch; jiggler.AnatomyScaleFactor = _dna["breastSize"].Get() * 2; InitializeBone(_jiggler); } }
private void MonitorJiggling(JiggleElement jiggler) { //Get variables - only really need to set these if we have deviated from the defaults _monitoredBone = jiggler.Bone; _boneAxis = jiggler.BoneAxis; _upDirection = jiggler.UpDirection; _extraRotation = jiggler.ExtraRotation; _stiffness = jiggler.Stiffness; _mass = jiggler.Mass; _damping = jiggler.Damping; _gravity = jiggler.Gravity; _force = jiggler.Force; _velocity = jiggler.Velocity; _acceleration = jiggler.Acceleration; _dynamicPos = jiggler.DynamicPosition; // Reset the bone rotation so we can recalculate the upVector and forwardVector _monitoredBone.rotation = new Quaternion(); //transform.localRotation = originalQuat; // Update forwardVector and upVector Vector3 upVector = _monitoredBone.TransformDirection(_upDirection); // Calculate target position _targetPos = _monitoredBone.position + _monitoredBone.TransformDirection(new Vector3((_boneAxis.x * _targetDistance), (_boneAxis.y * _targetDistance), (_boneAxis.z * _targetDistance))); // Calculate force, acceleration, and velocity per X, Y and Z _force.x = (_targetPos.x - _dynamicPos.x) * _stiffness; _acceleration.x = _force.x / _mass; _velocity.x += _acceleration.x * (1 - _damping); _force.y = (_targetPos.y - _dynamicPos.y) * _stiffness; _force.y -= _gravity / 10; // Add some gravity _acceleration.y = _force.y / _mass; _velocity.y += _acceleration.y * (1 - _damping); _force.z = (_targetPos.z - _dynamicPos.z) * _stiffness; _acceleration.z = _force.z / _mass; _velocity.z += _acceleration.z * (1 - _damping); // Update dynamic postion _dynamicPos += _velocity + _force; jiggler.DynamicPosition = _dynamicPos; jiggler.Force = _force; jiggler.Acceleration = _acceleration; jiggler.Velocity = _velocity; // Set bone rotation to look at dynamicPos _monitoredBone.LookAt(_dynamicPos, upVector); //Apply extra rotation _monitoredBone.Rotate(_extraRotation, Space.Self); // ================================================== // Squash and Stretch section // ================================================== if (jiggler.SquashAndStretch) { // Create a vector from target position to dynamic position // We will measure the magnitude of the vector to determine // how much squash and stretch we will apply Vector3 dynamicVec = _dynamicPos - _targetPos; // Get the magnitude of the vector float stretchMag = dynamicVec.magnitude; // Here we determine the amount of squash and stretch based on stretchMag // and the direction the Bone Axis is pointed in. Ideally there should be // a vector with two values at 0 and one at 1. Like Vector3(0,0,1) // for the 0 values, we assume those are the sides, and 1 is the direction // the bone is facing float xStretch; float yStretch; float zStretch; if (_boneAxis.x == 0) { xStretch = 1 + (-stretchMag * _sideStretch); } else { xStretch = 1 + (stretchMag * _frontStretch); } if (_boneAxis.y == 0) { yStretch = 1 + (-stretchMag * _sideStretch); } else { yStretch = 1 + (stretchMag * _frontStretch); } if (_boneAxis.z == 0) { zStretch = 1 + (-stretchMag * _sideStretch); } else { zStretch = 1 + (stretchMag * _frontStretch); } // Set the bone scale _anatomyScaleFactor = jiggler.AnatomyScaleFactor; _monitoredBone.localScale = new Vector3(xStretch, yStretch, zStretch) * _anatomyScaleFactor; } }
void InitializeBone(JiggleElement jiggler) { Vector3 targetPos = jiggler.Bone.position + jiggler.Bone.TransformDirection(new Vector3((jiggler.BoneAxis.x * _targetDistance), (jiggler.BoneAxis.y * _targetDistance), (jiggler.BoneAxis.z * _targetDistance))); jiggler.DynamicPosition = targetPos; }