// Copyright 2009 Google Inc.
//
// 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 com.google.android.stardroid.renderer;
import android.content.res.Resources;
import android.opengl.GLU;
import android.util.Log;
import com.google.android.stardroid.R;
import com.google.android.stardroid.renderer.LabelOverlayManager.Label;
import com.google.android.stardroid.renderer.util.ColoredQuad;
import com.google.android.stardroid.renderer.util.SearchHelper;
import com.google.android.stardroid.renderer.util.TextureManager;
import com.google.android.stardroid.units.GeocentricCoordinates;
import com.google.android.stardroid.units.Vector3;
import com.google.android.stardroid.util.MathUtil;
import com.google.android.stardroid.util.Matrix4x4;
import com.google.android.stardroid.util.VectorUtil;
import javax.microedition.khronos.opengles.GL10;
public class OverlayManager extends RendererObjectManager {
private int mWidth = 2;
private int mHeight = 2;
private Matrix4x4 mGeoToViewerTransform = Matrix4x4.createIdentity();
private Vector3 mLookDir = new Vector3(0, 0, 0);
private Vector3 mUpDir = new Vector3(0, 1, 0);
private Vector3 mTransformedLookDir = new Vector3(0, 0, 0);
private Vector3 mTransformedUpDir = new Vector3(0, 1, 0);
private boolean mMustUpdateTransformedOrientation = true;
private boolean mSearching = false;
private SearchHelper mSearchHelper = new SearchHelper();
private ColoredQuad mDarkQuad = null;
private SearchArrow mSearchArrow = new SearchArrow();
private CrosshairOverlay mCrosshair = new CrosshairOverlay();
private TextureManager mTextureManager;
public OverlayManager(int layer, TextureManager manager) {
super(layer, manager);
}
@Override
public void reload(GL10 gl, boolean fullReload) {
Resources res = getRenderState().getResources();
mSearchArrow.reloadTextures(gl, res, textureManager());
mCrosshair.reloadTextures(gl, res, textureManager());
}
public void resize(GL10 gl, int screenWidth, int screenHeight) {
mWidth = screenWidth;
mHeight = screenHeight;
// If the search target is within this radius of the center of the screen, the user is
// considered to have "found" it.
float searchTargetRadius = Math.min(screenWidth, screenHeight) - 20;
mSearchHelper.setTargetFocusRadius(searchTargetRadius);
mSearchHelper.resize(screenWidth, screenHeight);
mSearchArrow.resize(gl, screenWidth, screenHeight, searchTargetRadius);
mCrosshair.resize(gl, screenWidth, screenHeight);
mDarkQuad = new ColoredQuad(0, 0, 0, 0.6f,
0, 0, 0,
screenWidth, 0, 0,
0, screenHeight, 0);
}
public void setViewOrientation(GeocentricCoordinates lookDir, GeocentricCoordinates upDir) {
mLookDir = lookDir;
mUpDir = upDir;
mMustUpdateTransformedOrientation = true;
}
@Override
public void drawInternal(GL10 gl) {
updateTransformedOrientationIfNecessary();
setupMatrices(gl);
if (mSearching) {
mSearchHelper.setTransform(getRenderState().getTransformToDeviceMatrix());
mSearchHelper.checkState();
float transitionFactor = mSearchHelper.getTransitionFactor();
// Darken the background.
mDarkQuad.draw(gl);
// Draw the crosshair.
mCrosshair.draw(gl, mSearchHelper, getRenderState().getNightVisionMode());
// Draw the search arrow.
mSearchArrow.draw(gl, mTransformedLookDir, mTransformedUpDir, mSearchHelper,
getRenderState().getNightVisionMode());
}
restoreMatrices(gl);
}
// viewerUp MUST be normalized.
public void setViewerUpDirection(GeocentricCoordinates viewerUp) {
// Log.d("OverlayManager", "Setting viewer up " + viewerUp);
if (MathUtil.abs(viewerUp.y) < 0.999f) {
Vector3 cp = VectorUtil.crossProduct(viewerUp, new Vector3(0, 1, 0));
cp = VectorUtil.normalized(cp);
mGeoToViewerTransform = Matrix4x4.createRotation(MathUtil.acos(viewerUp.y), cp);
} else {
mGeoToViewerTransform = Matrix4x4.createIdentity();
}
mMustUpdateTransformedOrientation = true;
}
public void enableSearchOverlay(GeocentricCoordinates target, String targetName) {
Log.d("OverlayManager", "Searching for " + target);
mSearching = true;
mSearchHelper.setTransform(getRenderState().getTransformToDeviceMatrix());
mSearchHelper.setTarget(target, targetName);
Vector3 transformedPosition = Matrix4x4.multiplyMV(mGeoToViewerTransform, target);
mSearchArrow.setTarget(transformedPosition);
queueForReload(false);
}
public void disableSearchOverlay() {
mSearching = false;
}
private void setupMatrices(GL10 gl) {
// Save the matrix values.
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glPushMatrix();
float left = mWidth / 2;
float bottom = mHeight / 2;
gl.glLoadIdentity();
GLU.gluOrtho2D(gl, left, -left, bottom, -bottom);
}
private void restoreMatrices(GL10 gl) {
// Restore the matrices.
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glPopMatrix();
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glPopMatrix();
}
private void updateTransformedOrientationIfNecessary() {
if (mMustUpdateTransformedOrientation && mSearching) {
mTransformedLookDir = Matrix4x4.multiplyMV(mGeoToViewerTransform, mLookDir);
mTransformedUpDir = Matrix4x4.multiplyMV(mGeoToViewerTransform, mUpDir);
mMustUpdateTransformedOrientation = false;
}
}
}