Exemplo n.º 1
0
        private IEnumerator CalculateViewsRoutine(Action <List <string>, Dictionary <int, Texture2D> > callback)
        {
            yield return(Yielders.EndOfFrame); // Finish previous frame...

            List <string> viewsLines = new List <string>();
            Dictionary <int, Texture2D> viewsBilboards = new Dictionary <int, Texture2D>();

            int total   = 2 * (N_VIEWS * N_VIEWS + N_VIEWS) + 1;
            int current = 0;

            double zmax = Math.Abs(Z);
            double zmin = -Math.Abs(Z);

            for (int i = -N_VIEWS; i <= N_VIEWS; i++)
            {
                for (int j = -N_VIEWS + Math.Abs(i); j <= N_VIEWS - Math.Abs(i); ++j)
                {
                    double x     = (i + j) / (double)N_VIEWS;
                    double y     = (j - i) / (double)N_VIEWS;
                    double angle = 90.0 - Math.Max(Math.Abs(x), Math.Abs(y)) * 90.0;
                    double alpha = x.EpsilonEquals(0.0, 0.00000001) && y.EpsilonEquals(0.0, 0.00000001) ? 0.0f : Math.Atan2(y, x) / Math.PI * 180.0;

                    Matrix4x4d cameraToWorld = Matrix4x4d.RotateX(90) * Matrix4x4d.RotateX(angle);
                    Matrix4x4d worldToCamera = cameraToWorld.Inverse();

                    Box3d b = new Box3d();
                    b = b.Enlarge((worldToCamera * new Vector4d(-1.0, -1.0, zmin, 1.0)).xyz);
                    b = b.Enlarge((worldToCamera * new Vector4d(+1.0, -1.0, zmin, 1.0)).xyz);
                    b = b.Enlarge((worldToCamera * new Vector4d(-1.0, +1.0, zmin, 1.0)).xyz);
                    b = b.Enlarge((worldToCamera * new Vector4d(+1.0, +1.0, zmin, 1.0)).xyz);
                    b = b.Enlarge((worldToCamera * new Vector4d(-1.0, -1.0, zmax, 1.0)).xyz);
                    b = b.Enlarge((worldToCamera * new Vector4d(+1.0, -1.0, zmax, 1.0)).xyz);
                    b = b.Enlarge((worldToCamera * new Vector4d(-1.0, +1.0, zmax, 1.0)).xyz);
                    b = b.Enlarge((worldToCamera * new Vector4d(+1.0, +1.0, zmax, 1.0)).xyz);

                    Matrix4x4d c2s = Matrix4x4d.Ortho(b.Max.x, b.Min.x, b.Max.y, b.Min.y, -2.0 * b.Max.z, -2.0 * b.Min.z + S);
                    Matrix4x4d w2s = c2s * worldToCamera * Matrix4x4d.RotateZ(-90 - alpha);

                    Vector3d dir = ((Matrix4x4d.RotateZ(90 + alpha) * cameraToWorld) * new Vector4d(0.0, 0.0, 1.0, 0.0)).xyz;

                    ViewMaterial.SetTexture("colorSampler", TreeSampler);
                    ViewMaterial.SetVector("dir", dir.ToVector3());
                    ViewMaterial.SetMatrix("worldToScreen", w2s.ToMatrix4x4());

                    Camera.main.projectionMatrix = w2s.ToMatrix4x4();

                    ViewMaterial.SetPass(0);
                    Graphics.DrawMeshNow(PreProcessMesh, Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one));

                    ViewMaterial.SetPass(1);
                    Graphics.DrawMeshNow(PreProcessMesh, Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one));

                    yield return(Yielders.EndOfFrame); // Finish this frame...

                    var texture = new Texture2D(GRIDRES_VIEWS, GRIDRES_VIEWS, TextureFormat.RGBAFloat, false, true);

                    texture.ReadPixels(new Rect(0, 0, GRIDRES_VIEWS, GRIDRES_VIEWS), 0, 0, false);
                    texture.Apply(false);

                    viewsBilboards.Add(current, texture);

                    var view = i * (1 - Math.Abs(i)) + j + 2 * N_VIEWS * i + N_VIEWS * (N_VIEWS + 1);

                    RTUtility.ClearColor(RenderTexture.active);

                    current++;

                    Debug.Log(string.Format("Precomputing Views Step {0} of {1} : View {2}", current, total, view));

                    viewsLines.Add(string.Format("{0}f,{1}f,{2}f,{3}f,{4}f,{5}f,{6}f,{7}f,{8}f,", (float)w2s.m[0, 0], (float)w2s.m[0, 1], (float)w2s.m[0, 2],
                                                 (float)w2s.m[1, 0], (float)w2s.m[1, 1], (float)w2s.m[1, 2],
                                                 (float)w2s.m[2, 0], (float)w2s.m[2, 1], (float)w2s.m[2, 2]));
                }
            }

            if (callback != null)
            {
                callback(viewsLines, viewsBilboards);
            }
        }