VR Development Framework
v 1.0.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties Events Pages
AVR_OffsetGrabProvider.cs
1 using System.Collections;
2 using System.Collections.Generic;
3 using UnityEngine;
4 
5 namespace AVR.Phys {
6  /// <summary>
7  /// Same as BasicGrabProvider but additionally allows grabbing objects at an offset. (Eg. you may grab a pan by its handle instead of just its center)
8  /// Also allows the usage of an AVR_Hand.
9  /// Use this if you require grabbing larger / more complex objects.
10  /// </summary>
11  [AVR.Core.Attributes.DocumentationUrl("class_a_v_r_1_1_phys_1_1_a_v_r___offset_grab_provider.html")]
13  {
14  /// <summary>
15  /// Location an rotation the grabbed objects transform will strive to adopt.
16  /// Eg: if we grab a pan by its handle, this Transform represents the virtual location the pans transform will move towards.
17  /// </summary>
18  private Transform grabbedObjectCenter;
19 
20  /// <summary>
21  /// HandVisual
22  /// </summary>
24 
25  protected override void Start() {
26  base.Start();
27  if(!handVisual) handVisual = transform.parent.GetComponentInChildren<AVR_Hand>();
28  grabbedObjectCenter = new GameObject("grabbedObjectCenter").transform;
29  grabbedObjectCenter.SetParent(grabPoint);
30  }
31 
32  public override Vector3 getTargetPosition()
33  {
34  return grabbedObjectCenter.position;
35  }
36 
37  public override Quaternion getTargetRotation()
38  {
39  return grabbedObjectCenter.rotation;
40  }
41 
42  public override Transform getTargetTransform()
43  {
44  return grabbedObjectCenter;
45  }
46 
47  public override void makeRelease()
48  {
49  base.makeRelease();
50  if (handVisual != null) StartCoroutine(unsetHand());
51  }
52 
53  public override void makeGrab(GrabLocation location) {
54  base.makeGrab(location);
55  if(grabbedObject!=null)
56  {
57  // Set desired rotation
58  if(location.isNode) {
59  grabbedObjectCenter.rotation = location.node.get_target_rotation(handVisual.transform.rotation);
60 
61  // We need to find out the position offset *under the above given rotation*. For these purposes we temporarily apply the rotation to location.grabbable,
62  // then undo it again right afterwards.
63  Quaternion tmp = location.grabbable.transform.rotation;
64  location.grabbable.transform.rotation = grabbedObjectCenter.rotation;
65  grabbedObjectCenter.position = grabPoint.position + (location.grabbable.transform.position - location.location);
66  location.grabbable.transform.rotation = tmp;
67  }
68  else
69  {
70  grabbedObjectCenter.rotation = location.grabbable.transform.rotation;
71  grabbedObjectCenter.position = grabPoint.position + (location.grabbable.transform.position - location.location);
72  }
73 
74  if(handVisual) StartCoroutine(setHand());
75  }
76  }
77 
78  protected override void Update() {
79 #if AVR_NET
80  if (IsOnline && !IsOwner) return;
81 #endif
82  // Pre-grab hand
83  if (grabbedObject == null && handVisual != null && grabbableFinder.getGrabLocation(out GrabLocation grabLocation) && !grabLocation.isNode)
84  {
85  handVisual.SqueezeOn(grabLocation.collider, grabPoint.position - grabLocation.location);
86 
87  // This is a hacky/bad way of calculating the "entry-distance" (maximum distance inside the grabzone-collider in direction grabzone_p)
88  Vector3 far_away = 100.0f * (grabLocation.location - grabPoint.position);
89  Vector3 smth = grabbableFinder.closestPoint(far_away);
90  float entrydist = Vector3.Distance(smth, grabPoint.position);
91  float currentdist = Vector3.Distance(grabPoint.position, grabLocation.location);
92 
93  float max_pregrab_adapt_factor = 0.35f; // maximum AdaptWeigth used for pregrab. (weight when grabPoint=p)
94  float max_pregrab_grace_dist = 0.03f; // Distance at which we consider "grabPoint=p" for purposes stated above
95  float w = Mathf.Max(0, max_pregrab_adapt_factor - (Mathf.Max(0, currentdist - max_pregrab_grace_dist) / entrydist));
96 
97  handVisual.SetSqueezeWeight(w);
98 
99  }
100  else if (grabbedObject == null && handVisual)
101  {
102  handVisual.Relax();
103  }
104 
105  // Regular update
106  base.Update();
107  }
108 
109  // Set the handVisual appropriately to currently grabbed Grabbable
110  protected virtual IEnumerator setHand()
111  {
112  handVisual.disableColliders();
113  // Wait a bit to ensure at least 1 physics-frame has passed
114  yield return new WaitForSecondsRealtime(Time.fixedDeltaTime + 0.01f);
115  // Wait until the object is close enough
116  yield return new WaitUntil(() => Vector3.Distance(grabbedObject.transform.position, getTargetPosition()) < 0.05f); //TODO: grabbedObject == null?
117 
118  //TODO: disable hand colliders if the hand is physical
119 
120  if(grabLocation.isNode) {
121  handVisual.ApplyNodePose(grabLocation.node);
122  }
123  else
124  {
125  handVisual.SqueezeOn(grabbedObject);
126  handVisual.SetSqueezeWeight(1.0f);
127  }
128  handVisual.SetFakeParent(grabbedObject.transform);
129  }
130 
131  protected virtual IEnumerator unsetHand()
132  {
133  handVisual.enableColliders();
134  handVisual.Relax();
135  handVisual.UnsetFakeParent();
136 
137  //TODO: re-enable colliders if hand is physical
138 
139  yield return new WaitForEndOfFrame();
140  }
141  }
142 }
override Transform getTargetTransform()
getTargetPosition() and getTargetRotation() combined into one transform. The grabbed objects transfor...
Represents an (attempted) grab at a given location of an object.
override Quaternion getTargetRotation()
Target rotation the grabbed object should "strive" towards in world space. There will be force trying...
override void makeGrab(GrabLocation location)
Perform a grab on with parameters given in a GrabLocation struct
override Vector3 getTargetPosition()
Target position the grabbed object should "strive" towards in world coordiantes. There will be force ...
Transform grabbedObjectCenter
Location an rotation the grabbed objects transform will strive to adopt. Eg: if we grab a pan by its ...
Sets the documentation html file inside of Packages/com.avr.core/Documentation/html of a given class...
Simplest GrabProvider. Grabbed objects will move their center (obj.transform.position) towards the re...
Interactive hand model that adapts itself to grabbed objects. Only works with Offset- or AdvancedOffs...
Definition: AVR_Hand.cs:10
Same as BasicGrabProvider but additionally allows grabbing objects at an offset. (Eg. you may grab a pan by its handle instead of just its center) Also allows the usage of an AVR_Hand. Use this if you require grabbing larger / more complex objects.
override void makeRelease()
Ends a grab. Is called when the respective "releaseEvent" is true.