Back to project page geoar-app.
The source code is released under:
Apache License
If you think the Android project geoar-app listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/** * Copyright 2012 52North Initiative for Geospatial Open Source Software GmbH */* w w w .j a v a2s. com*/ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.n52.geoar.ar.view.gl; import java.util.Arrays; import org.n52.geoar.tracking.camera.RealityCamera; import org.n52.geoar.view.geoar.Settings; import android.opengl.Matrix; /** * * @author Arne de Wall * */ public class GLESCamera { private static class GeometryPlane { private static float[] mTmp1; private static float[] mTmp2; final float[] normal = new float[3]; float dot = 0; boolean isOutside(float[] p) { float dist = p[0] * normal[0] + p[1] * normal[1] + p[2] * normal[2] + dot; return dist < 0; } void set(float[] p1, float[] p2, float[] p3) { mTmp1 = Arrays.copyOf(p1, 3); mTmp2 = Arrays.copyOf(p2, 3); mTmp1[0] -= mTmp2[0]; mTmp1[1] -= mTmp2[1]; mTmp1[2] -= mTmp2[2]; mTmp2[0] -= p3[0]; mTmp2[1] -= p3[1]; mTmp2[2] -= p3[2]; // cross product in order to calculate the normal normal[0] = mTmp1[1] * mTmp2[2] - mTmp1[2] * mTmp2[1]; normal[1] = mTmp1[2] * mTmp2[0] - mTmp1[0] * mTmp2[2]; normal[2] = mTmp1[0] * mTmp2[1] - mTmp1[1] * mTmp2[0]; // normalizing the result // According to Lint faster than FloatMath float a = (float) Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2]); if (a != 0 && a != 1) { a = 1 / a; normal[0] *= a; normal[1] *= a; normal[2] *= a; } dot = -(p1[0] * normal[0] + p1[1] * normal[1] + p1[2] * normal[2]); } } public static float zNear = 1.f; public static float zFar = 2000.f; // Settings.SIZE_AR_INTERPOLATION // + Settings.RELOAD_DIST_AR; // // Viewport of OpenGL Viewport // public static int glViewportWidth; // public static int glViewportHeight; public static float[] projectionMatrix = new float[16]; // Store the view matrix. This matrix transforms world space to eye space; // it positions things relative to our eye. public static float[] viewMatrix = new float[16]; // public static float[] cameraPosition = new float[] { 0.f, 0f, 0.f }; public static int[] viewportMatrix = new int[4]; public static float[] cameraPosition = new float[]{0.0f, 1.6f, 0.0f}; // TODO XXX 1.6 is no constant! // public static int[] viewPortMatrix; private final static float[][] planePoints = new float[8][3]; // TODO FIXME XXX clipSpace needs to be setted with real frustum coordinates private final static float[][] clipSpace = new float[][] { new float[] { 0, 0, 0 }, new float[] { 1, 0, 0 }, new float[] { 1, 1, 0 }, new float[] { 0, 1, 0 }, new float[] { 0, 0, 1 }, new float[] { 1, 0, 1 }, new float[] { 1, 1, 1 }, new float[] { 0, 1, 1 }, }; private final static GeometryPlane[] frustumPlanes = new GeometryPlane[6]; static { for (int i = 0; i < 8; i++) { planePoints[i] = new float[3]; } for (int i = 0; i < 6; i++) { frustumPlanes[i] = new GeometryPlane(); } } public static boolean frustumCulling(float[] positionVec) { float z = -positionVec[2]; if (z > zFar || z < zNear) return false; return true; // float h = z * 2 * Math.tan(RealityCamera.) } // public static void gluLookAt(float[] m, float eyeX, float eyeY, float // eyeZ, // float centerX, float centerY, float centerZ, float upX, float upY, // float upZ) { // // // See the OpenGL GLUT documentation for gluLookAt for a description // // of the algorithm. We implement it in a straightforward way: // // float fx = centerX - eyeX; // float fy = centerY - eyeY; // float fz = centerZ - eyeZ; // // // Normalize f // float rlf = 1.0f / Matrix.length(fx, fy, fz); // fx *= rlf; // fy *= rlf; // fz *= rlf; // // // compute s = f x up (x means "cross product") // float sx = fy * upZ - fz * upY; // float sy = fz * upX - fx * upZ; // float sz = fx * upY - fy * upX; // // // and normalize s // float rls = 1.0f / Matrix.length(sx, sy, sz); // sx *= rls; // sy *= rls; // sz *= rls; // // // compute u = s x f // float ux = sy * fz - sz * fy; // float uy = sz * fx - sx * fz; // float uz = sx * fy - sy * fx; // // m[0] = sx; // m[1] = ux; // m[2] = -fx; // m[3] = 0.0f; // // m[4] = sy; // m[5] = uy; // m[6] = -fy; // m[7] = 0.0f; // // m[8] = sz; // m[9] = uz; // m[10] = -fz; // m[11] = 0.0f; // // m[12] = 0.0f; // m[13] = 0.0f; // m[14] = 0.0f; // m[15] = 1.0f; // // // Matrix.m // // gl.glMultMatrixf(m, 0); // // gl.glTranslatef(-eyeX, -eyeY, -eyeZ); // } public static boolean pointInFrustum(float[] p) { for (int i = 0; i < frustumPlanes.length; i++) { if (!frustumPlanes[i].isOutside(p)) return false; } return true; } public static void resetProjectionMatrix() { Matrix.setIdentityM(projectionMatrix, 0); perspectiveMatrix(projectionMatrix, 0, RealityCamera.fovY, RealityCamera.aspect, zNear, zFar); } public static void resetViewMatrix() { // calculate the viewMatrix for OpenGL rendering Matrix.setIdentityM(viewMatrix, 0); } public static void resetViewportMatrix(int width, int height) { viewportMatrix = new int[] { 0, 0, width, height }; } public static void updateFrustum(float[] projectionMatrix, float[] viewMatrix) { float[] projectionViewMatrix = new float[16]; float[] invertPVMatrix = new float[16]; Matrix.multiplyMM(projectionViewMatrix, 0, projectionMatrix, 0, viewMatrix, 0); Matrix.invertM(invertPVMatrix, 0, projectionViewMatrix, 0); for (int i = 0; i < 8; i++) { float[] point = Arrays.copyOf(clipSpace[i], 3); float rw = point[0] * invertPVMatrix[3] + point[1] * invertPVMatrix[7] + point[2] * invertPVMatrix[11] + invertPVMatrix[15]; planePoints[i] = clipSpace[i]; float[] newPlanePoints = new float[3]; newPlanePoints[0] = (point[0] * invertPVMatrix[0] + point[1] * invertPVMatrix[4] + point[2] * invertPVMatrix[8] + invertPVMatrix[12]) / rw; newPlanePoints[1] = (point[0] * invertPVMatrix[1] + point[1] * invertPVMatrix[5] + point[2] * invertPVMatrix[9] + invertPVMatrix[13]) / rw; newPlanePoints[2] = (point[0] * invertPVMatrix[2] + point[1] * invertPVMatrix[6] + point[2] * invertPVMatrix[10] + invertPVMatrix[14]) / rw; planePoints[i] = newPlanePoints; } frustumPlanes[0].set(planePoints[1], planePoints[0], planePoints[2]); frustumPlanes[1].set(planePoints[4], planePoints[5], planePoints[7]); frustumPlanes[2].set(planePoints[0], planePoints[4], planePoints[3]); frustumPlanes[3].set(planePoints[5], planePoints[1], planePoints[6]); frustumPlanes[4].set(planePoints[2], planePoints[3], planePoints[6]); frustumPlanes[5].set(planePoints[4], planePoints[0], planePoints[1]); } /** * Define a projection matrix in terms of a field of view angle, an aspect * ratio, and z clip planes SOURCE: Android 4.0.3 API-LEVEL 15 * * @param m * the float array that holds the perspective matrix * @param offset * the offset into float array m where the perspective matrix * data is written * @param fovy * field of view in y direction, in degrees * @param aspect * width to height aspect ratio of the viewport * @param zNear * @param zFar */ private static void perspectiveMatrix(float[] m, int offset, float fovy, float aspect, float zNear, float zFar) { float f = 1.0f / (float) Math.tan(fovy * (Math.PI / 360.0)); float rangeReciprocal = 1.0f / (zNear - zFar); m[offset + 0] = f / aspect; m[offset + 1] = 0.0f; m[offset + 2] = 0.0f; m[offset + 3] = 0.0f; m[offset + 4] = 0.0f; m[offset + 5] = f; m[offset + 6] = 0.0f; m[offset + 7] = 0.0f; m[offset + 8] = 0.0f; m[offset + 9] = 0.0f; m[offset + 10] = (zFar + zNear) * rangeReciprocal; m[offset + 11] = -1.0f; m[offset + 12] = 0.0f; m[offset + 13] = 0.0f; m[offset + 14] = 2.0f * zFar * zNear * rangeReciprocal; m[offset + 15] = 0.0f; } /** private constructor -> just a static class */ private GLESCamera() { } }