1 using System.Collections;
2 using System.Collections.Generic;
10 public class AVR_Hand : AVR.Core.AVR_ControllerComponent
13 public List<AVR_Finger> fingers =
new List<AVR_Finger>();
15 public Transform index_tip, middle_tip, ring_tip, pinky_tip,
thumb_tip;
16 public float delta = 0.05f;
29 public List<Collider> colliders =
new List<Collider>();
33 return glove_transform;
38 return handControllerTransform;
43 return controller.transform;
47 foreach(Collider c
in colliders) c.enabled =
false;
52 foreach (Collider c
in colliders) c.enabled =
true;
57 fingers.Add(
new AVR_Finger(index_tip, 1,
"Proc_IndexFinger", animator));
58 fingers.Add(
new AVR_Finger(middle_tip, 2,
"Proc_MiddleFinger", animator));
59 fingers.Add(
new AVR_Finger(ring_tip, 3,
"Proc_RingFinger", animator));
60 fingers.Add(
new AVR_Finger(pinky_tip, 4,
"Proc_PinkyFinger", animator));
61 fingers.Add(
new AVR_Finger(thumb_tip, 5,
"Proc_ThumbFinger", animator));
62 colliders.AddRange(GetComponentsInChildren<Collider>());
64 foreach(Collider c
in colliders) {
70 if(physical_hand && !physical_hand_rb) {
71 physical_hand_rb = GetComponent<Rigidbody>();
74 handControllerTransform =
new GameObject(
"handControllerTransform").transform;
75 handControllerTransform.SetParent(ControllerTransform());
76 handControllerTransform.position = HandVisualTransform().position;
77 handControllerTransform.rotation = HandVisualTransform().rotation;
78 def_pos = HandVisualTransform().localPosition;
79 def_rot = HandVisualTransform().localRotation;
86 foreach (
AVR_Finger f
in fingers) f.Calibrate(HandVisualTransform(), delta);
90 fingers[0].setStateImmediate(node.index_pose);
91 fingers[0].setWeightImmediate(1.0f);
92 fingers[1].setStateImmediate(node.middle_pose);
93 fingers[1].setWeightImmediate(1.0f);
94 fingers[2].setStateImmediate(node.ring_pose);
95 fingers[2].setWeightImmediate(1.0f);
96 fingers[3].setStateImmediate(node.pinky_pose);
97 fingers[3].setWeightImmediate(1.0f);
98 fingers[4].setStateImmediate(node.thumb_pose);
99 fingers[4].setWeightImmediate(1.0f);
103 foreach (
AVR_Finger f
in fingers) f.SqueezeOn(HandVisualTransform(), collider);
106 public void SqueezeOn(Collider collider, Vector3 collider_offset) {
107 collider.transform.position += collider_offset;
109 collider.transform.position -= collider_offset;
114 foreach (
AVR_Finger f
in fingers) f.SqueezeOn(HandVisualTransform(), g.colliders);
119 g.transform.position += grabbable_offset;
121 g.transform.position -= grabbable_offset;
125 SetSqueezeWeight(0.0f);
129 foreach (
AVR_Finger f
in fingers) f.setWeight(w);
134 if (IsOnline && !IsOwner)
return;
141 if (IsOnline && !IsOwner)
return;
143 if (fake_parent!=null) {
144 HandVisualTransform().position = fake_parent.position;
145 HandVisualTransform().rotation = fake_parent.rotation;
151 if (IsOnline && !IsOwner)
return;
153 if (fake_parent==null && physical_hand) {
156 Vector3 pDelta = (HandControllerTransform().position - HandVisualTransform().position);
157 Vector3 vel = pDelta / Time.fixedDeltaTime;
159 physical_hand_rb.velocity = vel;
162 Quaternion rotationDelta = HandControllerTransform().rotation * Quaternion.Inverse(HandVisualTransform().rotation);
164 rotationDelta.ToAngleAxis(out
float angle, out Vector3 axis);
165 while (angle > 180) angle -= 360;
167 physical_hand_rb.maxAngularVelocity = 99999.0f;
169 Vector3 angvel = (angle * axis * Mathf.Deg2Rad) / Time.fixedDeltaTime;
170 if (!
float.IsNaN(angvel.z)) physical_hand_rb.angularVelocity = angvel;
178 def_pos = HandVisualTransform().localPosition;
179 def_rot = HandVisualTransform().localRotation;
180 fake_parent =
new GameObject(
"DummyParent").transform;
181 fake_parent.position = HandVisualTransform().position;
182 fake_parent.rotation = HandVisualTransform().rotation;
183 fake_parent.SetParent(fp);
187 if(fake_parent==null)
return;
188 HandVisualTransform().localPosition = def_pos;
189 HandVisualTransform().localRotation = def_rot;
190 GameObject.Destroy(fake_parent.gameObject);
211 public AVR_Finger(Transform tip,
int layer,
string AnimationState, Animator anim)
213 this.animator = anim;
216 this.AnimationState = AnimationState;
217 this.positions =
new List<Vector3>();
222 this.state_target = this.state = state;
223 animator.Play(this.AnimationState, this.layer, state);
224 animator.Update(0.0f);
229 state_target = state;
234 this.weigth_target = this.weigth = w;
235 animator.SetLayerWeight(this.layer, w);
236 animator.Update(0.0f);
246 this.weigth = Mathf.Lerp(this.weigth, this.weigth_target, 10f * Time.deltaTime);
247 animator.SetLayerWeight(this.layer, this.weigth);
249 this.state = Mathf.Lerp(this.state, this.state_target, 10f * Time.deltaTime);
250 animator.Play(this.AnimationState, this.layer, this.state);
253 public void Calibrate(Transform handVisualTransform,
float delta)
256 this.setWeightImmediate(1.0f);
257 animator.speed = 0.0f;
259 for (
float i = 0.0f; i <= 1.0f; i += delta)
261 this.setStateImmediate(i);
263 this.positions.Add(handVisualTransform.InverseTransformPoint(this.tip.position));
267 this.setWeightImmediate(0.0f);
270 public void SqueezeOn(Transform handVisualTransform, Collider coll) {
272 for (i = 0; i < this.positions.Count; i++)
274 Vector3 pos = handVisualTransform.TransformPoint(this.positions[i]);
275 if (ColliderContains(coll, pos))
break;
277 float offset = Mathf.Clamp(-0.5f * delta + (float)(i) / (float)this.positions.Count, 0.0f, 1.0f);
278 this.setState(offset);
279 this.setWeight(1.0f);
282 public void SqueezeOn(Transform handVisualTransform, List<Collider> colls)
284 if(colls.Count<1)
return;
285 if(colls.Count==1) this.SqueezeOn(handVisualTransform, colls[0]);
288 for (i = 0; i < this.positions.Count; i++)
290 Vector3 pos = handVisualTransform.TransformPoint(this.positions[i]);
291 if (ColliderContains(colls[0], pos))
break;
294 if(i>=positions.Count) i--;
297 for(
int j=1; j<colls.Count; j++) {
298 while(i>0 && ColliderContains(colls[j], handVisualTransform.TransformPoint(
this.positions[i]))) i--;
301 float offset = Mathf.Clamp((float)(i) / (float)this.positions.Count, 0.0f, 1.0f);
302 this.setState(offset);
303 this.setWeight(1.0f);
309 return Vector3.Distance(pos, c.ClosestPoint(pos)) < 0.001f;
void SqueezeOn(Collider collider)
Transform HandControllerTransform()
Transform ControllerTransform()
Rigidbody physical_hand_rb
void SqueezeOn(AVR_Grabbable g)
void ApplyNodePose(AVR_GrabNode node)
Represents a grabbable object.
Transform HandVisualTransform()
void SetSqueezeWeight(float w)
void SqueezeOn(Collider collider, Vector3 collider_offset)
void setWeightImmediate(float w)
Sets the documentation html file inside of Packages/com.avr.core/Documentation/html of a given class...
void SetFakeParent(Transform fp)
void SqueezeOn(Transform handVisualTransform, Collider coll)
void SqueezeOn(AVR_Grabbable g, Vector3 grabbable_offset)
List< Vector3 > positions
Transform glove_transform
Represents a grabbable node on an AVR_Grabbable. Nodes have preset poses/constraints for the hand tha...
AVR_Finger(Transform tip, int layer, string AnimationState, Animator anim)
Transform handControllerTransform
void SqueezeOn(Transform handVisualTransform, List< Collider > colls)
Interactive hand model that adapts itself to grabbed objects. Only works with Offset- or AdvancedOffs...
void setState(float state)
void setStateImmediate(float state)
void Calibrate(Transform handVisualTransform, float delta)
static bool ColliderContains(Collider c, Vector3 pos)