public NVRAlignment SnapToNearest(Vector3 position, float maxSnapDistance) { NVRAlignment startingAlignment = new NVRAlignment(position, transform.rotation, transform.localScale); NVRAlignment newAlignment = startingAlignment; float bestAlignmentDistance = float.MaxValue; Bounds ourBounds = GetBounds(); foreach (NVRSnappable snappable in snappables) { if (snappable != this) { Bounds snapToBounds = snappable.GetBounds(); NVRAlignment alignment = SnapToBounds(position, snapToBounds); Vector3 bottomOfSnappable = new Vector3(position.x, ourBounds.min.y, position.z); float alignmentDistance = Mathf.Max(Vector3.Distance(bottomOfSnappable, snapToBounds.ClosestPoint(bottomOfSnappable)), startingAlignment.Distance(alignment)); if (alignmentDistance < bestAlignmentDistance && alignmentDistance <= maxSnapDistance) { newAlignment = alignment; bestAlignmentDistance = alignmentDistance; } } } return(newAlignment); }
public float Distance(NVRAlignment alignment) { float distance = 0; distance += Vector3.Distance(position, alignment.position); distance += (Quaternion.Angle(rotation, alignment.rotation) / 90) * scale.x; return(distance); }
public NVRAlignment SnapToBounds(Vector3 position, Bounds snappingBounds) { NVRAlignment alignment = new NVRAlignment(position, transform.rotation, transform.localScale); Bounds mybounds = GetBounds(); Vector3 boundsOffset = transform.position - mybounds.center; alignment.position.y = snappingBounds.center.y + snappingBounds.extents.y + mybounds.extents.y + boundsOffset.y; return(alignment); }
protected override void UpdateVelocities() { foreach (var hand in AttachedHands) { if (hand.UseButtonDown) { snap = !snap; break; } } Vector3 targetItemPosition; Quaternion targetItemRotation; Vector3 targetHandPosition; Quaternion targetHandRotation; GetTargetValues(out targetHandPosition, out targetHandRotation, out targetItemPosition, out targetItemRotation); float velocityMagic = VelocityMagic / (Time.deltaTime / NVRPlayer.NewtonVRExpectedDeltaTime); float angularVelocityMagic = AngularVelocityMagic / (Time.deltaTime / NVRPlayer.NewtonVRExpectedDeltaTime); // Snap position if (snappingType == positionalSnapping.objects) { NVRAlignment targetAlignment = snappable.SnapToNearest(targetHandPosition, .1f); if (targetAlignment == null) { return; } targetHandPosition = targetAlignment.position; Vector3 positionDelta = (targetHandPosition - targetItemPosition); Vector3 velocityTarget = (positionDelta * velocityMagic) * Time.deltaTime; if (float.IsNaN(velocityTarget.x) == false) { this.Rigidbody.velocity = Vector3.MoveTowards(this.Rigidbody.velocity, velocityTarget, MaxVelocityChange); } } if (snappingType == positionalSnapping.grid && snap) { targetHandPosition = SnapPosition(targetHandPosition); Vector3 positionDelta = (targetHandPosition - targetItemPosition); Vector3 velocityTarget = (positionDelta * velocityMagic) * Time.deltaTime; if (float.IsNaN(velocityTarget.x) == false) { this.Rigidbody.velocity = Vector3.MoveTowards(this.Rigidbody.velocity, velocityTarget, MaxVelocityChange); } } // Snap to nearest degrees if (snap) { targetHandRotation = SnapRotation(targetHandRotation); } Quaternion rotationDelta = targetHandRotation * Quaternion.Inverse(targetItemRotation); float angle; Vector3 axis; rotationDelta.ToAngleAxis(out angle, out axis); if (angle > 180) { angle -= 360; } if (angle != 0) { Vector3 angularTarget = angle * axis; if (float.IsNaN(angularTarget.x) == false) { angularTarget = (angularTarget * angularVelocityMagic) * Time.deltaTime; this.Rigidbody.angularVelocity = Vector3.MoveTowards(this.Rigidbody.angularVelocity, angularTarget, MaxAngularVelocityChange); } } if (VelocityHistory != null) { CurrentVelocityHistoryStep++; if (CurrentVelocityHistoryStep >= VelocityHistory.Length) { CurrentVelocityHistoryStep = 0; } VelocityHistory[CurrentVelocityHistoryStep] = this.Rigidbody.velocity; AngularVelocityHistory[CurrentVelocityHistoryStep] = this.Rigidbody.angularVelocity; } }