private void FixedUpdate() { if (!model.isActive) { return; } UpdateSlaveBone(model.proxyHand.slave.wrist as SlaveBoneModel, Space.World, model.configuration.wrist); for (int f = 0; f < model.proxyHand.slave.fingers.Length; f++) { for (int b = 0; b < model.proxyHand.slave.fingers[f].bones.Length; b++) { slaveBone = model.proxyHand.slave.fingers[f].bones[b] as SlaveBoneModel; if (slaveBone.isSpecial) { UpdateSlaveBone(slaveBone, Space.Self, model.configuration.specials); } else { UpdateSlaveBone(slaveBone, Space.Self, model.configuration.fingers); } } } }
private void FixedUpdate() { if ((model.proxyHand.slave.wrist as SlaveBoneModel).masterBone.offset != null) { masterWristDestination = (model.proxyHand.slave.wrist as SlaveBoneModel).masterBone.offset; } else { masterWristDestination = (model.proxyHand.slave.wrist as SlaveBoneModel).masterBone.transformRef; } UpdateSlaveBone(model.proxyHand.slave.wrist as SlaveBoneModel, masterWristDestination, Space.World, model.configuration.wrist); for (int f = 0; f < model.proxyHand.slave.fingers.Length; f++) { for (int b = 0; b < model.proxyHand.slave.fingers[f].bones.Length; b++) { slaveBone = model.proxyHand.slave.fingers[f].bones[b] as SlaveBoneModel; if (slaveBone.isSpecial) { UpdateSlaveBone(slaveBone, slaveBone.masterBone.transformRef, Space.Self, model.configuration.specials); } else { UpdateSlaveBone(slaveBone, slaveBone.masterBone.transformRef, Space.Self, model.configuration.fingers); } } } }
public static void UpdateBoneStrength(SlaveBoneModel bone, JointDrive minJointDrive, JointDrive maxJointDrive, float strength) { JointDrive updatedJointDrive = new JointDrive(); updatedJointDrive.positionSpring = Mathf.Lerp(minJointDrive.positionSpring, maxJointDrive.positionSpring, strength); updatedJointDrive.positionDamper = Mathf.Lerp(minJointDrive.positionDamper, maxJointDrive.positionDamper, strength); updatedJointDrive.maximumForce = Mathf.Lerp(minJointDrive.maximumForce, maxJointDrive.maximumForce, strength); bone.jointRef.angularXDrive = updatedJointDrive; bone.jointRef.angularYZDrive = updatedJointDrive; bone.jointRef.slerpDrive = updatedJointDrive; }
public static void SetBonePhysics(SlaveBoneModel bone, bool enabled) { if (bone.rigidbodyRef) { bone.rigidbodyRef.isKinematic = !enabled; } if (bone.colliderRef) { bone.colliderRef.enabled = enabled; } }
public static void SetHandPhysics(ProxyHandModel phModel, bool enabled) { SlaveBoneModel wristBone = phModel.slave.wrist as SlaveBoneModel; SetBonePhysics(wristBone, enabled); for (int f = 0; f < phModel.slave.fingers.Length; f++) { for (int b = 0; b < phModel.slave.fingers[f].bones.Length; b++) { SlaveBoneModel slaveBone = phModel.slave.fingers[f].bones[b] as SlaveBoneModel; SetBonePhysics(slaveBone, enabled); } } }
private void FixedUpdate() { UpdateSlaveBone(model.proxyHand.slave.wrist as SlaveBoneModel, model.proxyHand.master.wrist.transformRef, Space.World, model.configuration.wrist); for (int i = 0; i < model.proxyHand.slave.fingers.Length; i++) { for (int j = 0; j < model.proxyHand.slave.fingers[i].bones.Length; j++) { slaveBone = model.proxyHand.slave.fingers[i].bones[j] as SlaveBoneModel; if (slaveBone.isSpecial) { UpdateSlaveBone(slaveBone, model.proxyHand.master.fingers[i].bones[j].transformRef, Space.Self, model.configuration.specials); } else { UpdateSlaveBone(slaveBone, model.proxyHand.master.fingers[i].bones[j].transformRef, Space.Self, model.configuration.fingers); } } } }
public static void SetBonePhysics(SlaveBoneModel bone, bool enabled) { if (bone.rigidbodyRef) { if (bone.rigidbodyRef.isKinematic) { bone.rigidbodyRef.isKinematic = false; bone.rigidbodyRef.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic; } else { bone.rigidbodyRef.collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative; bone.rigidbodyRef.isKinematic = true; } } if (bone.colliderRef) { bone.colliderRef.enabled = enabled; } }
public static void IgnoreBoneCollisions(Rigidbody rb, SlaveBoneModel bone, bool ignore, bool includeRbGroup) { if (!bone.colliderRef) { return; } List <Collider> rbColliders = new List <Collider>(rb.GetComponentsInChildren <Collider>()); RigidbodyGroup rbGroup = rb.GetComponent <RigidbodyGroup>(); if (rbGroup && includeRbGroup) { for (int i = 0; i < rbGroup.rigidbodies.Length; i++) { rbColliders.AddRange(GetColliders(rbGroup.rigidbodies[i])); } } for (int i = 0; i < rbColliders.Count; i++) { Physics.IgnoreCollision(rbColliders[i], bone.colliderRef, ignore); } }
private void UpdateSlaveBone(SlaveBoneModel slaveBone, Transform master, Space space, SlaveBoneConfiguration boneConf) { if (!slaveBone.jointRef) { return; } if (boneConf.followsPosition) { if (boneConf.useTargetPos) { if (space == Space.Self && slaveBone.jointRef.configuredInWorldSpace) { Debug.LogError(slaveBone.name + " is configured in world space. You can't use local position as target position here"); } if (space == Space.World && !slaveBone.jointRef.configuredInWorldSpace) { Debug.LogError(slaveBone.name + " is configured in local space. You can't use world position as target position here"); } Vector3 desiredWorldPosition = PhysHelpers.GetDesiredWorldPos(slaveBone.transformRef, master, space); if (slaveBone.jointRef.configuredInWorldSpace) { slaveBone.jointRef.connectedAnchor = desiredWorldPosition; } else { slaveBone.jointRef.connectedAnchor = slaveBone.jointRef.connectedBody.transform.InverseTransformPoint(desiredWorldPosition); } } else { // Position Vector3 desiredPosition = PhysHelpers.GetDesiredWorldPos(slaveBone.transformRef, master, space); // Velocity Vector3 newVelocity = (desiredPosition - slaveBone.transformRef.position) / Time.fixedDeltaTime; slaveBone.rigidbodyRef.velocity = newVelocity; } } if (boneConf.followsRotation) { // Error logs if (space == Space.Self && slaveBone.jointRef.configuredInWorldSpace) { Debug.LogError(slaveBone.name + " is configured in world space. You can't use local rotation as target rotation here"); } if (space == Space.World && !slaveBone.jointRef.configuredInWorldSpace) { Debug.LogError(slaveBone.name + " is configured in local space. You can't use world rotation as target rotation here"); } if (space == Space.Self) { Quaternion clampedLocalRot = master.localRotation; if (slaveBone.minLocalRot.eulerAngles.z > 180.0f /* && * master.localRotation.eulerAngles.z < slaveBone.minLocalRot.eulerAngles.z*/) { clampedLocalRot = slaveBone.minLocalRot; } ConfigurableJointExtensions.SetTargetRotationLocal(slaveBone.jointRef, clampedLocalRot, slaveBone.initialConnectedBodyLocalRotation); } else { Quaternion worldToJointSpace = ConfigurableJointExtensions.GetWorldToJointSpace(slaveBone.jointRef); Quaternion jointSpaceToWorld = Quaternion.Inverse(worldToJointSpace); Quaternion resultRotation = ConfigurableJointExtensions.GetWorldResultRotation(slaveBone.jointRef, master.rotation, slaveBone.initialConnectedBodyLocalRotation, space, jointSpaceToWorld); // Transform back into joint space resultRotation *= worldToJointSpace; // Set target rotation to our newly calculated rotation slaveBone.jointRef.targetRotation = resultRotation; } // Local rotation offset slaveBone.jointRef.targetRotation *= Quaternion.Euler(slaveBone.targetEulerOffsetRot); if (boneConf.useDynamicStrength) { PhysHelpers.UpdateBoneStrength(slaveBone, boneConf.minDynamicRotDrive.toJointDrive(), boneConf.maxDynamicRotDrive.toJointDrive(), slaveBone.finger.strengthLerp); } } if (boneConf.clampLinearVelocity) { slaveBone.rigidbodyRef.velocity = Vector3.ClampMagnitude(slaveBone.rigidbodyRef.velocity, boneConf.maxLinearVelocity); } if (boneConf.clampAngularVelocity) { slaveBone.rigidbodyRef.angularVelocity = Vector3.ClampMagnitude(slaveBone.rigidbodyRef.angularVelocity, boneConf.maxAngularVelocity); } }
void SetupSlaveHandModel(SlaveHandModel handModel, Transform slaveWrist) { // CustomHand > [Modules] > ProxyHandModule > ProxyHandModel > Slave > Wrist GameObject wristBoneModelObj = BasicHelpers.InstantiateEmptyChild(handModel.gameObject); wristBoneModelObj.name = "Wrist"; SlaveBoneModel wristBone = wristBoneModelObj.AddComponent <SlaveBoneModel>(); wristBone.transformRef = slaveWrist; handModel.wrist = wristBone; /* SLAVE BONE MODEL SPECIFIC */ wristBone.masterBone = handModel.proxyHand.master.wrist as MasterBoneModel; /* */ // Set SkinnedMR handModel.skinnedMR = slaveWrist.GetComponent <SkinnedMeshRenderer>(); List <FingerModel> fingers = new List <FingerModel>(); int f = 0; for (int i = 0; i < slaveWrist.childCount; i++) { // If childCount is 0, then it's not a finger if (slaveWrist.GetChild(i).childCount == 0) { continue; } // CustomHand > [Modules] > ProxyHandModule > ProxyHandModel > Slave > Finger GameObject fingerModelObj = BasicHelpers.InstantiateEmptyChild(handModel.gameObject); fingerModelObj.name = "Finger" + f; FingerModel fingerModel = fingerModelObj.AddComponent <FingerModel>(); List <BoneModel> bones = new List <BoneModel>(); Transform[] fingerTransforms = GetFingerTransforms(slaveWrist.GetChild(i)); for (int b = 0; b < fingerTransforms.Length; b++) { if (fingerTransforms[b].childCount == 0) { fingerModel.fingerTip = fingerTransforms[b]; continue; } // CustomHand > [Modules] > ProxyHandModule > ProxyHandModel > Slave > Finger > Bone GameObject boneModelObj = BasicHelpers.InstantiateEmptyChild(fingerModelObj); boneModelObj.transform.name = "Bone" + b; SlaveBoneModel slaveBone = boneModelObj.AddComponent <SlaveBoneModel>(); slaveBone.transformRef = fingerTransforms[b]; /* SLAVE BONE MODEL SPECIFIC */ // Simple automatic rig mapping if (handModel.proxyHand.master.fingers[f] != null && handModel.proxyHand.master.fingers[f].bones[b] != null) { slaveBone.masterBone = handModel.proxyHand.master.fingers[f].bones[b] as MasterBoneModel; } /* */ bones.Add(slaveBone); } fingerModel.fingerBase = bones[0].transformRef; fingerModel.distal = bones[bones.Count - 1]; fingerModel.bones = bones.ToArray(); fingers.Add(fingerModel); if (i == indexSiblingIndex) { fingerModel.name = "Index"; handModel.index = fingerModel; } if (i == thumbSiblingIndex) { fingerModel.name = "Thumb"; handModel.thumb = fingerModel; /* SLAVE BONE MODEL SPECIFIC */ // Thumb is usually a finger with special participation in hand physics and grabbign detection for (int b = 0; b < fingerModel.bones.Length; b++) { (fingerModel.bones[b] as SlaveBoneModel).isSpecial = true; } /* */ } // Increase finger counter f++; } handModel.fingers = fingers.ToArray(); }