void StoreTool(Tool t) { GameObject o = t.gameObject; o.transform.SetParent(t.storage.transform); t.touchable.grabbed = false; t.engaged = false; t.stored = true; o.transform.localPosition = new Vector3(0f, 0f, 0f); o.transform.localRotation = Quaternion.identity; o.transform.localScale = new Vector3(1f, 1f, 1f); float v = t.storage.transform.localScale.x; //can grab any dimension Vector3 invscale = new Vector3(1f / v, 1f / v, 1f / v); t.text.transform.localScale = invscale; Halfable h = o.GetComponent <Halfable>(); if (h != null) { h.setHalf(false); //Un-half when we store a tool. } t.dial_dial.Reset(); // definitely need to reset tool when we store it. t.textv_tmpro.SetText("{0:3}" + t.dial_dial.unit, (float)t.dial_dial.val); UpdateApplyTool(t); }
// The three functions below are used to manage attach/detach and storage of tools. // Generally, they have to set the transforms properly, update state variables, // and update text. void ActivateTool(Tool t) { GameObject o = t.gameObject; o.transform.SetParent(t.active.transform); t.touchable.grabbed = false; t.engaged = true; t.stored = false; t.boxcollider.isTrigger = true; // Not sure the two below are ever used? We don't have dials for these tools in use. // if(t == tool_insulator) t.dial_dial.val = (float)ThermoMath.percent_given_t(thermo.temperature); //else if(t == tool_clamp) t.dial_dial.val = (float)ThermoMath.percent_given_v(thermo.volume); t.dial_dial.Reset(); // reset tool when we add it. t.textv_tmpro.SetText("{0:3}" + t.dial_dial.unit, (float)t.dial_dial.val); UpdateApplyTool(t); o.transform.localPosition = new Vector3(0f, 0f, 0f); o.transform.localRotation = Quaternion.identity; o.transform.localScale = new Vector3(1f, 1f, 1f); float v = t.active.transform.localScale.x; //can grab any dimension Vector3 invscale = new Vector3(1f / v, 1f / v, 1f / v); t.text.transform.localScale = invscale; Halfable h = o.GetComponent <Halfable>(); if (h != null) { h.setHalf(halfed); //conform to half-ness while engaged } }
/* * This function seems to handle all possible interactions between the hand and other objects. * Honestly, I haven't quite got a full understanding of this ~200-line behemoth. */ //"left_hand": true -> left, false -> right void TryHand(bool left_hand, float htrigger_val, float itrigger_val, float x_val, float y_val, Vector3 hand_vel, ref bool ref_htrigger, ref bool ref_itrigger, ref int ref_htrigger_delta, ref int ref_itrigger_delta, ref float ref_x, ref float ref_y, ref GameObject ref_hand, ref GameObject ref_grabbed, ref GameObject ref_ohand, ref GameObject ref_ograbbed) { float htrigger_threshhold = 0.1f; float itrigger_threshhold = 0.1f; //find deltas ref_htrigger_delta = 0; if (!ref_htrigger && htrigger_val > htrigger_threshhold) { ref_htrigger_delta = 1; ref_htrigger = true; } else if (ref_htrigger && htrigger_val <= htrigger_threshhold) { ref_htrigger_delta = -1; ref_htrigger = false; } ref_itrigger_delta = 0; if (!ref_itrigger && itrigger_val > itrigger_threshhold) { ref_itrigger_delta = 1; ref_itrigger = true; ref_x = x_val; ref_y = y_val; } else if (ref_itrigger && itrigger_val <= itrigger_threshhold) { ref_itrigger_delta = -1; ref_itrigger = false; } //find new grabs if (ref_grabbed == null && ref_htrigger_delta == 1) { //first try movables for (int i = 0; ref_grabbed == null && i < movables.Count; i++) { if ( //object newly grabbed (left_hand && movables[i].ltouch) || (!left_hand && movables[i].rtouch) ) { ref_grabbed = movables[i].gameObject; ref_grabbed.transform.SetParent(ref_hand.transform); if (ref_grabbed == ref_ograbbed) { ref_ograbbed = null; } movables[i].grabbed = true; Tool t = ref_grabbed.GetComponent <Tool>(); if (t) //newly grabbed object is a tool { t.engaged = false; t.stored = false; ref_grabbed.transform.localScale = new Vector3(1f, 1f, 1f); t.text.transform.localScale = new Vector3(1f, 1f, 1f); t.rigidbody.isKinematic = true; t.boxcollider.isTrigger = false; UpdateApplyTool(t); } VisAid v = ref_grabbed.GetComponent <VisAid>(); if (v) //newly grabbed object is a visaid { v.stored = false; v.rigidbody.isKinematic = true; } } } //then dials if (ref_grabbed == null) { for (int i = 0; i < tools.Count; i++) { if ( //dial newly grabbed (left_hand && tools[i].dial_touchable.ltouch) || (!left_hand && tools[i].dial_touchable.rtouch) ) { ref_grabbed = tools[i].dial; tools[i].dial_touchable.grabbed = true; if (ref_grabbed == ref_ograbbed) { ref_ograbbed = null; } } } } //then extraaneous if (ref_grabbed == null) //still not holding anything { Touchable g = handle_workspace_touchable; if ( //handle newly grabbed (left_hand && g.ltouch) || (!left_hand && g.rtouch) ) { ref_grabbed = handle_workspace; g.grabbed = true; if (ref_grabbed == ref_ograbbed) { ref_ograbbed = null; } } } if (ref_grabbed == null) //still not holding anything { Touchable g = halfer_touchable; if ( //halfing button newly grabbed (left_hand && g.ltouch) || (!left_hand && g.rtouch) ) { ref_grabbed = halfer; g.touch = true; if (ref_grabbed == ref_ograbbed) { ref_ograbbed = null; } SetAllHalfed(!halfed); } } if (ref_grabbed == null) //still not holding anything { Touchable g = reset_touchable; if ( //reset button newly grabbed (left_hand && g.ltouch) || (!left_hand && g.rtouch) ) { ref_grabbed = reset; g.touch = true; if (ref_grabbed == ref_ograbbed) { ref_ograbbed = null; } thermo.Reset(); } } if (ref_grabbed != null) //something newly grabbed { Halfable h = ref_grabbed.GetComponent <Halfable>(); if (h != null) { h.setHalf(false); //nothing should be halfed while being grabbed } } } //find new releases else if (ref_grabbed && ref_htrigger_delta == -1) //something newly released { Tool t = ref_grabbed.GetComponent <Tool>(); if (t) //tool newly released { if (t.active_ghost.tintersect) //tool released making it active { ActivateTool(t); } else if (t.storage_ghost.tintersect) //tool released making it stored { StoreTool(t); } else //tool released nowhere special { DetachTool(t, hand_vel); } } else //newly released object is NOT a tool { ref_grabbed.transform.SetParent(ref_grabbed.GetComponent <Touchable>().og_parent); //ok to do, even with a dial VisAid v = ref_grabbed.GetComponent <VisAid>(); if (v) //visaid newly released { v.rigidbody.isKinematic = false; v.rigidbody.velocity = hand_vel; } } ref_grabbed.GetComponent <Touchable>().grabbed = false; ref_grabbed = null; } if (ref_grabbed) { TryInteractable(ref_grabbed, x_val, y_val, ref ref_x, ref ref_y); } ref_x = x_val; ref_y = y_val; //centerer if (vrcenter_fingertoggleable.finger) //finger hitting vrcenter object { if ( //we're currently checking the correct hand (left_hand && vrcenter_fingertoggleable.lfinger) || (!left_hand && vrcenter_fingertoggleable.rfinger) ) { //reset center position vrcenter_backing_meshrenderer.material = tab_hisel; UnityEngine.XR.InputTracking.Recenter(); OVRManager.display.RecenterPose(); Vector3 pos = cam_offset.transform.localPosition - (cam_offset.transform.localPosition + ceye.transform.localPosition); pos.y = 0f; cam_offset.transform.localPosition = pos; } else { vrcenter_backing_meshrenderer.material = tab_hi; } } else { vrcenter_backing_meshrenderer.material = tab_default; } }