//compares projected world points to the expected corner points and calculates the total square distance
    private static float CalcValue(KeystoningSpecification spec, Camera camera, Matrix4x4 originalProjectionMatrix, KeystoningCorners corners, RUISDisplay display, bool firstPhase)//, Vector3[] worldPoints)
    {
        Vector2[] untransformedCorners = KeystoningCorners.untransformedCorners;

        float distanceFromCorners = 0; // sum of squared distances
        for (int pnum = 0; pnum < 4; pnum++)
        {
            // transformed coordinates (should match ’corners’ as good
            // as possible)
            float w = spec.m * untransformedCorners[pnum].x + spec.n * untransformedCorners[pnum].y + 1;
            float tx = (spec.a * untransformedCorners[pnum].x + spec.b * untransformedCorners[pnum].y + spec.d) / w;
            float ty = (spec.e * untransformedCorners[pnum].x + spec.f * untransformedCorners[pnum].y + spec.h) / w;
            
            Vector2 transformedCorner = corners.GetCornerNormalizedViewpointCoordinates(pnum);
            distanceFromCorners += Vector2.SqrMagnitude(new Vector2(tx, ty) - transformedCorner);
            
            if (float.IsNaN(distanceFromCorners))
            {
                Debug.Log("was nan " + w + " " + pnum + " " + tx + " " + ty);
                break;
            }
        }

        

        return distanceFromCorners;
        
        //Debug.Log(CreateKeystonedMatrix(a, b, d, e, f, h, m, n));
        //camera.projectionMatrix = originalProjectionMatrix * spec.GetMatrix();


        
        /*Vector2[] newPoints = new Vector2[worldPoints.Length];
        for(int i = 0; i < worldPoints.Length; i++)
        {
            newPoints[i] = camera.WorldToViewportPoint(worldPoints[i]);
        }*/

        /*Vector2[] newPoints = new Vector2[10];
        newPoints[0] = camera.WorldToViewportPoint(display.TopLeftPosition);
        newPoints[1] = camera.WorldToViewportPoint(display.TopRightPosition);
        newPoints[2] = camera.WorldToViewportPoint(display.BottomRightPosition);
        newPoints[3] = camera.WorldToViewportPoint(display.BottomLeftPosition);
        newPoints[4] = camera.WorldToViewportPoint(display.displayCenterPosition);
		newPoints[5] = camera.WorldToViewportPoint(display.TopLeftPosition + (display.TopLeftPosition - camera.transform.position) * 10);
        newPoints[6] = camera.WorldToViewportPoint(display.TopRightPosition + (display.TopRightPosition - camera.transform.position) * 10);
        newPoints[7] = camera.WorldToViewportPoint(display.BottomRightPosition + (display.BottomRightPosition - camera.transform.position) * 10);
        newPoints[8] = camera.WorldToViewportPoint(display.BottomLeftPosition + (display.BottomLeftPosition - camera.transform.position) * 10);
        newPoints[9] = camera.WorldToViewportPoint(display.displayCenterPosition + (display.displayCenterPosition - camera.transform.position) * 10);
        

        float distanceFromCorners = 0; // sum of squared distances
        for (int i = 0; i < (firstPhase ? 3 : 4); i++)
        {
            distanceFromCorners += (corners[i] - newPoints[i]).sqrMagnitude;
            distanceFromCorners += (corners[i] - newPoints[i+5]).sqrMagnitude;
        }

        if(!firstPhase){
            Vector2 diagonalCenter = corners.GetDiagonalCenter();
            distanceFromCorners += (diagonalCenter - newPoints[4]).sqrMagnitude;
			distanceFromCorners += (diagonalCenter - newPoints[9]).sqrMagnitude;
        }
        //distanceFromCorners += (diagonalCenter - newPoints[9]).sqrMagnitude;

        return distanceFromCorners;*/


    }
