public void SetSlaveActive(bool active) { if (active) { // Teleport model.slave.wrist.transformRef.position = model.master.wrist.transformRef.position; model.slave.wrist.transformRef.rotation = model.master.wrist.transformRef.rotation; // Physics PhysHelpers.SetHandPhysics(model, active); // Module HandPhysicsHandler handPhysics = BasicHelpers.FindHandler <HandPhysicsHandler>(model.relatedHandlers.ToArray()); handPhysics.viewModel.isActive = active; } else { // Module HandPhysicsHandler handPhysics = BasicHelpers.FindHandler <HandPhysicsHandler>(model.relatedHandlers.ToArray()); handPhysics.viewModel.isActive = active; // Physics PhysHelpers.SetHandPhysics(model, active); } // Visuals model.slave.skinnedMR.enabled = active; }
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); } } }
private void Start() { model.proxyHand.relatedHandlers.Add(this); slaveBones = AvatarHelpers.GetSlaveHandBones(model.proxyHand.slave); // Ignore palm-finger collisions for (int i = 0; i < slaveBones.Length; i++) { if (!slaveBones[i].colliderRef) { continue; } Physics.IgnoreCollision((model.proxyHand.slave.wrist as SlaveBoneModel).colliderRef, slaveBones[i].colliderRef, true); } // Set default configuration if needed if (model.configuration == null) { model.configuration = core.model.defaultHandPhysicsConfiguration; } for (int i = 0; i < slaveBones.Length; i++) { if (!slaveBones[i].jointRef) { continue; } // Get initial connected body local rotations if (slaveBones[i].jointRef.connectedBody != null) { slaveBones[i].initialConnectedBodyLocalRotation = slaveBones[i].jointRef.connectedBody.transform.localRotation; } else { slaveBones[i].initialConnectedBodyLocalRotation = slaveBones[i].jointRef.transform.rotation; } // Set initial joint configurations if (slaveBones[i] == model.proxyHand.slave.wrist) { PhysHelpers.SetSlaveBoneConfiguration(slaveBones[i].jointRef, model.configuration.wrist); } else if (slaveBones[i].isSpecial) { PhysHelpers.SetSlaveBoneConfiguration(slaveBones[i].jointRef, model.configuration.specials); } else { PhysHelpers.SetSlaveBoneConfiguration(slaveBones[i].jointRef, model.configuration.fingers); } slaveBones[i].rigidbodyRef.maxDepenetrationVelocity = model.configuration.fingers.maxLinearVelocity; slaveBones[i].rigidbodyRef.maxAngularVelocity = model.configuration.fingers.maxAngularVelocity; } }
IEnumerator RecoverFromError() { PhysHelpers.SetCollisionDetectionForBones(model.proxyHand.slave, false); yield return(new WaitForSeconds(1.0f)); PhysHelpers.SetCollisionDetectionForBones(model.proxyHand.slave, true); }
private void Update() { if (!model.isActive) { return; } if (model.proxyHand.error > core.model.configuration.maxErrorAllowed && !decoupled) { StartCoroutine(RecoverFromError()); } for (int i = 0; i < slaveBones.Length; i++) { if (model.updateConfFromScale) { model.configuration.fingers.positionDrive = CustomJointDrive.ScaledCopy(model.asset.configuration.fingers.positionDrive, model.proxyHand.slave.extraScale); model.configuration.fingers.rotationDrive = CustomJointDrive.ScaledCopy(model.asset.configuration.fingers.rotationDrive, model.proxyHand.slave.extraScale); model.configuration.fingers.rigidbodyMass = model.asset.configuration.fingers.rigidbodyMass * model.proxyHand.slave.extraScale; model.configuration.wrist.positionDrive = CustomJointDrive.ScaledCopy(model.asset.configuration.wrist.positionDrive, model.proxyHand.slave.extraScale); model.configuration.wrist.rotationDrive = CustomJointDrive.ScaledCopy(model.asset.configuration.wrist.rotationDrive, model.proxyHand.slave.extraScale); model.configuration.wrist.rigidbodyMass = model.asset.configuration.wrist.rigidbodyMass * model.proxyHand.slave.extraScale; model.configuration.specials.positionDrive = CustomJointDrive.ScaledCopy(model.asset.configuration.specials.positionDrive, model.proxyHand.slave.extraScale); model.configuration.specials.rotationDrive = CustomJointDrive.ScaledCopy(model.asset.configuration.specials.rotationDrive, model.proxyHand.slave.extraScale); model.configuration.specials.rigidbodyMass = model.asset.configuration.specials.rigidbodyMass * model.proxyHand.slave.extraScale; } if (model.applyConfOnUpdate && slaveBones[i].jointRef) { // Update joint configurations if (slaveBones[i] == model.proxyHand.slave.wrist) { PhysHelpers.SetSlaveBoneConfiguration(slaveBones[i].jointRef, model.configuration.wrist); } else if (slaveBones[i].isSpecial) { PhysHelpers.SetSlaveBoneConfiguration(slaveBones[i].jointRef, model.configuration.specials); } else { PhysHelpers.SetSlaveBoneConfiguration(slaveBones[i].jointRef, model.configuration.fingers); } // Update built-in velocity clamps slaveBones[i].rigidbodyRef.maxDepenetrationVelocity = model.configuration.fingers.maxLinearVelocity; slaveBones[i].rigidbodyRef.maxAngularVelocity = model.configuration.fingers.maxAngularVelocity; // NO-PROD if (slaveBones[i].jointRef.connectedBody) { slaveBones[i].jointRef.connectedAnchor = slaveBones[i].initialConnectedAnchor; } } } }
private void Start() { model.proxyHand.relatedHandlers.Add(this); slaveBones = AvatarHelpers.GetSlaveHandBones(model.proxyHand.slave); // Set default configuration if needed if (model.asset == null) { model.asset = BasicHelpers.FindScriptableObject <HandPhysicsConfigurationAsset>(core.model.defaultConfAssets); } // Make configuration editable model.configuration = new HandPhysicsConfiguration(model.asset.configuration); for (int i = 0; i < slaveBones.Length; i++) { if (slaveBones[i].colliderRef) { // Ignore palm-finger collisions Physics.IgnoreCollision((model.proxyHand.slave.wrist as SlaveBoneModel).colliderRef, slaveBones[i].colliderRef, true); } if (slaveBones[i].jointRef) { // Get initial connected body local rotations and conn anchors if (slaveBones[i].jointRef.connectedBody != null) { slaveBones[i].initialConnectedBodyLocalRotation = slaveBones[i].jointRef.connectedBody.transform.localRotation; slaveBones[i].initialConnectedAnchor = slaveBones[i].jointRef.connectedAnchor; slaveBones[i].jointRef.autoConfigureConnectedAnchor = false; } else { slaveBones[i].initialConnectedBodyLocalRotation = slaveBones[i].jointRef.transform.rotation; } // Set initial joint configurations if (slaveBones[i] == model.proxyHand.slave.wrist) { PhysHelpers.SetSlaveBoneConfiguration(slaveBones[i].jointRef, model.configuration.wrist); } else if (slaveBones[i].isSpecial) { PhysHelpers.SetSlaveBoneConfiguration(slaveBones[i].jointRef, model.configuration.specials); } else { PhysHelpers.SetSlaveBoneConfiguration(slaveBones[i].jointRef, model.configuration.fingers); } // Initial built-in velocity clamps slaveBones[i].rigidbodyRef.maxDepenetrationVelocity = model.configuration.fingers.maxLinearVelocity; slaveBones[i].rigidbodyRef.maxAngularVelocity = model.configuration.fingers.maxAngularVelocity; } } }
public void Respawn(Rigidbody rb, Respawnable respawnable) { if (respawnable == null) { return; } respawning.Add(rb); rb.detectCollisions = false; Transform[] parents = new Transform[respawnable.attachedRbs.Length]; for (int i = 0; i < respawnable.attachedRbs.Length; i++) { respawnable.attachedRbs[i].detectCollisions = false; parents[i] = respawnable.attachedRbs[i].transform.parent; respawnable.attachedRbs[i].transform.parent = respawnable.transform; } rb.transform.position = respawnable.initialPosition; rb.transform.rotation = respawnable.initialRotation; StartCoroutine(PhysHelpers.DoAfterFixedUpdate(() => { for (int i = 0; i < respawnable.attachedRbs.Length; i++) { respawnable.attachedRbs[i].transform.parent = parents[i]; respawnable.attachedRbs[i].detectCollisions = true; respawnable.attachedRbs[i].velocity = Vector3.zero; respawnable.attachedRbs[i].angularVelocity = Vector3.zero; } int index = respawning.IndexOf(rb); respawning[index].detectCollisions = true; respawning[index].velocity = Vector3.zero; respawning[index].angularVelocity = Vector3.zero; respawning.RemoveAt(index); })); }
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); } }
private void Start() { StartCoroutine(PhysHelpers.DoAfter(waitFor, () => { Find(); })); }
void UpdateJoint(TargetConstraint t, bool editMode) { if (editMode) { // Connected body/anchor if (t.connectedBody) { t.joint.connectedBody = t.connectedBody; } else { t.joint.connectedBody = null; } // Freedom SetPositionLock(t.joint, t.settings.linearMotion); SetRotationLock(t.joint, t.settings.angularMotion); // Drives if (gradualMode) { PhysHelpers.UpdateJointMotionDrive(t.joint, PhysHelpers.JointDriveLerp(new JointDrive(), t.settings.motionDrive.toJointDrive(), t.gradualLerp)); PhysHelpers.UpdateJointAngularDrive(t.joint, PhysHelpers.JointDriveLerp(new JointDrive(), t.settings.angularDrive.toJointDrive(), t.gradualLerp)); } else { PhysHelpers.UpdateJointMotionDrive(t.joint, t.settings.motionDrive.toJointDrive()); PhysHelpers.UpdateJointAngularDrive(t.joint, t.settings.angularDrive.toJointDrive()); } // Control t.joint.enableCollision = t.settings.collideWithConnectedRb; // Prevent modification t.joint.configuredInWorldSpace = !t.keepAxisRelativeToObject; } if (!t.setAxisWhenEnabled) { t.joint.autoConfigureConnectedAnchor = false; // Called every frame } // Connected body/anchor if (t.connectedBody) { t.tmpConnAnchor = t.joint.connectedBody.transform.InverseTransformPoint(t.connectedAnchor.position); } else { t.tmpConnAnchor = t.connectedAnchor.position; } if (t.joint.connectedAnchor != t.tmpConnAnchor) { t.joint.connectedAnchor = t.tmpConnAnchor; } // Target rotation t.jointFrameRotation = t.GetJointAxisWorldRotation(); Quaternion resultRotation = Quaternion.Inverse(t.jointFrameRotation); resultRotation *= t.anchor.rotation; resultRotation *= Quaternion.Inverse(t.connectedAnchor.rotation); resultRotation *= t.jointFrameRotation; t.joint.targetRotation = resultRotation; // Target position if (t.targetPosition) { t.tmpTargetPos = -1.0f * t.axis.InverseTransformPoint(t.targetPosition.position); if (t.connectedBody) { t.joint.targetPosition = Vector3.Scale(t.tmpTargetPos, t.connectedBody.transform.localScale); } else { t.joint.targetPosition = t.tmpTargetPos; } } else if (t.joint.targetPosition != Vector3.zero) { t.joint.targetPosition = Vector3.zero; } // Update flag if (!t.updated) { t.updated = true; } // Debug if (t.showAxis) { Debug.DrawLine(t.axis.position, t.axis.position + t.GetJointAxisWorldRotation() * Vector3.forward * 0.5f, Color.blue); } }