IMHOTEP Framework
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties Pages
LinearDrive.cs
1 //======= Copyright (c) Valve Corporation, All rights reserved. ===============
2 //
3 // Purpose: Drives a linear mapping based on position between 2 positions
4 //
5 //=============================================================================
6 
7 using UnityEngine;
8 using System.Collections;
9 
10 namespace Valve.VR.InteractionSystem
11 {
12  //-------------------------------------------------------------------------
13  [RequireComponent( typeof( Interactable ) )]
14  public class LinearDrive : MonoBehaviour
15  {
16  public Transform startPosition;
17  public Transform endPosition;
18  public LinearMapping linearMapping;
19  public bool repositionGameObject = true;
20  public bool maintainMomemntum = true;
21  public float momemtumDampenRate = 5.0f;
22 
23  private float initialMappingOffset;
24  private int numMappingChangeSamples = 5;
25  private float[] mappingChangeSamples;
26  private float prevMapping = 0.0f;
27  private float mappingChangeRate;
28  private int sampleCount = 0;
29 
30 
31  //-------------------------------------------------
32  void Awake()
33  {
34  mappingChangeSamples = new float[numMappingChangeSamples];
35  }
36 
37 
38  //-------------------------------------------------
39  void Start()
40  {
41  if ( linearMapping == null )
42  {
43  linearMapping = GetComponent<LinearMapping>();
44  }
45 
46  if ( linearMapping == null )
47  {
48  linearMapping = gameObject.AddComponent<LinearMapping>();
49  }
50 
51  initialMappingOffset = linearMapping.value;
52 
53  if ( repositionGameObject )
54  {
55  UpdateLinearMapping( transform );
56  }
57  }
58 
59 
60  //-------------------------------------------------
61  private void HandHoverUpdate( Hand hand )
62  {
63  if ( hand.GetStandardInteractionButtonDown() )
64  {
65  hand.HoverLock( GetComponent<Interactable>() );
66 
67  initialMappingOffset = linearMapping.value - CalculateLinearMapping( hand.transform );
68  sampleCount = 0;
69  mappingChangeRate = 0.0f;
70  }
71 
72  if ( hand.GetStandardInteractionButtonUp() )
73  {
74  hand.HoverUnlock( GetComponent<Interactable>() );
75 
76  CalculateMappingChangeRate();
77  }
78 
79  if ( hand.GetStandardInteractionButton() )
80  {
81  UpdateLinearMapping( hand.transform );
82  }
83  }
84 
85 
86  //-------------------------------------------------
87  private void CalculateMappingChangeRate()
88  {
89  //Compute the mapping change rate
90  mappingChangeRate = 0.0f;
91  int mappingSamplesCount = Mathf.Min( sampleCount, mappingChangeSamples.Length );
92  if ( mappingSamplesCount != 0 )
93  {
94  for ( int i = 0; i < mappingSamplesCount; ++i )
95  {
96  mappingChangeRate += mappingChangeSamples[i];
97  }
98  mappingChangeRate /= mappingSamplesCount;
99  }
100  }
101 
102 
103  //-------------------------------------------------
104  private void UpdateLinearMapping( Transform tr )
105  {
106  prevMapping = linearMapping.value;
107  linearMapping.value = Mathf.Clamp01( initialMappingOffset + CalculateLinearMapping( tr ) );
108 
109  mappingChangeSamples[sampleCount % mappingChangeSamples.Length] = ( 1.0f / Time.deltaTime ) * ( linearMapping.value - prevMapping );
110  sampleCount++;
111 
112  if ( repositionGameObject )
113  {
114  transform.position = Vector3.Lerp( startPosition.position, endPosition.position, linearMapping.value );
115  }
116  }
117 
118 
119  //-------------------------------------------------
120  private float CalculateLinearMapping( Transform tr )
121  {
122  Vector3 direction = endPosition.position - startPosition.position;
123  float length = direction.magnitude;
124  direction.Normalize();
125 
126  Vector3 displacement = tr.position - startPosition.position;
127 
128  return Vector3.Dot( displacement, direction ) / length;
129  }
130 
131 
132  //-------------------------------------------------
133  void Update()
134  {
135  if ( maintainMomemntum && mappingChangeRate != 0.0f )
136  {
137  //Dampen the mapping change rate and apply it to the mapping
138  mappingChangeRate = Mathf.Lerp( mappingChangeRate, 0.0f, momemtumDampenRate * Time.deltaTime );
139  linearMapping.value = Mathf.Clamp01( linearMapping.value + ( mappingChangeRate * Time.deltaTime ) );
140 
141  if ( repositionGameObject )
142  {
143  transform.position = Vector3.Lerp( startPosition.position, endPosition.position, linearMapping.value );
144  }
145  }
146  }
147  }
148 }