Example #2
0
    //compares projected world points to the expected corner points and calculates the total square distance
    private static float CalcValue(KeystoningSpecification spec, Camera camera, Matrix4x4 originalProjectionMatrix, KeystoningCorners corners, RUISDisplay display, bool firstPhase)//, Vector3[] worldPoints)
    {
        Vector2[] untransformedCorners = KeystoningCorners.untransformedCorners;

        float distanceFromCorners = 0; // sum of squared distances

        for (int pnum = 0; pnum < 4; pnum++)
        {
            // transformed coordinates (should match ’corners’ as good
            // as possible)
            float w  = spec.m * untransformedCorners[pnum].x + spec.n * untransformedCorners[pnum].y + 1;
            float tx = (spec.a * untransformedCorners[pnum].x + spec.b * untransformedCorners[pnum].y + spec.d) / w;
            float ty = (spec.e * untransformedCorners[pnum].x + spec.f * untransformedCorners[pnum].y + spec.h) / w;

            Vector2 transformedCorner = corners.GetCornerNormalizedViewpointCoordinates(pnum);
            distanceFromCorners += Vector2.SqrMagnitude(new Vector2(tx, ty) - transformedCorner);

            if (float.IsNaN(distanceFromCorners))
            {
                Debug.Log("was nan " + w + " " + pnum + " " + tx + " " + ty);
                break;
            }
        }



        return(distanceFromCorners);

        //Debug.Log(CreateKeystonedMatrix(a, b, d, e, f, h, m, n));
        //camera.projectionMatrix = originalProjectionMatrix * spec.GetMatrix();



        /*Vector2[] newPoints = new Vector2[worldPoints.Length];
         * for(int i = 0; i < worldPoints.Length; i++)
         * {
         *  newPoints[i] = camera.WorldToViewportPoint(worldPoints[i]);
         * }*/

        /*Vector2[] newPoints = new Vector2[10];
         * newPoints[0] = camera.WorldToViewportPoint(display.TopLeftPosition);
         * newPoints[1] = camera.WorldToViewportPoint(display.TopRightPosition);
         * newPoints[2] = camera.WorldToViewportPoint(display.BottomRightPosition);
         * newPoints[3] = camera.WorldToViewportPoint(display.BottomLeftPosition);
         * newPoints[4] = camera.WorldToViewportPoint(display.displayCenterPosition);
         *      newPoints[5] = camera.WorldToViewportPoint(display.TopLeftPosition + (display.TopLeftPosition - camera.transform.position) * 10);
         * newPoints[6] = camera.WorldToViewportPoint(display.TopRightPosition + (display.TopRightPosition - camera.transform.position) * 10);
         * newPoints[7] = camera.WorldToViewportPoint(display.BottomRightPosition + (display.BottomRightPosition - camera.transform.position) * 10);
         * newPoints[8] = camera.WorldToViewportPoint(display.BottomLeftPosition + (display.BottomLeftPosition - camera.transform.position) * 10);
         * newPoints[9] = camera.WorldToViewportPoint(display.displayCenterPosition + (display.displayCenterPosition - camera.transform.position) * 10);
         *
         *
         * float distanceFromCorners = 0; // sum of squared distances
         * for (int i = 0; i < (firstPhase ? 3 : 4); i++)
         * {
         *  distanceFromCorners += (corners[i] - newPoints[i]).sqrMagnitude;
         *  distanceFromCorners += (corners[i] - newPoints[i+5]).sqrMagnitude;
         * }
         *
         * if(!firstPhase){
         *  Vector2 diagonalCenter = corners.GetDiagonalCenter();
         *  distanceFromCorners += (diagonalCenter - newPoints[4]).sqrMagnitude;
         *              distanceFromCorners += (diagonalCenter - newPoints[9]).sqrMagnitude;
         * }
         * //distanceFromCorners += (diagonalCenter - newPoints[9]).sqrMagnitude;
         *
         * return distanceFromCorners;*/
    }
    public static float Optimize(Camera camera, Matrix4x4 originalProjectionMatrix, RUISDisplay display, KeystoningCorners corners, ref KeystoningSpecification spec)
    {
        if (!spec.isValid) Debug.Log("INVALID SPEC");
        spec = /*spec != null && spec.isValid ? spec : */new KeystoningSpecification();

        //Debug.Log(spec.GetMatrix());

        //save all the relevant world points that we use for optimizing the keystoning matrix
        //camera.projectionMatrix = originalProjectionMatrix;
        /*Vector3[] worldPoints = new Vector3[10];
        worldPoints[0] = camera.ViewportToWorldPoint(new Vector3(0, 1, camera.nearClipPlane));
        worldPoints[1] = camera.ViewportToWorldPoint(new Vector3(1, 1, camera.nearClipPlane));
        worldPoints[2] = camera.ViewportToWorldPoint(new Vector3(1, 0, camera.nearClipPlane));
        worldPoints[3] = camera.ViewportToWorldPoint(new Vector3(0, 0, camera.nearClipPlane));
        worldPoints[4] = camera.ViewportToWorldPoint(new Vector3(0, 1, camera.farClipPlane));
        worldPoints[5] = camera.ViewportToWorldPoint(new Vector3(1, 1, camera.farClipPlane));
        worldPoints[6] = camera.ViewportToWorldPoint(new Vector3(1, 0, camera.farClipPlane));
        worldPoints[7] = camera.ViewportToWorldPoint(new Vector3(0, 0, camera.farClipPlane));
        worldPoints[8] = camera.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, camera.nearClipPlane));
        worldPoints[9] = camera.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, camera.farClipPlane));
        */
        /*Debug.Log("---------------------------------------------------------------");
        foreach (Vector3 worldPoint in worldPoints)
        {
            Debug.Log(worldPoint);
            Debug.Log(camera.WorldToViewportPoint(worldPoint));
        }
        Debug.Log("--------------------------------------------------------------");*/

        float stepSize = 0.1f;
        float[] grad = new float[amountOfParameters];

        float currentValue = 0;
        /*while (stepSize > 0.000001f)
        {
            // compute gradient

            currentValue = CalcValue(spec, camera, originalProjectionMatrix, corners, display, true);
            

            Debug.Log("**********************************************");
            foreach (Vector3 worldPoint in worldPoints)
            {
                Debug.Log(camera.WorldToViewportPoint(worldPoint));
            }
            Debug.Log("**********************************************");
            
            //Debug.Log(currentValue);
            for (int i = 0; i < amountOfParameters-2; i++)
            {
                grad[i] = CalcValue(spec.ModifyWithStep(i, 0.1f * stepSize), camera, originalProjectionMatrix, corners, display, true) - currentValue;
            }

            // step in direction of gradient with length of stepSize
            float gradSquaredLength = 0;
            for (int i = 0; i < amountOfParameters-2; i++)
            {
                gradSquaredLength += grad[i] * grad[i];
            }
            float gradLength = Mathf.Sqrt((float)gradSquaredLength);
            for (int i = 0; i < amountOfParameters-2; i++)
            {
                spec = spec.ModifyWithStep(i, -stepSize * grad[i] / gradLength);
            }
            stepSize *= 0.99f;
        }
        */
        stepSize = 0.1f;
        grad = new float[amountOfParameters];
        currentValue = 0;
        while (stepSize > 0.000001f) 
        //for(int iterations = 0; iterations < 10; iterations++)
        {
            // compute gradient

            currentValue = CalcValue(spec, camera, originalProjectionMatrix, corners, display, false);
            for (int i = 0; i < amountOfParameters; i++)
            {
                grad[i] = CalcValue(spec.ModifyWithStep(i, 0.1f * stepSize), camera, originalProjectionMatrix, corners, display, false) - currentValue;
            }

            // step in direction of gradient with length of stepSize
            float gradSquaredLength = 0;
            for (int i = 0; i < amountOfParameters; i++)
            {
                gradSquaredLength += grad[i] * grad[i];
            }
            float gradLength = Mathf.Sqrt((float)gradSquaredLength);
            if (gradLength == 0) Debug.Log("CAUTIOOOOOOOOOOOOON");
            for (int i = 0; i < amountOfParameters; i++)
            {
                spec = spec.ModifyWithStep(i, -stepSize * grad[i] / gradLength);
            }
            stepSize *= 0.99f;
        }
        
        //Debug.Log("final: " + spec.GetMatrix());
        //Debug.Log("currentValue: " + currentValue);
        return currentValue;
    }
