1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.example.android.rs.vr.engine;
18
19import android.util.Log;
20
21import java.text.DecimalFormat;
22
23/**
24 * code to manage transformations between world screen and volume space.
25 */
26public class Transform {
27    public final static char WORLD_SPACE = 0;
28    public final static char SCREEN_SPACE = 1;
29    public final static char VOLUME_SPACE = 2;
30    private static final String LOGTAG = "Transform";
31
32    Matrix[][] mAllMat = new Matrix[3][3];
33    public ViewMatrix mViewMatrix = new ViewMatrix();
34    float[] mVoxelDim = new float[3];
35
36    public void clone(Transform src) {
37        System.arraycopy(src.mVoxelDim, 0, mVoxelDim, 0, mVoxelDim.length);
38        mViewMatrix.clone(src.mViewMatrix);
39        updateAllMatrix();
40    }
41
42    public void updateAllMatrix() {
43        mViewMatrix.calcMatrix();
44        Matrix m = new Matrix();
45        m.setToUnit();
46        mAllMat[0][0] = m;
47        mAllMat[1][1] = m;
48        mAllMat[2][2] = m;
49        mAllMat[SCREEN_SPACE][WORLD_SPACE] = new Matrix(mViewMatrix);
50        mAllMat[WORLD_SPACE][SCREEN_SPACE] = mViewMatrix.invers();
51        m = new Matrix();
52        m.setToUnit();
53        if (mVoxelDim[0] > 0) {
54            int min = 0;
55
56            m.m[0] = 1 / mVoxelDim[0];
57            m.m[5] = 1 / mVoxelDim[1];
58            m.m[10] = 1 / mVoxelDim[2];
59        }
60        mAllMat[WORLD_SPACE][VOLUME_SPACE] = m;
61        mAllMat[VOLUME_SPACE][WORLD_SPACE] = m.invers();
62        mAllMat[SCREEN_SPACE][VOLUME_SPACE] = m = m.premult(mViewMatrix);
63        mAllMat[VOLUME_SPACE][SCREEN_SPACE] = m.invers();
64
65    }
66
67    public void setVoxelDim(float[] volDim) {
68        mVoxelDim[0] = volDim[0];
69        mVoxelDim[1] = volDim[1];
70        mVoxelDim[2] = volDim[2];
71    }
72
73    public Matrix getMatrix(char from, char to) {
74        return mAllMat[from][to];
75    }
76
77    public void setScreenDim(int x, int y) {
78        mViewMatrix.setScreenDim(x, y);
79        updateAllMatrix();
80    }
81
82    public double[] getLookPoint() {
83        return mViewMatrix.getLookPoint();
84    }
85
86    public void setLookPoint(double[] mLookPoint) {
87        mViewMatrix.setLookPoint(mLookPoint);
88        updateAllMatrix();
89    }
90
91    public double[] getEyePoint() {
92        return mViewMatrix.getEyePoint();
93    }
94
95    public void setEyePoint(double[] mEyePoint) {
96        mViewMatrix.setEyePoint(mEyePoint);
97        updateAllMatrix();
98    }
99
100    public double[] getUpVector() {
101        return mViewMatrix.getUpVector();
102    }
103
104    public void setUpVector(double[] mUpVector) {
105        mViewMatrix.setUpVector(mUpVector);
106        updateAllMatrix();
107    }
108
109    public double getScreenWidth() {
110        return mViewMatrix.getScreenWidth();
111    }
112
113    public void setScreenWidth(double screenWidth) {
114        mViewMatrix.setScreenWidth(screenWidth);
115        updateAllMatrix();
116    }
117
118    public void lookAt(TriData tri, int w, int h) {
119        mViewMatrix.lookAt(tri, mVoxelDim, w, h);
120        updateAllMatrix();
121    }
122
123    public void look(char dir, TriData tri, int w, int h) {
124        mViewMatrix.look(dir, tri, mVoxelDim, w, h);
125        updateAllMatrix();
126    }
127
128    public void trackBallUp(float x, float y) {
129        mViewMatrix.trackBallUP(x, y);
130        updateAllMatrix();
131    }
132
133    public void trackBallDown(float x, float y) {
134        mViewMatrix.trackBallDown(x, y);
135    }
136
137    public void trackBallMove(float x, float y) {
138        mViewMatrix.trackBallMove(x, y);
139        updateAllMatrix();
140    }
141
142    static DecimalFormat df = new DecimalFormat("      ##0.000");
143
144    private static String trim(double d) {
145        String s = df.format(d);
146        return s.substring(s.length() - 6);
147    }
148
149    public static void print(float[] d) {
150        String s = "";
151        for (int i = 0; i < d.length; i++) {
152            s += (((i == 0) ? "[ " : " , ") + trim(d[i]));
153        }
154        Log.v(LOGTAG, s + "]");
155    }
156
157    public static void main(String[] args) {
158        int[] voldim = {50, 50, 100};
159        double[] mEyePoint = {voldim[0] / 2., -voldim[1] / 2., voldim[2] / 2.};
160        double[] mLookPoint = {voldim[0] / 2., voldim[1] / 2., voldim[2] / 2.};
161        double[] mUpVector = {0., 0., 1.};
162
163        Transform t = new Transform();
164        t.mVoxelDim[0] = 1;
165        t.setEyePoint(mEyePoint);
166        t.setLookPoint(mLookPoint);
167        t.setUpVector(mUpVector);
168        t.setScreenDim(256, 256);
169        t.setScreenWidth(128);
170        t.updateAllMatrix();
171
172        Matrix m = t.getMatrix(SCREEN_SPACE, VOLUME_SPACE);
173        float[] orig = {.5f, .5f, 0};
174        float[] ret = new float[3];
175
176        m.mult3(orig, ret);
177        print(ret);
178        float[] look = {0, 0, 1};
179        m.mult3v(look, ret);
180        print(ret);
181        float[] up = {1, 0, 0};
182        m.mult3v(up, ret);
183        print(ret);
184        float[] right = {0, 1, 0};
185        m.mult3v(right, ret);
186        print(ret);
187
188    }
189
190    public void print() {
191        Log.v(LOGTAG, "==== =========== VIEW ========== ======");
192
193        mViewMatrix.print();
194        Log.v(LOGTAG, "==== SCREEN_SPACE to WORLD_SPACE ======");
195        mAllMat[SCREEN_SPACE][WORLD_SPACE].print();
196        Log.v(LOGTAG, "==== SCREEN_SPACE to VOLUME_SPACE ======");
197        mAllMat[SCREEN_SPACE][VOLUME_SPACE].print();
198        Log.v(LOGTAG, "==== WORLD_SPACE to VOLUME_SPACE ======");
199        mAllMat[WORLD_SPACE][VOLUME_SPACE].print();
200        Log.v(LOGTAG, "==== WORLD_SPACE to SCREEN_SPACE ======");
201        mAllMat[WORLD_SPACE][SCREEN_SPACE].print();
202        Log.v(LOGTAG, "==== VOLUME_SPACE to SCREEN_SPACE ======");
203        mAllMat[VOLUME_SPACE][SCREEN_SPACE].print();
204        Log.v(LOGTAG, "==== VOLUME_SPACE to WORLD_SPACE ======");
205        mAllMat[VOLUME_SPACE][WORLD_SPACE].print();
206        Log.v(LOGTAG, "=======================================");
207    }
208}