public void SetDecoupledMode(bool newDecoupled) { if (decoupled == newDecoupled) { return; } SlaveBoneConfiguration newConf; if (decoupled) { newConf = new SlaveBoneConfiguration(model.configuration.wrist); newConf.followsPosition = false; newConf.followsRotation = false; newConf.useGravity = true; } else { newConf = model.configuration.wrist; } for (int i = 0; i < slaveBones.Length; i++) { if (!slaveBones[i].jointRef) { continue; } if (slaveBones[i] == model.proxyHand.slave.wrist) { PhysHelpers.SetSlaveBoneConfiguration(slaveBones[i].jointRef, newConf); } } }
public static void SetSlaveBoneConfiguration(ConfigurableJoint joint, SlaveBoneConfiguration conf) { Rigidbody rb = joint.GetComponent <Rigidbody>(); rb.mass = conf.rigidbodyMass; rb.drag = conf.rigidbodyDrag; rb.angularDrag = conf.rigidbodyAngularDrag; rb.useGravity = conf.useGravity; if (conf.followsRotation) { joint.angularXDrive = conf.rotationDrive.toJointDrive(); joint.angularYZDrive = conf.rotationDrive.toJointDrive(); joint.slerpDrive = conf.rotationDrive.toJointDrive(); } else { joint.angularXDrive = CustomJointDrive.zero.toJointDrive(); joint.angularYZDrive = CustomJointDrive.zero.toJointDrive(); joint.slerpDrive = CustomJointDrive.zero.toJointDrive(); } if (conf.useTargetPos) { joint.xDrive = conf.positionDrive.toJointDrive(); joint.yDrive = conf.positionDrive.toJointDrive(); joint.zDrive = conf.positionDrive.toJointDrive(); } else { joint.xDrive = CustomJointDrive.zero.toJointDrive(); joint.yDrive = CustomJointDrive.zero.toJointDrive(); joint.zDrive = CustomJointDrive.zero.toJointDrive(); } joint.massScale = conf.jointMassScale; joint.connectedMassScale = conf.jointConnectedMassScale; }
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); } }