void Start()
        {
            touchBounds = new Bounds();
            int size = getTouchPoolSize();

            touches   = new List <depthTouch>();
            touchPool = new depthTouch[size];
            for (int i = 0; i < size; i++)
            {
                touchPool[i] = new depthTouch(i);
            }
        }
        void Update()                                                                      //rename his to getTouches?
        {
            if (pluginThread == null || !pluginThread.prepareTouches() || touches == null) //do this first.  if it gives false it means the plugin isn't even loaded.
            {
                return;
            }

            int count = pluginThread.getTouches(ref touchPool);

            touches.Clear();

            touchBounds = new Bounds();

            for (int i = 0; i < count; i++)
            {
                if (touchPool[i].getLocalPos() != Vector3.zero)
                {
                    touchBounds.Encapsulate(touchPool[i].getLocalPos());
                    touches.Add(touchPool[i]);
                }
            }

            //handle open/closed hand
            if (lastFrameTouchCount > 1 && touches.Count == 1) //determine close
            {
                Vector3 testPos = touches[0].getLocalPos();
                testPos.z = lastFrameBounds.center.z;  //invalidate testing the z;
                if (lastFrameBounds.Contains(testPos)) //if the single available touch is within the last  frame's touches bounds, call it a closed hand
                {
                    setHandState(false);
                }
            }
            else if (touches.Count > 2) //determine open
            {
                float openThresholdMeters = openThresholdCm * .01f;
                if ((touchBounds.size.x > openThresholdMeters) ||
                    (touchBounds.size.y > openThresholdMeters)) //note that Z is not tested here for determining open/close hand
                {
                    setHandState(true);
                }
            }


            //handle average positions
            averageNormalized = Vector3.zero;
            averageDiff       = Vector3.zero;

            depthTouch highX = null;
            depthTouch lowX  = null;
            depthTouch highY = null;
            depthTouch lowY  = null;

            //main touches are a way for us to stabilize the twist and scale outputs by not hopping around different touches, instead trying to calculate the values from the same touches if possible
            bool updateMainTouches = false;

            if (touches.Count > 1 && (mainTouchA == null || mainTouchB == null || mainTouchA.getLocalPos() == Vector3.zero || mainTouchB.getLocalPos() == Vector3.zero))
            {
                updateMainTouches = true;
            }

            int t = 0;

            for (int i = 0; i < touchPool.Length; i++)
            {
                if (touchPool[i].getLocalPos() != Vector3.zero)
                {
                    touches[t] = touchPool[i];//these are the touches that can be queried from hypercube.input.front.touches
                    t++;

                    averageNormalized += touchPool[i].getLocalPos();
                    averageDiff       += touchPool[i].getLocalDiff();

                    if (updateMainTouches)
                    {
                        if (highX == null || touchPool[i].getLocalPos().x > highX.getLocalPos().x)
                        {
                            highX = touchPool[i];
                        }
                        if (lowX == null || touchPool[i].getLocalPos().x < lowX.getLocalPos().x)
                        {
                            lowX = touchPool[i];
                        }
                        if (highY == null || touchPool[i].getLocalPos().y > highY.getLocalPos().y)
                        {
                            highY = touchPool[i];
                        }
                        if (lowY == null || touchPool[i].getLocalPos().y < lowY.getLocalPos().y)
                        {
                            lowY = touchPool[i];
                        }
                    }
                }
            }

            if (touches.Count < 2)
            {
                pinch          = 1f;
                lastTouchAngle = twist = 0f;
                mainTouchA     = mainTouchB = null;
                if (touches.Count == 0)
                {
                    averageNormalized = averageDiff = Vector3.zero;
                }
                else //1 touch only.
                {
                    averageNormalized = touches[0].getLocalPos();
                    averageDiff       = touches[0].getLocalDiff();
                }
            }
            else
            {
                averageNormalized /= (float)touches.Count;
                averageDiff       /= (float)touches.Count;

                if (averageDiff.x < -.3f || averageDiff.x > .3f || averageDiff.y < -.3f || averageDiff.y > .3) //this is too fast to be a real movement, its probably an artifact.
                {
                    averageDiff = Vector3.zero;
                }

                //pinch and twist
                if (updateMainTouches)
                {
                    if ((highX.getLocalPos().x - lowX.getLocalPos().x) > (highY.getLocalPos().y - lowY.getLocalPos().y))//use the bigger of the two differences, and then use the true distance
                    {
                        mainTouchA = highX;
                        mainTouchB = lowX;
                    }
                    else
                    {
                        mainTouchA = highY;
                        mainTouchB = lowY;
                    }
                }

                float angle = HoloPlaySDK.utils.angleBetweenPoints(mainTouchA.getLocalPos(), mainTouchB.getLocalPos());
                float size  = lastFrameBounds.size.x * lastFrameBounds.size.y;

                //validate everything coming out of here... ignore crazy values that may come from hardware artifacts.
                if (lastTouchAngle == 0)
                {
                    twist = 0;
                }
                else
                {
                    twist = lastTouchAngle - angle;
                }

                if (twist < -20f || twist > 20f) //more than 20 degrees in 1 frame?!.. most likely junk. toss it.
                {
                    twist = angle = 0f;
                }
                lastTouchAngle = angle;

                if (lastFrameBounds.size == Vector3.zero)
                {
                    pinch = 1f;
                }
                else
                {
                    pinch = size / lastSize;
                }

                if (pinch < .7f || pinch > 1.3f) //the chances that this is junk data coming from the touchscreen are very high. dump it.
                {
                    pinch = 1f;
                }

                lastSize = size;
            }

            lastFrameBounds     = touchBounds;
            lastFrameTouchCount = touches.Count;

            processDepthTouches(touches);
            processTextureStreams();
        }