Example #4
0
    public static float Optimize(Camera camera, Matrix4x4 originalProjectionMatrix, RUISDisplay display, KeystoningCorners corners, ref KeystoningSpecification spec)
    {
        if (!spec.isValid)
        {
            Debug.Log("INVALID SPEC");
        }
        spec = /*spec != null && spec.isValid ? spec : */ new KeystoningSpecification();

        //Debug.Log(spec.GetMatrix());

        //save all the relevant world points that we use for optimizing the keystoning matrix
        //camera.projectionMatrix = originalProjectionMatrix;

        /*Vector3[] worldPoints = new Vector3[10];
         * worldPoints[0] = camera.ViewportToWorldPoint(new Vector3(0, 1, camera.nearClipPlane));
         * worldPoints[1] = camera.ViewportToWorldPoint(new Vector3(1, 1, camera.nearClipPlane));
         * worldPoints[2] = camera.ViewportToWorldPoint(new Vector3(1, 0, camera.nearClipPlane));
         * worldPoints[3] = camera.ViewportToWorldPoint(new Vector3(0, 0, camera.nearClipPlane));
         * worldPoints[4] = camera.ViewportToWorldPoint(new Vector3(0, 1, camera.farClipPlane));
         * worldPoints[5] = camera.ViewportToWorldPoint(new Vector3(1, 1, camera.farClipPlane));
         * worldPoints[6] = camera.ViewportToWorldPoint(new Vector3(1, 0, camera.farClipPlane));
         * worldPoints[7] = camera.ViewportToWorldPoint(new Vector3(0, 0, camera.farClipPlane));
         * worldPoints[8] = camera.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, camera.nearClipPlane));
         * worldPoints[9] = camera.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, camera.farClipPlane));
         */
        /*Debug.Log("---------------------------------------------------------------");
         * foreach (Vector3 worldPoint in worldPoints)
         * {
         *  Debug.Log(worldPoint);
         *  Debug.Log(camera.WorldToViewportPoint(worldPoint));
         * }
         * Debug.Log("--------------------------------------------------------------");*/

        float stepSize = 0.1f;

        float[] grad = new float[amountOfParameters];

        float currentValue = 0;

        /*while (stepSize > 0.000001f)
         * {
         *  // compute gradient
         *
         *  currentValue = CalcValue(spec, camera, originalProjectionMatrix, corners, display, true);
         *
         *
         *  Debug.Log("**********************************************");
         *  foreach (Vector3 worldPoint in worldPoints)
         *  {
         *      Debug.Log(camera.WorldToViewportPoint(worldPoint));
         *  }
         *  Debug.Log("**********************************************");
         *
         *  //Debug.Log(currentValue);
         *  for (int i = 0; i < amountOfParameters-2; i++)
         *  {
         *      grad[i] = CalcValue(spec.ModifyWithStep(i, 0.1f * stepSize), camera, originalProjectionMatrix, corners, display, true) - currentValue;
         *  }
         *
         *  // step in direction of gradient with length of stepSize
         *  float gradSquaredLength = 0;
         *  for (int i = 0; i < amountOfParameters-2; i++)
         *  {
         *      gradSquaredLength += grad[i] * grad[i];
         *  }
         *  float gradLength = Mathf.Sqrt((float)gradSquaredLength);
         *  for (int i = 0; i < amountOfParameters-2; i++)
         *  {
         *      spec = spec.ModifyWithStep(i, -stepSize * grad[i] / gradLength);
         *  }
         *  stepSize *= 0.99f;
         * }
         */
        stepSize     = 0.1f;
        grad         = new float[amountOfParameters];
        currentValue = 0;
        while (stepSize > 0.000001f)
        //for(int iterations = 0; iterations < 10; iterations++)
        {
            // compute gradient

            currentValue = CalcValue(spec, camera, originalProjectionMatrix, corners, display, false);
            for (int i = 0; i < amountOfParameters; i++)
            {
                grad[i] = CalcValue(spec.ModifyWithStep(i, 0.1f * stepSize), camera, originalProjectionMatrix, corners, display, false) - currentValue;
            }

            // step in direction of gradient with length of stepSize
            float gradSquaredLength = 0;
            for (int i = 0; i < amountOfParameters; i++)
            {
                gradSquaredLength += grad[i] * grad[i];
            }
            float gradLength = Mathf.Sqrt((float)gradSquaredLength);
            if (gradLength == 0)
            {
                Debug.Log("CAUTIOOOOOOOOOOOOON");
            }
            for (int i = 0; i < amountOfParameters; i++)
            {
                spec = spec.ModifyWithStep(i, -stepSize * grad[i] / gradLength);
            }
            stepSize *= 0.99f;
        }

        //Debug.Log("final: " + spec.GetMatrix());
        //Debug.Log("currentValue: " + currentValue);
        return(currentValue);
    }