public void _interface(touchInterface i)
        {
            if (!i.active) //deactivate this touch.
            {
                deactivate();
                return;
            }

            if (state < activationState.ACTIVE)
            {
                state         = activationState.TOUCHDOWN;
                touchDownTime = Time.timeSinceLevelLoad;

                _diffX = _diffY = _distX = _distY = 0f; //this is a touch down: we don't want to compare this to zeroed out values and get crazy values on the first frame active.
            }
            else
            {
                state  = activationState.ACTIVE;
                _diffX = i.normalizedPos.x - posX;
                _diffY = i.normalizedPos.y - posY;
                _distX = i.physicalPos.x - physicalPos.x;
                _distY = i.physicalPos.y - physicalPos.y;
            }

            _posX       = i.normalizedPos.x;
            _posY       = i.normalizedPos.y;
            physicalPos = i.physicalPos;

            touchScreenX = i.rawTouchScreenX;
            touchScreenY = i.rawTouchScreenY;

            id = i._id; //faster and easier to just set it all the time than check if this is a new touch or not.
        }
        public float getPhysicalDistanceTo(touch t)
        {
            touchInterface i = null;

            t._getInterface(ref i);
            return(Vector2.Distance(i.physicalPos, physicalPos));
        }
        public override void onTouchMoved(touch touch)
        {
            touchInterface i = new touchInterface();

            touch._getInterface(ref i);

            display.text = "Latest Values:\nx: " + i.rawTouchScreenX + "\ny: " + i.rawTouchScreenY;
        }
        public void _getInterface(ref touchInterface i)
        {
            i.normalizedPos.x = _posX;
            i.normalizedPos.y = _posY;

            i.physicalPos     = physicalPos;
            i.rawTouchScreenX = touchScreenX;
            i.rawTouchScreenY = touchScreenY;

            i._id = id;
            if (state < activationState.ACTIVE)
            {
                i.active = false;
            }
            else
            {
                i.active = true;
            }
        }
        public touchScreenInputManager(string _deviceName, SerialController _serial, bool _isFrontTouchScreen) : base(_serial, new byte[] { 255, 255 }, 1024)
        {
            firmwareVersion = -9999f;
            touches         = new touch[0];
            touchCount      = 0;
            pinch           = 1f;
            twist           = 0f;
            deviceName      = _deviceName;
            isFront         = _isFrontTouchScreen;

            for (int i = 0; i < touchPool.Length; i++)
            {
                touchPool[i] = new touch(isFront);
            }
            for (int i = 0; i < interfaces.Length; i++)
            {
                interfaces[i] = new touchInterface();
            }
            for (int i = 0; i < touchIdMap.Length; i++)
            {
                touchIdMap[i] = 0;
            }
        }
        public touchScreen(touchScreenOrientation _orientation)
        {
            touches           = new touch[0];
            touchCount        = 0;
            pinch             = 1f;
            twist             = 0f;
            screenOrientation = _orientation;

            active = false; //the first input causes it to activate.

            for (int i = 0; i < touchPool.Length; i++)
            {
                touchPool[i] = new touch();
            }
            for (int i = 0; i < interfaces.Length; i++)
            {
                interfaces[i]             = new touchInterface();
                interfaces[i].orientation = _orientation;
            }
            for (int i = 0; i < touchIdMap.Length; i++)
            {
                touchIdMap[i] = 0;
            }
        }
        void postProcessData()
        {
            touchCount = 0;
            for (int k = 0; k < maxTouches; k++)
            {
                if (interfaces[touchIdMap[k]].active)
                {
                    touchCount++;
                }
            }

            float averageNormalizedX = 0f;
            float averageNormalizedY = 0f;
            float averageDiffX       = 0f;
            float averageDiffY       = 0f;
            float averageDistX       = 0f;
            float averageDistY       = 0f;

            touchInterface highX = null;
            touchInterface lowX  = null;
            touchInterface highY = null;
            touchInterface lowY  = null;

            touches = new touch[touchCount];

            //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 (touchCount > 1 && (mainTouchA == null || mainTouchB == null || mainTouchA.active == false || mainTouchB.active == false))
            {
                updateMainTouches = true;
            }

            int t = 0;

            for (int i = 0; i < touchPoolSize; i++)
            {
                touchPool[i]._interface(interfaces[i]); //update and apply our new info to each touch.
                if (interfaces[i].active)
                {
                    touches[t] = touchPool[i];//these are the touches that can be queried from hypercube.input.front.touches
                    t++;

                    averageNormalizedX += touchPool[i].posX;
                    averageNormalizedY += touchPool[i].posY;
                    averageDiffX       += touchPool[i].diffX;
                    averageDiffY       += touchPool[i].diffY;
                    averageDistX       += touchPool[i].distX;
                    averageDistY       += touchPool[i].distY;

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

            if (touchCount < 2)
            {
                touchSize      = touchSizeCm = 0f;
                pinch          = 1f;
                lastTouchAngle = twist = 0f;
                mainTouchA     = mainTouchB = null;
                if (touchCount == 0)
                {
                    averagePos = averageDiff = averageDist = Vector2.zero;
                }
                else //1 touch only.
                {
                    averagePos  = new Vector2(touches[0].posX, touches[0].posY);
                    averageDiff = new Vector2(touches[0].diffX, touches[0].diffY);
                    averageDist = new Vector2(touches[0].distX, touches[0].distY);
                }
            }
            else
            {
                averagePos  = new Vector2(averageNormalizedX / (float)touchCount, averageNormalizedX / (float)touchCount);
                averageDiff = new Vector2(averageDiffX / (float)touchCount, averageDiffY / (float)touchCount);
                averageDist = new Vector2(averageDistX / (float)touchCount, averageDistY / (float)touchCount);

                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 = averageDist = Vector2.zero;
                }

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

                touchSizeCm = mainTouchA.getPhysicalDistance(mainTouchB);
                touchSize   = mainTouchA.getDistance(mainTouchB);

                float angle = angleBetweenPoints(mainTouchA.normalizedPos, mainTouchB.normalizedPos);


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

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

                if (lastSize == 0f)
                {
                    pinch = 1f;
                }
                else
                {
                    pinch = touchSizeCm / 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 = touchSizeCm;
            }

            //finally, send off the events to touchScreenTargets.
            for (int i = 0; i < touchPoolSize; i++)
            {
                if (touchPool[i].state != touch.activationState.DESTROYED)
                {
                    input._processTouchScreenEvent(touchPool[i]);
                }
            }
        }
 public float getPhysicalDistance(touchInterface i)
 {
     return(Vector2.Distance(physicalPos, i.physicalPos));
 }
 public float getDistance(touchInterface i)
 {
     return(Vector2.Distance(normalizedPos, i.normalizedPos));
 }