IMHOTEP Framework
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties Pages
ToolControl.cs
1 using UnityEngine;
2 using System.Collections;
3 using System.Collections.Generic;
4 
9 public class ToolControl : MonoBehaviour {
10 
11  public Platform platform;
12  public Sprite ToolSelectSprite;
13  public Sprite ToolAcceptSprite;
14  public Sprite ArrowL;
15  public Sprite ArrowR;
16  public Sprite Cancel;
17 
18  private GameObject activeTool = null;
19 
20  public static ToolControl instance { private set; get; }
21 
22  private GameObject toolRing;
23 
24  private float rotationStartTime = 0f;
25  private float toolRingTargetAngle = 0.0f;
26  private float rotationTime = 0.3f;
27 
28  private bool toolRingActive = false;
29  private float movingStartTime = 0f;
30  private Vector3 targetPosition;
31  private float movingTime = 0.3f;
32  private float toolRingY = 0.1f;
33  private TextMesh ActiveToolName;
34 
35  public Color iconColor = new Color( 0.7f, 0.85f, 1.0f );
36 
38  private ToolRingEntry selectedToolEntry = null;
39 
40  private List<ToolWidget> availableTools = new List<ToolWidget> ();
41 
43  private GameObject overridingTool;
44  private GameObject previousTool;
45 
46  public ToolControl() {
47  if( instance != null )
48  throw(new System.Exception ("Error: Cannot create more than one instance of ToolControl!"));
49  instance = this;
50  }
51 
52  void Start () {
53  // Register event callbacks for all Patient events:
54  PatientEventSystem.startListening( PatientEventSystem.Event.PATIENT_FinishedLoading, patientLoaded );
55  PatientEventSystem.startListening( PatientEventSystem.Event.PATIENT_Closed, patientClosed );
56 
57  InputDeviceManager.instance.setLeftControllerTouchpadIconCentral (ToolSelectSprite);
58 
59  foreach (Transform child in transform) {
60  child.gameObject.SetActive (false);
61  }
62  updateAvailableTools ();
63  }
64 
65  void Update() {
66 
67  // If the input device is a controller, handle the touch-pad-selection:
68  InputDevice inputDevice = InputDeviceManager.instance.currentInputDevice;
69  if (inputDevice.getDeviceType() == InputDeviceManager.InputDeviceType.ViveController) {
70  Controller lc = InputDeviceManager.instance.leftController;
71  if( lc != null )
72  {
73  if( lc.touchpadButtonState == UnityEngine.EventSystems.PointerEventData.FramePressState.Released ) {
74  if (lc.hoverTouchpadCenter()) {
75  toggleToolRing ();
76  } else if (toolRingActive) {
77  if (lc.hoverTouchpadLeft()) {
78  toolRingPrev ();
79  } else if (lc.hoverTouchpadRight()) {
80  toolRingNext ();
81  } else if (lc.hoverTouchpadDown()) {
82  toolRingCancel ();
83  }
84  }
85  }
86  }
87  }
88 
89  if (toolRing != null) {
90  // Rotate the tool ring if left/right was pressed:
91  Quaternion targetRotation = Quaternion.AngleAxis (toolRingTargetAngle, Vector3.up);
92  toolRing.transform.localRotation = Quaternion.Slerp (toolRing.transform.localRotation,
93  targetRotation, (Time.time - rotationStartTime) / rotationTime);
94 
95  // Move the tool ring up or down when it's being activated or deactivated:
96  toolRing.transform.localPosition = Vector3.Slerp( toolRing.transform.localPosition,
97  targetPosition, (Time.time - movingStartTime) / movingTime);
98 
99  ActiveToolName.transform.localPosition = toolRing.transform.localPosition + new Vector3 ( 0f, -0.06f, -0.07f );
100 
101  updateToolRingIcons ();
102  }
103  }
104 
105  public void updateAvailableTools( object obj = null )
106  {
107  availableTools = new List<ToolWidget> ();
108 
109  foreach (Transform child in transform) {
110  ToolWidget tool = child.GetComponent<ToolWidget> ();
111  if (tool != null) {
112  // Only show the tool if it's currently available:
113  if (tool.displayTime == ToolWidget.ToolDisplayTime.Always ||
114  (tool.displayTime == ToolWidget.ToolDisplayTime.WhenPatientIsLoaded && Patient.getLoadedPatient () != null) ||
115  (tool.displayTime == ToolWidget.ToolDisplayTime.WhenNoPatientIsLoaded && Patient.getLoadedPatient () == null)) {
116  availableTools.Add (tool);
117  }
118  }
119  }
120 
121  if (ToolUIAnchor.instance != null)
122  {
123  foreach (Transform child in ToolUIAnchor.instance.transform)
124  {
125  ToolWidget tool = child.GetComponent<ToolWidget>();
126  if (tool != null)
127  {
128  // Only show the tool if it's currently available:
129  if (tool.displayTime == ToolWidget.ToolDisplayTime.Always ||
130  (tool.displayTime == ToolWidget.ToolDisplayTime.WhenPatientIsLoaded && Patient.getLoadedPatient() != null) ||
131  (tool.displayTime == ToolWidget.ToolDisplayTime.WhenNoPatientIsLoaded && Patient.getLoadedPatient() == null))
132  {
133  availableTools.Add(tool);
134  }
135  }
136  }
137  }
138  }
139 
141  public void generateToolRing()
142  {
143  Controller lc = InputDeviceManager.instance.leftController;
144  if (lc != null) {
145  // If there's already a tool ring element, delete it:
146  Transform oldToolRing = lc.transform.Find ("ToolRingAnchor");
147  if (oldToolRing != null)
148  Destroy (oldToolRing.gameObject);
149 
150  // Create new Tool Ring:
151  GameObject anchor = new GameObject ("ToolRingAnchor"); // Anchor object for rotation/positon only.
152  anchor.transform.SetParent (lc.transform, false);
153  anchor.transform.localPosition = new Vector3 (0f, -0.025f, 0f);
154  anchor.transform.localRotation = Quaternion.AngleAxis (85f, Vector3.right);
155  toolRing = new GameObject ("ToolRing"); // Actual tool ring. Will only be rotated around its local Y axis.
156  toolRing.transform.SetParent (anchor.transform, false);
157 
158  // Add a choice for each tool to the ring:
159  int i = 0;
160  int numTools = availableTools.Count;
161  float radius = 0.07f;
162  foreach (ToolWidget tool in availableTools) {
163  if (tool != null) {
164  float currentAngle = (float)i * (2f * Mathf.PI) / (float)numTools;
165 
166  GameObject go = new GameObject (i.ToString ());
167  go.transform.SetParent (toolRing.transform);
168  go.transform.localPosition = radius * (new Vector3 (-Mathf.Sin (currentAngle), 0f, -Mathf.Cos (currentAngle)));
169  go.transform.localRotation = Quaternion.AngleAxis (currentAngle * 180f / Mathf.PI, Vector3.up);
170  go.transform.localScale = new Vector3 (0.045f, 0.045f, 0.045f);
171  SpriteRenderer sr = go.AddComponent<SpriteRenderer> ();
172  sr.sprite = tool.ToolIcon;
173  sr.sortingLayerID = SortingLayer.NameToID ("Sprites");
174 
175  ToolRingEntry entry = go.AddComponent<ToolRingEntry> ();
176  entry.Tool = tool;
177  entry.name = tool.name;
178  }
179  i++;
180  }
181 
182  GameObject text = new GameObject ("ToolNameText");
183  text.transform.SetParent (anchor.transform);
184  text.transform.localPosition = new Vector3 (0f, -0.06f, -radius);
185  text.transform.localRotation = Quaternion.AngleAxis (0f * 180f / Mathf.PI, Vector3.up);
186  text.transform.localScale = new Vector3 (0.02f, 0.02f, 0.02f);
187  ActiveToolName = text.AddComponent<TextMesh> ();
188  ActiveToolName.text = "";
189  ActiveToolName.fontSize = 40;
190  ActiveToolName.alignment = TextAlignment.Center;
191  ActiveToolName.anchor = TextAnchor.MiddleCenter;
192 
193  Renderer r = text.GetComponent<Renderer> ();
194  r.sortingLayerID = SortingLayer.NameToID ("Sprites");
195  } else {
196  // If no controller is active, let the RiftToolRing handle the display of available tools:
197  if(RiftToolRing.instance != null)
198  {
199  RiftToolRing.instance.setAvailableTools (availableTools);
200  }
201  }
202  }
203 
204  public void removeToolRing()
205  {
206  targetPosition = new Vector3 (0f, 0f, 0.0f);
207  movingTime = 0.5f;
208  movingStartTime = Time.time;
209  }
210 
211  public void activateToolRing()
212  {
213  //updateAvailableTools ();
214 
215  generateToolRing ();
216 
217  InputDeviceManager.instance.setLeftControllerTouchpadIconCentral (ToolAcceptSprite);
218  InputDeviceManager.instance.setLeftControllerTouchpadIcons (ArrowL, ArrowR, null, Cancel);
219  toolRingActive = true;
220 
221  // Start animation: (ease the ring in)
222  targetPosition = new Vector3 (0f, toolRingY, 0f);
223  movingTime = 1f;
224  movingStartTime = Time.time;
225  }
226 
227  public void toggleToolRing()
228  {
229  if( toolRingActive )
230  {
231  closeActiveTool ();
232  removeToolRing ();
233  InputDeviceManager.instance.setLeftControllerTouchpadIconCentral (ToolSelectSprite);
234  InputDeviceManager.instance.setLeftControllerTouchpadIcons (null, null, null, null);
235  toolRingActive = false;
236 
237  // Select the current tool:
238  if( selectedToolEntry != null )
239  {
240  Debug.Log ("SelectedToolEntry: " + selectedToolEntry.Tool.name);
241  chooseTool (selectedToolEntry.Tool);
242  }
243  } else {
244  closeActiveTool ();
245  activateToolRing ();
246  }
247  }
248 
249  public void toolRingCancel()
250  {
251  removeToolRing ();
252  InputDeviceManager.instance.setLeftControllerTouchpadIconCentral (ToolSelectSprite);
253  InputDeviceManager.instance.setLeftControllerTouchpadIcons (null, null, null, null);
254  toolRingActive = false;
255  }
256 
258  public void toolRingNext()
259  {
260  if (toolRing == null)
261  return;
262 
263  int numTools = transform.childCount;
264  float angle = (360f) / (float)numTools;
265  setToolRingTargetRotation( toolRingTargetAngle + angle );
266  //toolRing.transform.localRotation *= Quaternion.AngleAxis (angle, Vector3.up);
267  }
268 
270  public void toolRingPrev()
271  {
272  if (toolRing == null)
273  return;
274 
275  int numTools = transform.childCount;
276  float angle = (360f) / (float)numTools;
277  setToolRingTargetRotation( toolRingTargetAngle - angle );
278  //toolRing.transform.localRotation *= Quaternion.AngleAxis (-angle, Vector3.up);
279  }
280 
281  public void setToolRingTargetRotation( float angle )
282  {
283  toolRingTargetAngle = angle;
284  rotationStartTime = Time.time;
285  rotationTime = 0.3f;
286  }
287 
288  public void updateToolRingIcons()
289  {
290  if (toolRing != null) {
291 
292  // Make the tool ring become less transparent as it eases in:
293  float alpha = Mathf.Pow (toolRing.transform.localPosition.y / toolRingY, 2f);
294 
295  float scale = 0.75f + 0.25f * alpha;
296  Vector3 scaleVec = 0.045f*(new Vector3( scale, scale, scale ));
297  //toolRing.transform.localScale = new Vector3 (scale, scale, scale);
298 
299  float smallestAngleDiff = float.MaxValue;
300  selectedToolEntry = null;
301 
302  foreach (Transform tf in toolRing.transform) {
303  if (alpha > 0) {
304  tf.gameObject.SetActive (true);
305 
306  float angleDiff = Mathf.Abs(-toolRing.transform.localEulerAngles.y - tf.localEulerAngles.y);
307  angleDiff = angleDiff % 360f; // Just to make sure...
308  if (angleDiff > 180f)
309  angleDiff = 360f - angleDiff;
310  Color col = (1f - angleDiff / 360f)*(iconColor);
311  // Make the tool ring become less transparent as
312  col.a *= alpha;
313  tf.localScale = scaleVec;
314 
315  if(tf.GetComponent<SpriteRenderer> () != null)
316  tf.GetComponent<SpriteRenderer> ().color = col;
317 
318  if (angleDiff < smallestAngleDiff) {
319  smallestAngleDiff = angleDiff;
320  selectedToolEntry = tf.GetComponent<ToolRingEntry> ();
321  }
322  } else {
323  tf.gameObject.SetActive (false);
324  }
325  }
326  if (selectedToolEntry != null) {
327  Color col = Color.white;
328  col.a *= alpha;
329  selectedToolEntry.GetComponent<SpriteRenderer>().color = col;
330  ActiveToolName.text = selectedToolEntry.name;
331  }
332  Color textCol = ActiveToolName.color;
333  textCol.a = alpha*alpha;
334  ActiveToolName.color = textCol;
335  ActiveToolName.transform.localScale = scaleVec * 0.1f;
336  }
337  }
338 
339  public void patientLoaded( object obj = null )
340  {
341  updateAvailableTools ();
342  generateToolRing ();
343  }
344 
345  public void patientClosed( object obj = null )
346  {
347  if (activeTool != null) {
348  if (activeTool.GetComponent<ToolWidget> ().displayTime == ToolWidget.ToolDisplayTime.WhenPatientIsLoaded) {
349  closeActiveTool ();
350  }
351  }
352  updateAvailableTools ();
353  generateToolRing ();
354  }
355 
356  public void closeActiveTool()
357  {
358  if (activeTool != null) {
359  activeTool.SetActive (false);
360  activeTool = null;
361 
362  InputDeviceManager.instance.resetToolIcons ();
363  }
364  }
365 
366  public void chooseTool( ToolWidget tool )
367  {
368  previousTool = activeTool;
369  overridingTool = null;
370 
371  closeActiveTool ();
372  toolRingCancel ();
373  activeTool = tool.gameObject;
374  // Move the active tool to the tool anchor:
375  activeTool.SetActive (true);
376  InputDeviceManager.instance.shakeLeftController( 0.5f, 0.15f );
377  }
378 
380  public void overrideTool( string name )
381  {
382  foreach (ToolWidget tool in availableTools) {
383  if (tool.name == name) {
384  if (tool.gameObject != activeTool) {
385  chooseTool (tool);
386  overridingTool = tool.gameObject;
387  }
388  }
389  }
390  }
391 
392  public void unoverrideTool( string name )
393  {
394  if (overridingTool != null && overridingTool.name == name) {
395  overridingTool = null;
396  if (previousTool != null) {
397  chooseTool (previousTool.GetComponent<ToolWidget> ());
398  previousTool = null;
399  } else {
400  closeActiveTool ();
401  }
402  }
403  }
404 }
void overrideTool(string name)
Definition: ToolControl.cs:380
void toolRingNext()
Definition: ToolControl.cs:258
void toolRingPrev()
Definition: ToolControl.cs:270
void generateToolRing()
Definition: ToolControl.cs:141