Advertisement
Guest User

Untitled

a guest
Oct 14th, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 15.14 KB | None | 0 0
  1. /************************************************************************************
  2. Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
  3.  
  4. Licensed under the Oculus Utilities SDK License Version 1.31 (the "License"); you may not use
  5. the Utilities SDK except in compliance with the License, which is provided at the time of installation
  6. or download, or which otherwise accompanies this software in either electronic or hard copy form.
  7.  
  8. You may obtain a copy of the License at
  9. https://developer.oculus.com/licenses/utilities-1.31
  10.  
  11. Unless required by applicable law or agreed to in writing, the Utilities SDK distributed
  12. under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
  13. ANY KIND, either express or implied. See the License for the specific language governing
  14. permissions and limitations under the License.
  15. ************************************************************************************/
  16.  
  17. using System.Collections.Generic;
  18. using UnityEngine;
  19.  
  20. /// <summary>
  21. /// Allows grabbing and throwing of objects with the OVRGrabbable component on them.
  22. /// </summary>
  23. [RequireComponent(typeof(Rigidbody))]
  24. public class OVRGrabber : MonoBehaviour
  25. {
  26.     public Transform part11;
  27.  
  28.     // Grip trigger thresholds for picking up objects, with some hysteresis.
  29.     public float grabBegin = 0.55f;
  30.     public float grabEnd = 0.35f;
  31.  
  32.     //public Rigidbody target;
  33.     public AudioClip hapticClip;
  34.  
  35.  
  36.     // Demonstrates parenting the held object to the hand's transform when grabbed.
  37.     // When false, the grabbed object is moved every FixedUpdate using MovePosition.
  38.     // Note that MovePosition is required for proper physics simulation. If you set this to true, you can
  39.     // easily observe broken physics simulation by, for example, moving the bottom cube of a stacked
  40.     // tower and noting a complete loss of friction.
  41.     [SerializeField]
  42.     protected bool m_parentHeldObject = false;
  43.  
  44.     [Tooltip("Assign controller as a child of grabbed object - just for test purpose")]
  45.     public bool m_childToHeldObject = false;
  46.  
  47.     // Child/attached transforms of the grabber, indicating where to snap held objects to (if you snap them).
  48.     // Also used for ranking grab targets in case of multiple candidates.
  49.     [SerializeField]
  50.     protected Transform m_gripTransform = null;
  51.     // Child/attached Colliders to detect candidate grabbable objects.
  52.     [SerializeField]
  53.     protected Collider[] m_grabVolumes = null;
  54.  
  55.     // Should be OVRInput.Controller.LTouch or OVRInput.Controller.RTouch.
  56.     [SerializeField]
  57.     public OVRInput.Controller m_controller;
  58.  
  59.     [SerializeField]
  60.     protected Transform m_parentTransform;
  61.  
  62.     protected bool m_grabVolumeEnabled = true;
  63.     protected Vector3 m_lastPos;
  64.     protected Quaternion m_lastRot;
  65.     protected Quaternion m_anchorOffsetRotation;
  66.     protected Vector3 m_anchorOffsetPosition;
  67.     protected float m_prevFlex;
  68.     protected OVRGrabbable m_grabbedObj = null;
  69.     protected Vector3 m_grabbedObjectPosOff;
  70.     protected Quaternion m_grabbedObjectRotOff;
  71.     protected Dictionary<OVRGrabbable, int> m_grabCandidates = new Dictionary<OVRGrabbable, int>();
  72.     protected bool operatingWithoutOVRCameraRig = true;
  73.  
  74.     /// <summary>
  75.     /// The currently grabbed object.
  76.     /// </summary>
  77.     public OVRGrabbable grabbedObject
  78.     {
  79.         get { return m_grabbedObj; }
  80.     }
  81.  
  82.     public void ForceRelease(OVRGrabbable grabbable)
  83.     {
  84.         bool canRelease = (
  85.             (m_grabbedObj != null) &&
  86.             (m_grabbedObj == grabbable)
  87.         );
  88.         if (canRelease)
  89.         {
  90.             GrabEnd();
  91.         }
  92.     }
  93.  
  94.     protected virtual void Awake()
  95.     {
  96.  
  97.         m_anchorOffsetPosition = transform.localPosition;
  98.         m_anchorOffsetRotation = transform.localRotation;
  99.  
  100.         // If we are being used with an OVRCameraRig, let it drive input updates, which may come from Update or FixedUpdate.
  101.  
  102.         OVRCameraRig rig = null;
  103.         if (transform.parent != null && transform.parent.parent != null)
  104.             rig = transform.parent.parent.GetComponent<OVRCameraRig>();
  105.  
  106.         if (rig != null)
  107.         {
  108.             rig.UpdatedAnchors += (r) => {OnUpdatedAnchors();};
  109.             operatingWithoutOVRCameraRig = false;
  110.         }
  111.     }
  112.  
  113.     protected virtual void Start()
  114.     {
  115.         m_lastPos = transform.position;
  116.         m_lastRot = transform.rotation;
  117.         if(m_parentTransform == null)
  118.         {
  119.             if(gameObject.transform.parent != null)
  120.             {
  121.                 m_parentTransform = gameObject.transform.parent.transform;
  122.             }
  123.             else
  124.             {
  125.                 m_parentTransform = new GameObject().transform;
  126.                 m_parentTransform.position = Vector3.zero;
  127.                 m_parentTransform.rotation = Quaternion.identity;
  128.             }
  129.         }
  130.     }
  131.  
  132.     void FixedUpdate()
  133.     {
  134.         if (operatingWithoutOVRCameraRig)
  135.             OnUpdatedAnchors();    
  136.     }
  137.  
  138.     // Hands follow the touch anchors by calling MovePosition each frame to reach the anchor.
  139.     // This is done instead of parenting to achieve workable physics. If you don't require physics on
  140.     // your hands or held objects, you may wish to switch to parenting.
  141.     void OnUpdatedAnchors()
  142.     {
  143.         Vector3 handPos = OVRInput.GetLocalControllerPosition(m_controller);
  144.         Quaternion handRot = OVRInput.GetLocalControllerRotation(m_controller);
  145.         Vector3 destPos = m_parentTransform.TransformPoint(m_anchorOffsetPosition + handPos);
  146.         Quaternion destRot = m_parentTransform.rotation * handRot * m_anchorOffsetRotation;
  147.         GetComponent<Rigidbody>().MovePosition(destPos);
  148.         GetComponent<Rigidbody>().MoveRotation(destRot);
  149.  
  150.         if (!m_parentHeldObject)
  151.         {
  152.             MoveGrabbedObject(destPos, destRot);
  153.         }
  154.  
  155.         if (!m_childToHeldObject)
  156.             MoveGrabbedObject(destPos, destRot);
  157.  
  158.         m_lastPos = transform.position;
  159.         m_lastRot = transform.rotation;
  160.  
  161.         float prevFlex = m_prevFlex;
  162.  
  163.         // Update values from inputs
  164.         m_prevFlex = OVRInput.Get(OVRInput.Axis1D.PrimaryHandTrigger, m_controller);
  165.         CheckForGrabOrRelease(prevFlex);
  166.     }
  167.  
  168.     void OnDestroy()
  169.     {
  170.         if (m_grabbedObj != null)
  171.         {
  172.             GrabEnd();
  173.         }
  174.     }
  175.  
  176.     void OnTriggerEnter(Collider otherCollider)
  177.     {
  178.         // Get the grab trigger
  179.         OVRGrabbable grabbable = otherCollider.GetComponent<OVRGrabbable>() ?? otherCollider.GetComponentInParent<OVRGrabbable>();
  180.         if (grabbable == null) return;
  181.  
  182.         // Add the grabbable
  183.         int refCount = 0;
  184.         m_grabCandidates.TryGetValue(grabbable, out refCount);
  185.         m_grabCandidates[grabbable] = refCount + 1;
  186.  
  187.         OVRHapticsClip oVRHapticsClip = new OVRHapticsClip(hapticClip);
  188.         if (m_controller == OVRInput.Controller.LTouch)
  189.             OVRHaptics.LeftChannel.Preempt(oVRHapticsClip);
  190.         else
  191.             OVRHaptics.RightChannel.Preempt(oVRHapticsClip);
  192.     }
  193.  
  194.     void OnTriggerExit(Collider otherCollider)
  195.     {
  196.         OVRGrabbable grabbable = otherCollider.GetComponent<OVRGrabbable>() ?? otherCollider.GetComponentInParent<OVRGrabbable>();
  197.         if (grabbable == null) return;
  198.  
  199.         // Remove the grabbable
  200.         int refCount = 0;
  201.         bool found = m_grabCandidates.TryGetValue(grabbable, out refCount);
  202.         if (!found)
  203.         {
  204.             return;
  205.         }
  206.  
  207.         if (refCount > 1)
  208.         {
  209.             m_grabCandidates[grabbable] = refCount - 1;
  210.         }
  211.         else
  212.         {
  213.             m_grabCandidates.Remove(grabbable);
  214.         }
  215.     }
  216.  
  217.     protected void CheckForGrabOrRelease(float prevFlex)
  218.     {
  219.         if ((m_prevFlex >= grabBegin) && (prevFlex < grabBegin))
  220.         {
  221.             GrabBegin();
  222.         }
  223.         else if ((m_prevFlex <= grabEnd) && (prevFlex > grabEnd))
  224.         {
  225.             GrabEnd();
  226.         }
  227.     }
  228.  
  229.     protected virtual void GrabBegin()
  230.     {
  231.  
  232.         float closestMagSq = float.MaxValue;
  233.         OVRGrabbable closestGrabbable = null;
  234.         Collider closestGrabbableCollider = null;
  235.  
  236.         // Iterate grab candidates and find the closest grabbable candidate
  237.         foreach (OVRGrabbable grabbable in m_grabCandidates.Keys)
  238.         {
  239.             bool canGrab = !(grabbable.isGrabbed && !grabbable.allowOffhandGrab);
  240.             if (!canGrab)
  241.             {
  242.                 continue;
  243.             }
  244.  
  245.             for (int j = 0; j < grabbable.grabPoints.Length; ++j)
  246.             {
  247.                 Collider grabbableCollider = grabbable.grabPoints[j];
  248.                 // Store the closest grabbable
  249.                 Vector3 closestPointOnBounds = grabbableCollider.ClosestPointOnBounds(m_gripTransform.position);
  250.                 float grabbableMagSq = (m_gripTransform.position - closestPointOnBounds).sqrMagnitude;
  251.                 if (grabbableMagSq < closestMagSq)
  252.                 {
  253.                     closestMagSq = grabbableMagSq;
  254.                     closestGrabbable = grabbable;
  255.                     closestGrabbableCollider = grabbableCollider;
  256.                 }
  257.             }
  258.         }
  259.  
  260.         // Disable grab volumes to prevent overlaps
  261.         GrabVolumeEnable(false);
  262.  
  263.         if (closestGrabbable != null)
  264.         {
  265.             if (closestGrabbable.isGrabbed)
  266.             {
  267.                 closestGrabbable.grabbedBy.OffhandGrabbed(closestGrabbable);
  268.             }
  269.  
  270.             m_grabbedObj = closestGrabbable;
  271.             m_grabbedObj.GrabBegin(this, closestGrabbableCollider);
  272.  
  273.             m_lastPos = transform.position;
  274.             m_lastRot = transform.rotation;
  275.  
  276.             // Set up offsets for grabbed object desired position relative to hand.
  277.             if(m_grabbedObj.snapPosition)
  278.             {
  279.                 m_grabbedObjectPosOff = m_gripTransform.localPosition;
  280.                 if(m_grabbedObj.snapOffset)
  281.                 {
  282.                     Vector3 snapOffset = m_grabbedObj.snapOffset.position;
  283.                     if (m_controller == OVRInput.Controller.LTouch) snapOffset.x = -snapOffset.x;
  284.                     m_grabbedObjectPosOff += snapOffset;
  285.                 }
  286.             }
  287.             else
  288.             {
  289.                 Vector3 relPos = m_grabbedObj.transform.position - transform.position;
  290.                 relPos = Quaternion.Inverse(transform.rotation) * relPos;
  291.                 m_grabbedObjectPosOff = relPos;
  292.             }
  293.  
  294.             if (m_grabbedObj.snapOrientation)
  295.             {
  296.                 m_grabbedObjectRotOff = m_gripTransform.localRotation;
  297.                 if(m_grabbedObj.snapOffset)
  298.                 {
  299.                     m_grabbedObjectRotOff = m_grabbedObj.snapOffset.rotation * m_grabbedObjectRotOff;
  300.                 }
  301.             }
  302.             else
  303.             {
  304.                 Quaternion relOri = Quaternion.Inverse(transform.rotation) * m_grabbedObj.transform.rotation;
  305.                 m_grabbedObjectRotOff = relOri;
  306.             }
  307.  
  308.             // Note: force teleport on grab, to avoid high-speed travel to dest which hits a lot of other objects at high
  309.             // speed and sends them flying. The grabbed object may still teleport inside of other objects, but fixing that
  310.             // is beyond the scope of this demo.
  311.             MoveGrabbedObject(m_lastPos, m_lastRot, true);
  312.             if(m_parentHeldObject)
  313.             {
  314.                 m_grabbedObj.transform.parent = transform;
  315.             }
  316.             if (m_childToHeldObject)
  317.                 transform.parent = m_grabbedObj.transform;        }
  318.     }
  319.  
  320.     protected virtual void MoveGrabbedObject(Vector3 pos, Quaternion rot, bool forceTeleport = false)
  321.     {
  322.         if (m_grabbedObj == null)
  323.             return;
  324.  
  325.         //Rigidbody part11rb = part11.GetComponent<Rigidbody>();
  326.  
  327.         //Rigidbody grabbedRigidbody = m_grabbedObj.grabbedRigidbody;
  328.         //Vector3 grabbablePosition = pos + rot * m_grabbedObjectPosOff;
  329.         //Quaternion grabbableRotation = rot * m_grabbedObjectRotOff;
  330.  
  331.         //float Xpos = OVRInput.GetLocalControllerPosition(OVRInput.Controller.LTouch).x + OVRInput.GetLocalControllerPosition(OVRInput.Controller.RTouch).x;
  332.         //float Ypos = OVRInput.GetLocalControllerPosition(OVRInput.Controller.LTouch).y + OVRInput.GetLocalControllerPosition(OVRInput.Controller.RTouch).y;
  333.         //float Zpos = OVRInput.GetLocalControllerPosition(OVRInput.Controller.LTouch).z + OVRInput.GetLocalControllerPosition(OVRInput.Controller.RTouch).z;
  334.  
  335.         //Vector3 centerVector = new Vector3(Xpos, Ypos, Zpos) / 2;
  336.         //part11.transform.position = centerVector;
  337.  
  338.         Vector3 direction = (OVRInput.GetLocalControllerPosition(OVRInput.Controller.RTouch) - OVRInput.GetLocalControllerPosition(OVRInput.Controller.LTouch)).normalized;
  339.         Vector3 currentPos = part11.localEulerAngles;
  340.  
  341.         Quaternion lockRot = Quaternion.LookRotation(direction, part11.up.normalized);
  342.         float locZ = lockRot.z;
  343.  
  344.         part11.localEulerAngles = new Vector3(0f, 0f, locZ);
  345.        
  346.  
  347.         //if (forceTeleport)
  348.         //{
  349.         //   //grabbedRigidbody.transform.position = grabbablePosition;
  350.         //   //grabbedRigidbody.transform.rotation = grabbableRotation;
  351.         //}
  352.         //else
  353.         //{
  354.         //    //grabbedRigidbody.MovePosition(grabbablePosition);
  355.         //    // grabbedRigidbody.MoveRotation(grabbableRotation);
  356.         //}
  357.     }
  358.  
  359.     protected void GrabEnd()
  360.     {
  361.         if (m_grabbedObj != null)
  362.         {
  363.             OVRPose localPose = new OVRPose { position = OVRInput.GetLocalControllerPosition(m_controller), orientation = OVRInput.GetLocalControllerRotation(m_controller) };
  364.             OVRPose offsetPose = new OVRPose { position = m_anchorOffsetPosition, orientation = m_anchorOffsetRotation };
  365.             localPose = localPose * offsetPose;
  366.  
  367.             OVRPose trackingSpace = transform.ToOVRPose() * localPose.Inverse();
  368.             Vector3 linearVelocity = trackingSpace.orientation * OVRInput.GetLocalControllerVelocity(m_controller);
  369.             Vector3 angularVelocity = trackingSpace.orientation * OVRInput.GetLocalControllerAngularVelocity(m_controller);
  370.  
  371.             GrabbableRelease(linearVelocity, angularVelocity);
  372.         }
  373.  
  374.         // Re-enable grab volumes to allow overlap events
  375.         GrabVolumeEnable(true);
  376.        
  377.     }
  378.  
  379.     protected void GrabbableRelease(Vector3 linearVelocity, Vector3 angularVelocity)
  380.     {
  381.         m_grabbedObj.GrabEnd(linearVelocity, angularVelocity);
  382.         if(m_parentHeldObject) m_grabbedObj.transform.parent = null;
  383.         if (m_childToHeldObject)
  384.             transform.parent = null;
  385.         m_grabbedObj = null;
  386.     }
  387.  
  388.     protected virtual void GrabVolumeEnable(bool enabled)
  389.     {
  390.         if (m_grabVolumeEnabled == enabled)
  391.         {
  392.             return;
  393.         }
  394.  
  395.         m_grabVolumeEnabled = enabled;
  396.         for (int i = 0; i < m_grabVolumes.Length; ++i)
  397.         {
  398.             Collider grabVolume = m_grabVolumes[i];
  399.             grabVolume.enabled = m_grabVolumeEnabled;
  400.         }
  401.  
  402.         if (!m_grabVolumeEnabled)
  403.         {
  404.             m_grabCandidates.Clear();
  405.         }
  406.     }
  407.  
  408.     protected virtual void OffhandGrabbed(OVRGrabbable grabbable)
  409.     {
  410.         if (m_grabbedObj == grabbable)
  411.         {
  412.             GrabbableRelease(Vector3.zero, Vector3.zero);
  413.         }
  414.     }
  415. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement