15b539461dcc159bd89297443780d635ccc5e3564John Hoford/*
25b539461dcc159bd89297443780d635ccc5e3564John Hoford * Copyright (C) 2015 The Android Open Source Project
35b539461dcc159bd89297443780d635ccc5e3564John Hoford *
45b539461dcc159bd89297443780d635ccc5e3564John Hoford * Licensed under the Apache License, Version 2.0 (the "License");
55b539461dcc159bd89297443780d635ccc5e3564John Hoford * you may not use this file except in compliance with the License.
65b539461dcc159bd89297443780d635ccc5e3564John Hoford * You may obtain a copy of the License at
75b539461dcc159bd89297443780d635ccc5e3564John Hoford *
85b539461dcc159bd89297443780d635ccc5e3564John Hoford *      http://www.apache.org/licenses/LICENSE-2.0
95b539461dcc159bd89297443780d635ccc5e3564John Hoford *
105b539461dcc159bd89297443780d635ccc5e3564John Hoford * Unless required by applicable law or agreed to in writing, software
115b539461dcc159bd89297443780d635ccc5e3564John Hoford * distributed under the License is distributed on an "AS IS" BASIS,
125b539461dcc159bd89297443780d635ccc5e3564John Hoford * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135b539461dcc159bd89297443780d635ccc5e3564John Hoford * See the License for the specific language governing permissions and
145b539461dcc159bd89297443780d635ccc5e3564John Hoford * limitations under the License.
155b539461dcc159bd89297443780d635ccc5e3564John Hoford */
165b539461dcc159bd89297443780d635ccc5e3564John Hoford
175b539461dcc159bd89297443780d635ccc5e3564John Hofordpackage com.example.android.rs.vr.engine;
185b539461dcc159bd89297443780d635ccc5e3564John Hoford
195b539461dcc159bd89297443780d635ccc5e3564John Hofordimport android.util.Log;
205b539461dcc159bd89297443780d635ccc5e3564John Hoford
215b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.text.DecimalFormat;
225b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.util.Arrays;
235b539461dcc159bd89297443780d635ccc5e3564John Hoford
245b539461dcc159bd89297443780d635ccc5e3564John Hofordpublic class ViewMatrix extends Matrix {
255b539461dcc159bd89297443780d635ccc5e3564John Hoford    private static final String LOGTAG = "ViewMatrix";
265b539461dcc159bd89297443780d635ccc5e3564John Hoford    private double[] mLookPoint;
275b539461dcc159bd89297443780d635ccc5e3564John Hoford    private double[] mEyePoint;
285b539461dcc159bd89297443780d635ccc5e3564John Hoford    private double[] mUpVector;
295b539461dcc159bd89297443780d635ccc5e3564John Hoford    private double mScreenWidth;
305b539461dcc159bd89297443780d635ccc5e3564John Hoford    private int[] mScreenDim;
315b539461dcc159bd89297443780d635ccc5e3564John Hoford
325b539461dcc159bd89297443780d635ccc5e3564John Hoford    private Matrix mStartMatrix;
335b539461dcc159bd89297443780d635ccc5e3564John Hoford    private double[] mStartV = new double[3];
345b539461dcc159bd89297443780d635ccc5e3564John Hoford    private double[] mMoveToV = new double[3];
355b539461dcc159bd89297443780d635ccc5e3564John Hoford    private double[] mStartEyePoint;
365b539461dcc159bd89297443780d635ccc5e3564John Hoford    private double[] mStartUpVector;
375b539461dcc159bd89297443780d635ccc5e3564John Hoford    private Quaternion mQ = new Quaternion(0, 0, 0, 0);
385b539461dcc159bd89297443780d635ccc5e3564John Hoford
395b539461dcc159bd89297443780d635ccc5e3564John Hoford    public final static char UP_AT = 0x001;
405b539461dcc159bd89297443780d635ccc5e3564John Hoford    public final static char DOWN_AT = 0x002;
415b539461dcc159bd89297443780d635ccc5e3564John Hoford    public final static char RIGHT_AT = 0x010;
425b539461dcc159bd89297443780d635ccc5e3564John Hoford    public final static char LEFT_AT = 0x020;
435b539461dcc159bd89297443780d635ccc5e3564John Hoford    public final static char FORWARD_AT = 0x100;
445b539461dcc159bd89297443780d635ccc5e3564John Hoford    public final static char BEHIND_AT = 0x200;
455b539461dcc159bd89297443780d635ccc5e3564John Hoford
465b539461dcc159bd89297443780d635ccc5e3564John Hoford    public void clone(ViewMatrix src) {
475b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (src.mLookPoint != null) {
485b539461dcc159bd89297443780d635ccc5e3564John Hoford            System.arraycopy(src.mLookPoint, 0, mLookPoint, 0, mLookPoint.length);
495b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
505b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (src.mEyePoint != null) {
515b539461dcc159bd89297443780d635ccc5e3564John Hoford            System.arraycopy(src.mEyePoint, 0, mEyePoint, 0, mEyePoint.length);
525b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
535b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (src.mUpVector != null) {
545b539461dcc159bd89297443780d635ccc5e3564John Hoford            System.arraycopy(src.mUpVector, 0, mUpVector, 0, mUpVector.length);
555b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
565b539461dcc159bd89297443780d635ccc5e3564John Hoford        mScreenWidth = src.mScreenWidth;
575b539461dcc159bd89297443780d635ccc5e3564John Hoford
585b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (src.mScreenDim != null) {
595b539461dcc159bd89297443780d635ccc5e3564John Hoford            System.arraycopy(src.mScreenDim, 0, mScreenDim, 0, mScreenDim.length);
605b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
615b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (src.mStartV != null) {
625b539461dcc159bd89297443780d635ccc5e3564John Hoford            System.arraycopy(src.mStartV, 0, mStartV, 0, mStartV.length);
635b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
645b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (src.mMoveToV != null) {
655b539461dcc159bd89297443780d635ccc5e3564John Hoford            System.arraycopy(src.mMoveToV, 0, mMoveToV, 0, mMoveToV.length);
665b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
675b539461dcc159bd89297443780d635ccc5e3564John Hoford
685b539461dcc159bd89297443780d635ccc5e3564John Hoford
695b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (src.mStartEyePoint != null) {
705b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (mStartEyePoint == null) {
715b539461dcc159bd89297443780d635ccc5e3564John Hoford                mStartEyePoint = Arrays.copyOf(src.mStartEyePoint,src.mStartEyePoint.length);
725b539461dcc159bd89297443780d635ccc5e3564John Hoford            } else {
735b539461dcc159bd89297443780d635ccc5e3564John Hoford                System.arraycopy(src.mStartEyePoint, 0, mStartEyePoint, 0, mStartEyePoint.length);
745b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
755b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
765b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (src.mStartUpVector != null) {
775b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (mStartUpVector == null) {
785b539461dcc159bd89297443780d635ccc5e3564John Hoford                mStartUpVector = Arrays.copyOf(src.mStartUpVector,src.mStartUpVector.length);
795b539461dcc159bd89297443780d635ccc5e3564John Hoford            } else {
805b539461dcc159bd89297443780d635ccc5e3564John Hoford                System.arraycopy(src.mStartUpVector, 0, mStartUpVector, 0, mStartUpVector.length);
815b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
825b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
835b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (src.mStartMatrix != null) {
845b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (mStartMatrix == null) {
855b539461dcc159bd89297443780d635ccc5e3564John Hoford                mStartMatrix = new Matrix();
865b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
875b539461dcc159bd89297443780d635ccc5e3564John Hoford            mStartMatrix.clone(src.mStartMatrix);
885b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
895b539461dcc159bd89297443780d635ccc5e3564John Hoford        mQ.clone(src.mQ);
905b539461dcc159bd89297443780d635ccc5e3564John Hoford        super.clone(src);
915b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
925b539461dcc159bd89297443780d635ccc5e3564John Hoford
935b539461dcc159bd89297443780d635ccc5e3564John Hoford    private static String toStr(double d) {
945b539461dcc159bd89297443780d635ccc5e3564John Hoford        String s = "         " + df.format(d);
955b539461dcc159bd89297443780d635ccc5e3564John Hoford        return s.substring(s.length() - 9);
965b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
975b539461dcc159bd89297443780d635ccc5e3564John Hoford
985b539461dcc159bd89297443780d635ccc5e3564John Hoford    private static String toStr(double[] d) {
995b539461dcc159bd89297443780d635ccc5e3564John Hoford        String s = "[";
1005b539461dcc159bd89297443780d635ccc5e3564John Hoford        for (int i = 0; i < d.length; i++) {
1015b539461dcc159bd89297443780d635ccc5e3564John Hoford            s += toStr(d[i]);
1025b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
1035b539461dcc159bd89297443780d635ccc5e3564John Hoford
1045b539461dcc159bd89297443780d635ccc5e3564John Hoford        return s + "]";
1055b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1065b539461dcc159bd89297443780d635ccc5e3564John Hoford
1075b539461dcc159bd89297443780d635ccc5e3564John Hoford    private static DecimalFormat df = new DecimalFormat("##0.000");
1085b539461dcc159bd89297443780d635ccc5e3564John Hoford
1095b539461dcc159bd89297443780d635ccc5e3564John Hoford    @Override
1105b539461dcc159bd89297443780d635ccc5e3564John Hoford    public void print() {
1115b539461dcc159bd89297443780d635ccc5e3564John Hoford        Log.v(LOGTAG, "mLookPoint  :" + toStr(mLookPoint));
1125b539461dcc159bd89297443780d635ccc5e3564John Hoford        Log.v(LOGTAG, "mEyePoint   :" + toStr(mEyePoint));
1135b539461dcc159bd89297443780d635ccc5e3564John Hoford        Log.v(LOGTAG, "mUpVector   :" + toStr(mUpVector));
1145b539461dcc159bd89297443780d635ccc5e3564John Hoford        Log.v(LOGTAG, "mScreenWidth: " + toStr(mScreenWidth));
1155b539461dcc159bd89297443780d635ccc5e3564John Hoford        Log.v(LOGTAG, "mScreenDim  :[" + mScreenDim[0] + ", " + mScreenDim[1] + "]");
1165b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1175b539461dcc159bd89297443780d635ccc5e3564John Hoford
1185b539461dcc159bd89297443780d635ccc5e3564John Hoford    public ViewMatrix() {
1195b539461dcc159bd89297443780d635ccc5e3564John Hoford        mLookPoint = new double[3];
1205b539461dcc159bd89297443780d635ccc5e3564John Hoford        mEyePoint = new double[3];
1215b539461dcc159bd89297443780d635ccc5e3564John Hoford        mUpVector = new double[3];
1225b539461dcc159bd89297443780d635ccc5e3564John Hoford        mScreenDim = new int[2];
1235b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1245b539461dcc159bd89297443780d635ccc5e3564John Hoford
1255b539461dcc159bd89297443780d635ccc5e3564John Hoford    public void setScreenDim(int x, int y) {
1265b539461dcc159bd89297443780d635ccc5e3564John Hoford        mScreenDim = new int[]{x, y};
1275b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1285b539461dcc159bd89297443780d635ccc5e3564John Hoford
1295b539461dcc159bd89297443780d635ccc5e3564John Hoford    public double[] getLookPoint() {
1305b539461dcc159bd89297443780d635ccc5e3564John Hoford        return mLookPoint;
1315b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1325b539461dcc159bd89297443780d635ccc5e3564John Hoford
1335b539461dcc159bd89297443780d635ccc5e3564John Hoford    public void setLookPoint(double[] mLookPoint) {
1345b539461dcc159bd89297443780d635ccc5e3564John Hoford        this.mLookPoint = mLookPoint;
1355b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1365b539461dcc159bd89297443780d635ccc5e3564John Hoford
1375b539461dcc159bd89297443780d635ccc5e3564John Hoford    public double[] getEyePoint() {
1385b539461dcc159bd89297443780d635ccc5e3564John Hoford        return mEyePoint;
1395b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1405b539461dcc159bd89297443780d635ccc5e3564John Hoford
1415b539461dcc159bd89297443780d635ccc5e3564John Hoford    public void setEyePoint(double[] mEyePoint) {
1425b539461dcc159bd89297443780d635ccc5e3564John Hoford        this.mEyePoint = mEyePoint;
1435b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1445b539461dcc159bd89297443780d635ccc5e3564John Hoford
1455b539461dcc159bd89297443780d635ccc5e3564John Hoford    public double[] getUpVector() {
1465b539461dcc159bd89297443780d635ccc5e3564John Hoford        return mUpVector;
1475b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1485b539461dcc159bd89297443780d635ccc5e3564John Hoford
1495b539461dcc159bd89297443780d635ccc5e3564John Hoford    public void setUpVector(double[] mUpVector) {
1505b539461dcc159bd89297443780d635ccc5e3564John Hoford        this.mUpVector = mUpVector;
1515b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1525b539461dcc159bd89297443780d635ccc5e3564John Hoford
1535b539461dcc159bd89297443780d635ccc5e3564John Hoford    public double getScreenWidth() {
1545b539461dcc159bd89297443780d635ccc5e3564John Hoford        return mScreenWidth;
1555b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1565b539461dcc159bd89297443780d635ccc5e3564John Hoford
1575b539461dcc159bd89297443780d635ccc5e3564John Hoford    public void setScreenWidth(double screenWidth) {
1585b539461dcc159bd89297443780d635ccc5e3564John Hoford        this.mScreenWidth = screenWidth;
1595b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1605b539461dcc159bd89297443780d635ccc5e3564John Hoford
1615b539461dcc159bd89297443780d635ccc5e3564John Hoford    public void makeUnit() {
1625b539461dcc159bd89297443780d635ccc5e3564John Hoford
1635b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1645b539461dcc159bd89297443780d635ccc5e3564John Hoford
1655b539461dcc159bd89297443780d635ccc5e3564John Hoford    public void calcMatrix() {
1665b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (mScreenDim == null) {
1675b539461dcc159bd89297443780d635ccc5e3564John Hoford            return;
1685b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
1695b539461dcc159bd89297443780d635ccc5e3564John Hoford        double scale = mScreenWidth / mScreenDim[0];
1705b539461dcc159bd89297443780d635ccc5e3564John Hoford        double[] zv = {
1715b539461dcc159bd89297443780d635ccc5e3564John Hoford                mLookPoint[0] - mEyePoint[0],
1725b539461dcc159bd89297443780d635ccc5e3564John Hoford                mLookPoint[1] - mEyePoint[1],
1735b539461dcc159bd89297443780d635ccc5e3564John Hoford                mLookPoint[2] - mEyePoint[2]
1745b539461dcc159bd89297443780d635ccc5e3564John Hoford        };
1755b539461dcc159bd89297443780d635ccc5e3564John Hoford        VectorUtil.normalize(zv);
1765b539461dcc159bd89297443780d635ccc5e3564John Hoford
1775b539461dcc159bd89297443780d635ccc5e3564John Hoford
1785b539461dcc159bd89297443780d635ccc5e3564John Hoford        double[] m = new double[16];
1795b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[2] = zv[0];
1805b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[6] = zv[1];
1815b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[10] = zv[2];
1825b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[14] = 0;
1835b539461dcc159bd89297443780d635ccc5e3564John Hoford
1845b539461dcc159bd89297443780d635ccc5e3564John Hoford        calcRight(zv, mUpVector, zv);
1855b539461dcc159bd89297443780d635ccc5e3564John Hoford        double[] right = zv;
1865b539461dcc159bd89297443780d635ccc5e3564John Hoford
1875b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[0] = right[0] * scale;
1885b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[4] = right[1] * scale;
1895b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[8] = right[2] * scale;
1905b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[12] = 0;
1915b539461dcc159bd89297443780d635ccc5e3564John Hoford
1925b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[1] = -mUpVector[0] * scale;
1935b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[5] = -mUpVector[1] * scale;
1945b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[9] = -mUpVector[2] * scale;
1955b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[13] = 0;
1965b539461dcc159bd89297443780d635ccc5e3564John Hoford        double sw = mScreenDim[0] / 2 - 0.5;
1975b539461dcc159bd89297443780d635ccc5e3564John Hoford        double sh = mScreenDim[1] / 2 - 0.5;
1985b539461dcc159bd89297443780d635ccc5e3564John Hoford        double sz = -0.5;
1995b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[3] = mEyePoint[0] - (m[0] * sw + m[1] * sh + m[2] * sz);
2005b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[7] = mEyePoint[1] - (m[4] * sw + m[5] * sh + m[6] * sz);
2015b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[11] = mEyePoint[2] - (m[8] * sw + m[9] * sh + m[10] * sz);
2025b539461dcc159bd89297443780d635ccc5e3564John Hoford
2035b539461dcc159bd89297443780d635ccc5e3564John Hoford        m[15] = 1;
2045b539461dcc159bd89297443780d635ccc5e3564John Hoford        this.m = m;
2055b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
2065b539461dcc159bd89297443780d635ccc5e3564John Hoford
2075b539461dcc159bd89297443780d635ccc5e3564John Hoford    static void calcRight(double[] a, double[] b, double[] out) {
2085b539461dcc159bd89297443780d635ccc5e3564John Hoford        VectorUtil.cross(a, b, out);
2095b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
2105b539461dcc159bd89297443780d635ccc5e3564John Hoford
2115b539461dcc159bd89297443780d635ccc5e3564John Hoford    public static void main(String[] args) {
2125b539461dcc159bd89297443780d635ccc5e3564John Hoford        double[] up = {0, 0, 1};
2135b539461dcc159bd89297443780d635ccc5e3564John Hoford        double[] look = {0, 0, 0};
2145b539461dcc159bd89297443780d635ccc5e3564John Hoford        double[] eye = {-10, 0, 0};
2155b539461dcc159bd89297443780d635ccc5e3564John Hoford        ViewMatrix v = new ViewMatrix();
2165b539461dcc159bd89297443780d635ccc5e3564John Hoford        v.setEyePoint(eye);
2175b539461dcc159bd89297443780d635ccc5e3564John Hoford        v.setLookPoint(look);
2185b539461dcc159bd89297443780d635ccc5e3564John Hoford        v.setUpVector(up);
2195b539461dcc159bd89297443780d635ccc5e3564John Hoford        v.setScreenWidth(10);
2205b539461dcc159bd89297443780d635ccc5e3564John Hoford        v.setScreenDim(512, 512);
2215b539461dcc159bd89297443780d635ccc5e3564John Hoford        v.calcMatrix();
2225b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
2235b539461dcc159bd89297443780d635ccc5e3564John Hoford
2245b539461dcc159bd89297443780d635ccc5e3564John Hoford    private void calcLook(TriData tri, float[] voxelDim, int w, int h) {
2255b539461dcc159bd89297443780d635ccc5e3564John Hoford        float minx = Float.MAX_VALUE, miny = Float.MAX_VALUE, minz = Float.MAX_VALUE;
2265b539461dcc159bd89297443780d635ccc5e3564John Hoford        float maxx = -Float.MAX_VALUE, maxy = -Float.MAX_VALUE, maxz = -Float.MAX_VALUE;
2275b539461dcc159bd89297443780d635ccc5e3564John Hoford
2285b539461dcc159bd89297443780d635ccc5e3564John Hoford        for (int i = 0; i < tri.mVert.length; i += 3) {
2295b539461dcc159bd89297443780d635ccc5e3564John Hoford            maxx = Math.max(tri.mVert[i], maxx);
2305b539461dcc159bd89297443780d635ccc5e3564John Hoford            minx = Math.min(tri.mVert[i], minx);
2315b539461dcc159bd89297443780d635ccc5e3564John Hoford            maxy = Math.max(tri.mVert[i + 1], maxy);
2325b539461dcc159bd89297443780d635ccc5e3564John Hoford            miny = Math.min(tri.mVert[i + 1], miny);
2335b539461dcc159bd89297443780d635ccc5e3564John Hoford            maxz = Math.max(tri.mVert[i + 2], maxz);
2345b539461dcc159bd89297443780d635ccc5e3564John Hoford            minz = Math.min(tri.mVert[i + 2], minz);
2355b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
2365b539461dcc159bd89297443780d635ccc5e3564John Hoford        mLookPoint = new double[]{voxelDim[0] * (maxx + minx) / 2,
2375b539461dcc159bd89297443780d635ccc5e3564John Hoford                voxelDim[1] * (maxy + miny) / 2,
2385b539461dcc159bd89297443780d635ccc5e3564John Hoford                voxelDim[2] * (maxz + minz) / 2};
2395b539461dcc159bd89297443780d635ccc5e3564John Hoford        mScreenWidth = Math.max(voxelDim[0] * (maxx - minx),
2405b539461dcc159bd89297443780d635ccc5e3564John Hoford                Math.max(voxelDim[1] * (maxy - miny),
2415b539461dcc159bd89297443780d635ccc5e3564John Hoford                        voxelDim[2] * (maxz - minz))) * 2;
2425b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
2435b539461dcc159bd89297443780d635ccc5e3564John Hoford
2445b539461dcc159bd89297443780d635ccc5e3564John Hoford    private void calcLook(TriData triW, int w, int h) {
2455b539461dcc159bd89297443780d635ccc5e3564John Hoford        float minx = Float.MAX_VALUE, miny = Float.MAX_VALUE, minz = Float.MAX_VALUE;
2465b539461dcc159bd89297443780d635ccc5e3564John Hoford        float maxx = -Float.MAX_VALUE, maxy = -Float.MAX_VALUE, maxz = -Float.MAX_VALUE;
2475b539461dcc159bd89297443780d635ccc5e3564John Hoford
2485b539461dcc159bd89297443780d635ccc5e3564John Hoford        for (int i = 0; i < triW.mVert.length; i += 3) {
2495b539461dcc159bd89297443780d635ccc5e3564John Hoford            maxx = Math.max(triW.mVert[i], maxx);
2505b539461dcc159bd89297443780d635ccc5e3564John Hoford            minx = Math.min(triW.mVert[i], minx);
2515b539461dcc159bd89297443780d635ccc5e3564John Hoford            maxy = Math.max(triW.mVert[i + 1], maxy);
2525b539461dcc159bd89297443780d635ccc5e3564John Hoford            miny = Math.min(triW.mVert[i + 1], miny);
2535b539461dcc159bd89297443780d635ccc5e3564John Hoford            maxz = Math.max(triW.mVert[i + 2], maxz);
2545b539461dcc159bd89297443780d635ccc5e3564John Hoford            minz = Math.min(triW.mVert[i + 2], minz);
2555b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
2565b539461dcc159bd89297443780d635ccc5e3564John Hoford        mLookPoint = new double[]{(maxx + minx) / 2, (maxy + miny) / 2, (maxz + minz) / 2};
2575b539461dcc159bd89297443780d635ccc5e3564John Hoford
2585b539461dcc159bd89297443780d635ccc5e3564John Hoford        mScreenWidth = 2 * Math.max((maxx - minx), Math.max((maxy - miny), (maxz - minz)));
2595b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
2605b539461dcc159bd89297443780d635ccc5e3564John Hoford
2615b539461dcc159bd89297443780d635ccc5e3564John Hoford    public void look(char dir, TriData tri, float[] voxelDim, int w, int h) {
2625b539461dcc159bd89297443780d635ccc5e3564John Hoford        calcLook(tri, w, h);
2635b539461dcc159bd89297443780d635ccc5e3564John Hoford        int dx = ((dir >> 4) & 0xF);
2645b539461dcc159bd89297443780d635ccc5e3564John Hoford        int dy = ((dir >> 8) & 0xF);
2655b539461dcc159bd89297443780d635ccc5e3564John Hoford        int dz = ((dir >> 0) & 0xF);
2665b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (dx > 1) {
2675b539461dcc159bd89297443780d635ccc5e3564John Hoford            dx = -1;
2685b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
2695b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (dy > 1) {
2705b539461dcc159bd89297443780d635ccc5e3564John Hoford            dy = -1;
2715b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
2725b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (dz > 1) {
2735b539461dcc159bd89297443780d635ccc5e3564John Hoford            dz = -1;
2745b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
2755b539461dcc159bd89297443780d635ccc5e3564John Hoford        mEyePoint = new double[]{mLookPoint[0] + 2 * mScreenWidth * dx,
2765b539461dcc159bd89297443780d635ccc5e3564John Hoford                mLookPoint[1] + 2 * mScreenWidth * dy,
2775b539461dcc159bd89297443780d635ccc5e3564John Hoford                mLookPoint[2] + 2 * mScreenWidth * dz};
2785b539461dcc159bd89297443780d635ccc5e3564John Hoford        double[] zv = new double[]{-dx, -dy, -dz};
2795b539461dcc159bd89297443780d635ccc5e3564John Hoford        double[] rv = new double[]{(dx == 0) ? 1 : 0, (dx == 0) ? 0 : 1, 0};
2805b539461dcc159bd89297443780d635ccc5e3564John Hoford        double[] up = new double[3];
2815b539461dcc159bd89297443780d635ccc5e3564John Hoford        VectorUtil.norm(zv);
2825b539461dcc159bd89297443780d635ccc5e3564John Hoford        VectorUtil.norm(rv);
2835b539461dcc159bd89297443780d635ccc5e3564John Hoford
2845b539461dcc159bd89297443780d635ccc5e3564John Hoford        VectorUtil.cross(zv, rv, up);
2855b539461dcc159bd89297443780d635ccc5e3564John Hoford        VectorUtil.cross(zv, up, rv);
2865b539461dcc159bd89297443780d635ccc5e3564John Hoford        VectorUtil.cross(zv, rv, up);
2875b539461dcc159bd89297443780d635ccc5e3564John Hoford        mUpVector = up;
2885b539461dcc159bd89297443780d635ccc5e3564John Hoford        mScreenDim = new int[]{w, h};
2895b539461dcc159bd89297443780d635ccc5e3564John Hoford        calcMatrix();
2905b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
2915b539461dcc159bd89297443780d635ccc5e3564John Hoford
2925b539461dcc159bd89297443780d635ccc5e3564John Hoford    public void lookAt(TriData tri, float[] voxelDim, int w, int h) {
2935b539461dcc159bd89297443780d635ccc5e3564John Hoford        calcLook(tri, voxelDim, w, h);
2945b539461dcc159bd89297443780d635ccc5e3564John Hoford
2955b539461dcc159bd89297443780d635ccc5e3564John Hoford        mEyePoint = new double[]{mLookPoint[0] + mScreenWidth,
2965b539461dcc159bd89297443780d635ccc5e3564John Hoford                mLookPoint[1] + mScreenWidth,
2975b539461dcc159bd89297443780d635ccc5e3564John Hoford                mLookPoint[2] + mScreenWidth};
2985b539461dcc159bd89297443780d635ccc5e3564John Hoford        double[] zv = new double[]{-1, -1, -1};
2995b539461dcc159bd89297443780d635ccc5e3564John Hoford        double[] rv = new double[]{1, 1, 0};
3005b539461dcc159bd89297443780d635ccc5e3564John Hoford        double[] up = new double[3];
3015b539461dcc159bd89297443780d635ccc5e3564John Hoford        VectorUtil.norm(zv);
3025b539461dcc159bd89297443780d635ccc5e3564John Hoford        VectorUtil.norm(rv);
3035b539461dcc159bd89297443780d635ccc5e3564John Hoford
3045b539461dcc159bd89297443780d635ccc5e3564John Hoford        VectorUtil.cross(zv, rv, up);
3055b539461dcc159bd89297443780d635ccc5e3564John Hoford        VectorUtil.cross(zv, up, rv);
3065b539461dcc159bd89297443780d635ccc5e3564John Hoford        VectorUtil.cross(zv, rv, up);
3075b539461dcc159bd89297443780d635ccc5e3564John Hoford        mUpVector = up;
3085b539461dcc159bd89297443780d635ccc5e3564John Hoford        mScreenDim = new int[]{w, h};
3095b539461dcc159bd89297443780d635ccc5e3564John Hoford        calcMatrix();
3105b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
3115b539461dcc159bd89297443780d635ccc5e3564John Hoford
3125b539461dcc159bd89297443780d635ccc5e3564John Hoford    public void trackBallUP(float x, float y) {
3135b539461dcc159bd89297443780d635ccc5e3564John Hoford
3145b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
3155b539461dcc159bd89297443780d635ccc5e3564John Hoford
3165b539461dcc159bd89297443780d635ccc5e3564John Hoford    public void trackBallDown(float x, float y) {
3175b539461dcc159bd89297443780d635ccc5e3564John Hoford
3185b539461dcc159bd89297443780d635ccc5e3564John Hoford        ballToVec(x, y, mStartV);
3195b539461dcc159bd89297443780d635ccc5e3564John Hoford        mStartEyePoint = Arrays.copyOf(mEyePoint, m.length);
3205b539461dcc159bd89297443780d635ccc5e3564John Hoford        mStartUpVector = Arrays.copyOf(mUpVector, m.length);
3215b539461dcc159bd89297443780d635ccc5e3564John Hoford        mStartMatrix = new Matrix(this);
3225b539461dcc159bd89297443780d635ccc5e3564John Hoford        mStartMatrix.makeRotation();
3235b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
3245b539461dcc159bd89297443780d635ccc5e3564John Hoford
3255b539461dcc159bd89297443780d635ccc5e3564John Hoford    public void trackBallMove(float x, float y) {
3265b539461dcc159bd89297443780d635ccc5e3564John Hoford        ballToVec(x, y, mMoveToV);
3275b539461dcc159bd89297443780d635ccc5e3564John Hoford
3285b539461dcc159bd89297443780d635ccc5e3564John Hoford        double angle = Quaternion.calcAngle(mStartV, mMoveToV);
3295b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (angle < 0.0001) {
3305b539461dcc159bd89297443780d635ccc5e3564John Hoford            calcMatrix();
3315b539461dcc159bd89297443780d635ccc5e3564John Hoford            return;
3325b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
3335b539461dcc159bd89297443780d635ccc5e3564John Hoford        double[] axis = Quaternion.calcAxis(mStartV, mMoveToV);
3345b539461dcc159bd89297443780d635ccc5e3564John Hoford
3355b539461dcc159bd89297443780d635ccc5e3564John Hoford
3365b539461dcc159bd89297443780d635ccc5e3564John Hoford        axis = mStartMatrix.vecmult(axis);
3375b539461dcc159bd89297443780d635ccc5e3564John Hoford
3385b539461dcc159bd89297443780d635ccc5e3564John Hoford        mQ.set(angle, axis);
3395b539461dcc159bd89297443780d635ccc5e3564John Hoford
3405b539461dcc159bd89297443780d635ccc5e3564John Hoford        VectorUtil.sub(mLookPoint, mStartEyePoint, mEyePoint);
3415b539461dcc159bd89297443780d635ccc5e3564John Hoford
3425b539461dcc159bd89297443780d635ccc5e3564John Hoford        mEyePoint = mQ.rotateVec(mEyePoint);
3435b539461dcc159bd89297443780d635ccc5e3564John Hoford        mUpVector = mQ.rotateVec(mStartUpVector);
3445b539461dcc159bd89297443780d635ccc5e3564John Hoford
3455b539461dcc159bd89297443780d635ccc5e3564John Hoford        VectorUtil.sub(mLookPoint, mEyePoint, mEyePoint);
3465b539461dcc159bd89297443780d635ccc5e3564John Hoford        calcMatrix();
3475b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
3485b539461dcc159bd89297443780d635ccc5e3564John Hoford
3495b539461dcc159bd89297443780d635ccc5e3564John Hoford    void ballToVec(float x, float y, double[] v) {
3505b539461dcc159bd89297443780d635ccc5e3564John Hoford        float ballRadius = Math.min(mScreenDim[0], mScreenDim[1]) * .4f;
3515b539461dcc159bd89297443780d635ccc5e3564John Hoford        double cx = mScreenDim[0] / 2.;
3525b539461dcc159bd89297443780d635ccc5e3564John Hoford        double cy = mScreenDim[1] / 2.;
3535b539461dcc159bd89297443780d635ccc5e3564John Hoford
3545b539461dcc159bd89297443780d635ccc5e3564John Hoford        double dx = (cx - x) / ballRadius;
3555b539461dcc159bd89297443780d635ccc5e3564John Hoford        double dy = (cy - y) / ballRadius;
3565b539461dcc159bd89297443780d635ccc5e3564John Hoford        double scale = dx * dx + dy * dy;
3575b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (scale > 1) {
3585b539461dcc159bd89297443780d635ccc5e3564John Hoford            scale = Math.sqrt(scale);
3595b539461dcc159bd89297443780d635ccc5e3564John Hoford            dx = dx / scale;
3605b539461dcc159bd89297443780d635ccc5e3564John Hoford            dy = dy / scale;
3615b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
3625b539461dcc159bd89297443780d635ccc5e3564John Hoford
3635b539461dcc159bd89297443780d635ccc5e3564John Hoford        double dz = Math.sqrt(Math.abs(1 - (dx * dx + dy * dy)));
3645b539461dcc159bd89297443780d635ccc5e3564John Hoford        v[0] = dx;
3655b539461dcc159bd89297443780d635ccc5e3564John Hoford        v[1] = dy;
3665b539461dcc159bd89297443780d635ccc5e3564John Hoford        v[2] = dz;
3675b539461dcc159bd89297443780d635ccc5e3564John Hoford        VectorUtil.normalize(v);
3685b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
3695b539461dcc159bd89297443780d635ccc5e3564John Hoford}
370