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 
17 package com.example.android.rs.vr.engine;
18 
19 import android.util.Log;
20 
21 import java.text.DecimalFormat;
22 
23 /**
24  * code to manage transformations between world screen and volume space.
25  */
26 public 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 
clone(Transform src)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 
updateAllMatrix()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 
setVoxelDim(float[] volDim)67     public void setVoxelDim(float[] volDim) {
68         mVoxelDim[0] = volDim[0];
69         mVoxelDim[1] = volDim[1];
70         mVoxelDim[2] = volDim[2];
71     }
72 
getMatrix(char from, char to)73     public Matrix getMatrix(char from, char to) {
74         return mAllMat[from][to];
75     }
76 
setScreenDim(int x, int y)77     public void setScreenDim(int x, int y) {
78         mViewMatrix.setScreenDim(x, y);
79         updateAllMatrix();
80     }
81 
getLookPoint()82     public double[] getLookPoint() {
83         return mViewMatrix.getLookPoint();
84     }
85 
setLookPoint(double[] mLookPoint)86     public void setLookPoint(double[] mLookPoint) {
87         mViewMatrix.setLookPoint(mLookPoint);
88         updateAllMatrix();
89     }
90 
getEyePoint()91     public double[] getEyePoint() {
92         return mViewMatrix.getEyePoint();
93     }
94 
setEyePoint(double[] mEyePoint)95     public void setEyePoint(double[] mEyePoint) {
96         mViewMatrix.setEyePoint(mEyePoint);
97         updateAllMatrix();
98     }
99 
getUpVector()100     public double[] getUpVector() {
101         return mViewMatrix.getUpVector();
102     }
103 
setUpVector(double[] mUpVector)104     public void setUpVector(double[] mUpVector) {
105         mViewMatrix.setUpVector(mUpVector);
106         updateAllMatrix();
107     }
108 
getScreenWidth()109     public double getScreenWidth() {
110         return mViewMatrix.getScreenWidth();
111     }
112 
setScreenWidth(double screenWidth)113     public void setScreenWidth(double screenWidth) {
114         mViewMatrix.setScreenWidth(screenWidth);
115         updateAllMatrix();
116     }
117 
lookAt(TriData tri, int w, int h)118     public void lookAt(TriData tri, int w, int h) {
119         mViewMatrix.lookAt(tri, mVoxelDim, w, h);
120         updateAllMatrix();
121     }
122 
look(char dir, TriData tri, int w, int h)123     public void look(char dir, TriData tri, int w, int h) {
124         mViewMatrix.look(dir, tri, mVoxelDim, w, h);
125         updateAllMatrix();
126     }
127 
trackBallUp(float x, float y)128     public void trackBallUp(float x, float y) {
129         mViewMatrix.trackBallUP(x, y);
130         updateAllMatrix();
131     }
132 
trackBallDown(float x, float y)133     public void trackBallDown(float x, float y) {
134         mViewMatrix.trackBallDown(x, y);
135     }
136 
trackBallMove(float x, float y)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 
trim(double d)144     private static String trim(double d) {
145         String s = df.format(d);
146         return s.substring(s.length() - 6);
147     }
148 
print(float[] d)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 
main(String[] args)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 
print()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 }