package com.example.atest22;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import com.google.vrtoolkit.cardboard.*;
import android.opengl.GLES20;
import android.opengl.Matrix;
import android.os.Bundle;
import android.os.Vibrator;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
public class MainActivity extends CardboardActivity implements CardboardView.StereoRenderer {
private static final String TAG = "MainActivity";
private static final float CAMERA_Z = 0.01f;
private static final float TIME_DELTA = 0.3f;
private static final float YAW_LIMIT = 0.12f;
private static final float PITCH_LIMIT = 0.12f;
//---------------------------------------------------
private int intCurrentI = -1;
private int intCurrentI1 = -1;
//---------------------------------------------------
// We keep the light always position just above the user.
private final float[] mLightPosInWorldSpace = new float[] {0.0f, 2.0f, 0.0f, 1.0f};
private final float[] mLightPosInEyeSpace = new float[4];
private static final int COORDS_PER_VERTEX = 3;
private final WorldLayoutData DATA = new WorldLayoutData();
private FloatBuffer mFloorVertices;
private FloatBuffer mFloorColors;
private FloatBuffer mFloorNormals;
private FloatBuffer mCubeVertices;
private FloatBuffer mCubeColors;
private FloatBuffer mCubeFoundColors;
private FloatBuffer mCubeNormals;
private int mGlProgram;
private int mPositionParam;
private int mNormalParam;
private int mColorParam;
private int mModelViewProjectionParam;
private int mLightPosParam;
private int mModelViewParam;
private int mModelParam;
private int mIsFloorParam;
private float[] mModelCube;
private float[] mCamera;
private float[] mView;
private float[] mHeadView;
private float[] mModelViewProjection;
private float[] mModelView;
/**
* 2014-10-16
* 自行添加,用于测试,是否可以显示两个物体,在空间中。
* *************************/
private float[] mModelCube2;
/***************************/
private float[] mModelFloor;
private int mScore = 0;
private float mObjectDistance = 12f;
private float mFloorDepth = 20f;
private Vibrator mVibrator;
private CardboardOverlayView mOverlayView;
/**
* Converts a raw text file, saved as a resource, into an OpenGL ES shader
* @param type The type of shader we will be creating.
* @param resId The resource ID of the raw text file about to be turned into a shader.
* @return
*/
private int loadGLShader(int type, int resId) {
String code = readRawTextFile(resId);
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, code);
GLES20.glCompileShader(shader);
// Get the compilation status.
final int[] compileStatus = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
// If the compilation failed, delete the shader.
if (compileStatus[0] == 0) {
// Log.e(TAG, "Error compiling shader: " + GLES20.glGetShaderInfoLog(shader));
GLES20.glDeleteShader(shader);
shader = 0;
}
if (shader == 0) {
throw new RuntimeException("Error creating shader.");
}
return shader;
}
/**
* Checks if we've had an error inside of OpenGL ES, and if so what that error is.
* @param func
*/
private static void checkGLError(String func) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
// Log.e(TAG, func + ": glError " + error);
throw new RuntimeException(func + ": glError " + error);
}
}
/**
* Sets the view to our CardboardView and initializes the transformation matrices we will use
* to render our scene.
* @param savedInstanceState
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.common_ui);
CardboardView cardboardView = (CardboardView) findViewById(R.id.cardboard_view);
/*********************/
cardboardView.setEGLConfigChooser(8 , 8, 8, 8, 16, 0);
/*********************/
cardboardView.setRenderer(this);
setCardboardView(cardboardView);
/* 2014-10-16 */
mModelCube2 = new float[16];
/* 2014-10-16 */
mModelCube = new float[16];
mCamera = new float[16];
mView = new float[16];
mModelViewProjection = new float[16];
mModelView = new float[16];
mModelFloor = new float[16];
mHeadView = new float[16];
mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mOverlayView = (CardboardOverlayView) findViewById(R.id.overlay);
// mOverlayView.show3DToast("2Pull the magnet when you find an object2.");
mOverlayView.show3DToast("当你找到方块时,请拉动磁铁!");
}
@Override
public void onRendererShutdown() {
// Log.i(TAG, "onRendererShutdown");
}
@Override
public void onSurfaceChanged(int width, int height) {
// Log.i(TAG, "onSurfaceChanged");
}
/**
* Creates the buffers we use to store information about the 3D world. OpenGL doesn't use Java
* arrays, but rather needs data in a format it can understand. Hence we use ByteBuffers.
* @param config The EGL configuration used when creating the surface.
*/
@Override
public void onSurfaceCreated(EGLConfig config) {
// Log.i(TAG, "onSurfaceCreated");
GLES20.glClearColor(0.1f, 0.1f, 0.1f, 0.5f); // Dark background so text shows up well
ByteBuffer bbVertices = ByteBuffer.allocateDirect(DATA.CUBE_COORDS.length * 4);
bbVertices.order(ByteOrder.nativeOrder());
mCubeVertices = bbVertices.asFloatBuffer();
mCubeVertices.put(DATA.CUBE_COORDS);
mCubeVertices.position(0);
ByteBuffer bbColors = ByteBuffer.allocateDirect(DATA.CUBE_COLORS.length * 4);
bbColors.order(ByteOrder.nativeOrder());
mCubeColors = bbColors.asFloatBuffer();
mCubeColors.put(DATA.CUBE_COLORS);
mCubeColors.position(0);
ByteBuffer bbFoundColors = ByteBuffer.allocateDirect(DATA.CUBE_FOUND_COLORS.length * 4);
bbFoundColors.order(ByteOrder.nativeOrder());
mCubeFoundColors = bbFoundColors.asFloatBuffer();
mCubeFoundColors.put(DATA.CUBE_FOUND_COLORS);
mCubeFoundColors.position(0);
ByteBuffer bbNormals = ByteBuffer.allocateDirect(DATA.CUBE_NORMALS.length * 4);
bbNormals.order(ByteOrder.nativeOrder());
mCubeNormals = bbNormals.asFloatBuffer();
mCubeNormals.put(DATA.CUBE_NORMALS);
mCubeNormals.position(0);
// make a floor
ByteBuffer bbFloorVertices = ByteBuffer.allocateDirect(DATA.FLOOR_COORDS.length * 4);
bbFloorVertices.order(ByteOrder.nativeOrder());
mFloorVertices = bbFloorVertices.asFloatBuffer();
mFloorVertices.put(DATA.FLOOR_COORDS);
mFloorVertices.position(0);
ByteBuffer bbFloorNormals = ByteBuffer.allocateDirect(DATA.FLOOR_NORMALS.length * 4);
bbFloorNormals.order(ByteOrder.nativeOrder());
mFloorNormals = bbFloorNormals.asFloatBuffer();
mFloorNormals.put(DATA.FLOOR_NORMALS);
mFloorNormals.position(0);
ByteBuffer bbFloorColors = ByteBuffer.allocateDirect(DATA.FLOOR_COLORS.length * 4);
bbFloorColors.order(ByteOrder.nativeOrder());
mFloorColors = bbFloorColors.asFloatBuffer();
mFloorColors.put(DATA.FLOOR_COLORS);
mFloorColors.position(0);
int vertexShader = loadGLShader(GLES20.GL_VERTEX_SHADER, R.raw.light_vertex);
int gridShader = loadGLShader(GLES20.GL_FRAGMENT_SHADER, R.raw.grid_fragment);
mGlProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(mGlProgram, vertexShader);
GLES20.glAttachShader(mGlProgram, gridShader);
GLES20.glLinkProgram(mGlProgram);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
// Object first appears directly in front of user
Matrix.setIdentityM(mModelCube, 0);
Matrix.translateM(mModelCube, 0, 0, 0, -mObjectDistance);
/*204-10-16
* 绘制第二个方块。
* */
Matrix.setIdentityM(mModelCube2, 0);
Matrix.translateM(mModelCube2, 0, -10.0f, -10.0f, -mObjectDistance - 12.0f );
/*204-10-16*/
Matrix.setIdentityM(mModelFloor, 0);
Matrix.translateM(mModelFloor, 0, 0, -mFloorDepth, 0); // Floor appears below user
checkGLError("onSurfaceCreated");
}
/**
* Converts a raw text file into a string.
* @param resId The resource ID of the raw text file about to be turned into a shader.
* @return
*/
private String readRawTextFile(int resId) {
InputStream inputStream = getResources().openRawResource(resId);
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
reader.close();
return sb.toString();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
/**
* Prepares OpenGL ES before we draw a frame.
* @param headTransform The head transformation in the new frame.
*/
@Override
public void onNewFrame(HeadTransform headTransform) {
GLES20.glUseProgram(mGlProgram);
mModelViewProjectionParam = GLES20.glGetUniformLocation(mGlProgram, "u_MVP");
mLightPosParam = GLES20.glGetUniformLocation(mGlProgram, "u_LightPos");
mModelViewParam = GLES20.glGetUniformLocation(mGlProgram, "u_MVMatrix");
mModelParam = GLES20.glGetUniformLocation(mGlProgram, "u_Model");
mIsFloorParam = GLES20.glGetUniformLocation(mGlProgram, "u_IsFloor");
// Build the Model part of the ModelView matrix.
Matrix.rotateM(mModelCube, 0, TIME_DELTA, 0.5f, 0.5f, 1.0f);
//--2014-10-16 添加---------------------
// Matrix.rotateM(mModelCube2, 0, TIME_DELTA, 1.5f, 1.5f, 1.0f);
Matrix.rotateM(mModelCube2, 0, TIME_DELTA, 0.5f, 0.5f, 1.0f);
//--------------------------------------
// Build the camera matrix and apply it to the ModelView.
Matrix.setLookAtM(mCamera, 0, 0.0f, 0.0f, CAMERA_Z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
headTransform.getHeadView(mHeadView, 0);
checkGLError("onReadyToDraw");
}
/**
* Draws a frame for an eye. The transformation for that eye (from the camera) is passed in as
* a parameter.
* @param transform The transformations to apply to render this eye.
*/
@Override
public void onDrawEye(EyeTransform transform) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
mPositionParam = GLES20.glGetAttribLocation(mGlProgram, "a_Position");
mNormalParam = GLES20.glGetAttribLocation(mGlProgram, "a_Normal");
mColorParam = GLES20.glGetAttribLocation(mGlProgram, "a_Color");
GLES20.glEnableVertexAttribArray(mPositionParam);
GLES20.glEnableVertexAttribArray(mNormalParam);
GLES20.glEnableVertexAttribArray(mColorParam);
checkGLError("mColorParam");
// Apply the eye transformation to the camera.
Matrix.multiplyMM(mView, 0, transform.getEyeView(), 0, mCamera, 0);
// Set the position of the light
Matrix.multiplyMV(mLightPosInEyeSpace, 0, mView, 0, mLightPosInWorldSpace, 0);
GLES20.glUniform3f(mLightPosParam, mLightPosInEyeSpace[0], mLightPosInEyeSpace[1],
mLightPosInEyeSpace[2]);
// Build the ModelView and ModelViewProjection matrices
// for calculating cube position and light.
Matrix.multiplyMM(mModelView, 0, mView, 0, mModelCube, 0);
Matrix.multiplyMM(mModelViewProjection, 0, transform.getPerspective(), 0,
mModelView, 0);
drawCube(1);
//--------------------------------------
Matrix.multiplyMM(mModelView, 0, mView, 0, mModelCube2, 0);
Matrix.multiplyMM(mModelViewProjection, 0, transform.getPerspective(), 0,
mModelView, 0);
drawCube(0);
//--------------------------------------
// Set mModelView for the floor, so we draw floor in the correct location
Matrix.multiplyMM(mModelView, 0, mView, 0, mModelFloor, 0);
Matrix.multiplyMM(mModelViewProjection, 0, transform.getPerspective(), 0,
mModelView, 0);
drawFloor(transform.getPerspective());
}
@Override
public void onFinishFrame(Viewport viewport) {
}
/**
* Draw the cube. We've set all of our transformation matrices. Now we simply pass them into
* the shader.
*/
// public void drawCube() {
// // This is not the floor!
// GLES20.glUniform1f(mIsFloorParam, 0f);
//
// // Set the Model in the shader, used to calculate lighting
// GLES20.glUniformMatrix4fv(mModelParam, 1, false, mModelCube, 0);
//
// //--2014-10-16 添加--------------------------------
// GLES20.glUniformMatrix4fv(mModelParam, 1, false, mModelCube2, 0);
// //-------------------------------------------------
//
// // Set the ModelView in the shader, used to calculate lighting
// GLES20.glUniformMatrix4fv(mModelViewParam, 1, false, mModelView, 0);
//
// // Set the position of the cube
// GLES20.glVertexAttribPointer(mPositionParam, COORDS_PER_VERTEX, GLES20.GL_FLOAT,
// false, 0, mCubeVertices);
//
// // Set the ModelViewProjection matrix in the shader.
// GLES20.glUniformMatrix4fv(mModelViewProjectionParam, 1, false, mModelViewProjection, 0);
//
// // Set the normal positions of the cube, again for shading
// GLES20.glVertexAttribPointer(mNormalParam, 3, GLES20.GL_FLOAT,
// false, 0, mCubeNormals);
//
//
//
// if (isLookingAtObject()) {
// GLES20.glVertexAttribPointer(mColorParam, 4, GLES20.GL_FLOAT, false,
// 0, mCubeFoundColors);
// } else {
// GLES20.glVertexAttribPointer(mColorParam, 4, GLES20.GL_FLOAT, false,
// 0, mCubeColors);
// }
// GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 36);
// checkGLError("Drawing cube");
// }
public void drawCube(int i1) {
// This is not the floor!
GLES20.glUniform1f(mIsFloorParam, 0f);
// Set the Model in the shader, used to calculate lighting
if(i1 == 1){
GLES20.glUniformMatrix4fv(mModelParam, 1, false, mModelCube, 0);
// intCurrentI1 = 1;
}else if(i1 == 0){
//--2014-10-16 添加--------------------------------
GLES20.glUniformMatrix4fv(mModelParam, 1, false, mModelCube2, 0);
//-------------------------------------------------
}
// Set the ModelView in the shader, used to calculate lighting
GLES20.glUniformMatrix4fv(mModelViewParam, 1, false, mModelView, 0);
// Set the position of the cube
GLES20.glVertexAttribPointer(mPositionParam, COORDS_PER_VERTEX, GLES20.GL_FLOAT,
false, 0, mCubeVertices);
// Set the ModelViewProjection matrix in the shader.
GLES20.glUniformMatrix4fv(mModelViewProjectionParam, 1, false, mModelViewProjection, 0);
// Set the normal positions of the cube, again for shading
GLES20.glVertexAttribPointer(mNormalParam, 3, GLES20.GL_FLOAT,
false, 0, mCubeNormals);
if (isLookingAtObject(i1)) {
// if (isLookingAtObject()) {
GLES20.glVertexAttribPointer(mColorParam, 4, GLES20.GL_FLOAT, false,
0, mCubeFoundColors);
if(i1 == 1)
intCurrentI1 = i1;
else
intCurrentI1 = -1;
intCurrentI = i1;
System.out.println("drawCube->intCurrentI2:"+intCurrentI);
} else {
GLES20.glVertexAttribPointer(mColorParam, 4, GLES20.GL_FLOAT, false,
0, mCubeColors);
intCurrentI = -1;
}
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 36);
checkGLError("Drawing cube");
if(intCurrentI1 != -1)
intCurrentI = intCurrentI1;
System.out.println("drawCube_out_if->intCurrentI4:"+intCurrentI);
// intCurrentI = -1;
}
/**
* Draw the floor. This feeds in data for the floor into the shader. Note that this doesn't
* feed in data about position of the light, so if we rewrite our code to draw the floor first,
* the lighting might look strange.
*/
public void drawFloor(float[] perspective) {
// This is the floor!
GLES20.glUniform1f(mIsFloorParam, 1f);
// Set ModelView, MVP, position, normals, and color
GLES20.glUniformMatrix4fv(mModelParam, 1, false, mModelFloor, 0);
GLES20.glUniformMatrix4fv(mModelViewParam, 1, false, mModelView, 0);
GLES20.glUniformMatrix4fv(mModelViewProjectionParam, 1, false, mModelViewProjection, 0);
GLES20.glVertexAttribPointer(mPositionParam, COORDS_PER_VERTEX, GLES20.GL_FLOAT,
false, 0, mFloorVertices);
GLES20.glVertexAttribPointer(mNormalParam, 3, GLES20.GL_FLOAT, false, 0, mFloorNormals);
GLES20.glVertexAttribPointer(mColorParam, 4, GLES20.GL_FLOAT, false, 0, mFloorColors);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);
checkGLError("drawing floor");
}
/**
* Increment the score, hide the object, and give feedback if the user pulls the magnet while
* looking at the object. Otherwise, remind the user what to do.
*/
@Override
public void onCardboardTrigger() {
// Log.i(TAG, "onCardboardTrigger");
// if (isLookingAtObject()) {
if(isLookingAtObject(intCurrentI)){
mScore++;
mOverlayView.show3DToast("Found it! Look around for another one.\nScore = " + mScore);
hideObject(intCurrentI);
} else {
mOverlayView.show3DToast("Look around to find the object!");
}
// Always give user feedback
mVibrator.vibrate(50);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Log.i(TAG, "onKeyDown");
mVibrator.vibrate(60);
if(keyCode == KeyEvent.KEYCODE_BACK){
// mOverlayView.show3DToast("你按下了退回键!");
if(isLookingAtObject(intCurrentI)){
// if (isLookingAtObject()) {
mScore++;
mOverlayView.show3DToast(""+intCurrentI+"找到了,再找下一个吧.\n 得分: = " + mScore);
hideObject(intCurrentI);
}else{
mOverlayView.show3DToast(""+intCurrentI+"看看周围有没有方块!!");
}
return true;
}
return super.onKeyDown(keyCode, event);
}
/**
* Find a new random position for the object.
* We'll rotate it around the Y-axis so it's out of sight, and then up or down by a little bit.
*/
// private void hideObject() {
// float[] rotationMatrix = new float[16];
// float[] posVec = new float[4];
//
// // First rotate in XZ plane, between 90 and 270 deg away, and scale so that we vary
// // the object's distance from the user.
// float angleXZ = (float) Math.random() * 180 + 90;
// Matrix.setRotateM(rotationMatrix, 0, angleXZ, 0f, 1f, 0f);
// float oldObjectDistance = mObjectDistance;
// mObjectDistance = (float) Math.random() * 15 + 5;
// float objectScalingFactor = mObjectDistance / oldObjectDistance;
// Matrix.scaleM(rotationMatrix, 0, objectScalingFactor, objectScalingFactor, objectScalingFactor);
// if(intCurrentI==1){
// Matrix.multiplyMV(posVec, 0, rotationMatrix, 0, mModelCube, 12);
// }else if(intCurrentI==0){
// Matrix.multiplyMV(posVec, 0, rotationMatrix, 0, mModelCube2, 12);
// }
// // Now get the up or down angle, between -20 and 20 degrees
// float angleY = (float) Math.random() * 80 - 40; // angle in Y plane, between -40 and 40
// angleY = (float) Math.toRadians(angleY);
// float newY = (float)Math.tan(angleY) * mObjectDistance;
//
// if(intCurrentI==1){
// Matrix.setIdentityM(mModelCube, 0);
// Matrix.translateM(mModelCube, 0, posVec[0], newY, posVec[2]);
// }else if(intCurrentI==0){
// Matrix.setIdentityM(mModelCube2, 0);
// Matrix.translateM(mModelCube2, 0, posVec[0], newY, posVec[2]);
// }
//
// System.out.println("intCurrentI3:"+intCurrentI);
// }
private void hideObject(int i1) {
float[] rotationMatrix = new float[16];
float[] posVec = new float[4];
// First rotate in XZ plane, between 90 and 270 deg away, and scale so that we vary
// the object's distance from the user.
float angleXZ = (float) Math.random() * 180 + 90;
Matrix.setRotateM(rotationMatrix, 0, angleXZ, 0f, 1f, 0f);
float oldObjectDistance = mObjectDistance;
mObjectDistance = (float) Math.random() * 15 + 5;
float objectScalingFactor = mObjectDistance / oldObjectDistance;
Matrix.scaleM(rotationMatrix, 0, objectScalingFactor, objectScalingFactor, objectScalingFactor);
// Matrix.multiplyMV(posVec, 0, rotationMatrix, 0, mModelCube, 12);
if(i1==1){
Matrix.multiplyMV(posVec, 0, rotationMatrix, 0, mModelCube, 12);
}else if(i1==0){
Matrix.multiplyMV(posVec, 0, rotationMatrix, 0, mModelCube2, 12);
}
// Now get the up or down angle, between -20 and 20 degrees
float angleY = (float) Math.random() * 80 - 40; // angle in Y plane, between -40 and 40
angleY = (float) Math.toRadians(angleY);
float newY = (float)Math.tan(angleY) * mObjectDistance;
// Matrix.setIdentityM(mModelCube, 0);
// Matrix.translateM(mModelCube, 0, posVec[0], newY, posVec[2]);
if(i1==1){
Matrix.setIdentityM(mModelCube, 0);
Matrix.translateM(mModelCube, 0, posVec[0], newY, posVec[2]);
}else if(i1==0){
Matrix.setIdentityM(mModelCube2, 0);
Matrix.translateM(mModelCube2, 0, posVec[0], newY, posVec[2]);
}
System.out.println("hideObject->i1:"+i1);
}
/**
* Check if user is looking at object by calculating where the object is in eye-space.
* @return
*/
// private boolean isLookingAtObject() {
// float[] initVec = {0, 0, 0, 1.0f};
// float[] objPositionVec = new float[4];
//
// // Convert object space to camera space. Use the headView from onNewFrame.
// Matrix.multiplyMM(mModelView, 0, mHeadView, 0, mModelCube, 0);
// Matrix.multiplyMV(objPositionVec, 0, mModelView, 0, initVec, 0);
//
// Matrix.multiplyMM(mModelView, 0, mHeadView, 0, mModelCube2, 0);
// Matrix.multiplyMV(objPositionVec, 0, mModelView, 0, initVec, 0);
//
// float pitch = (float)Math.atan2(objPositionVec[1], -objPositionVec[2]);
// float yaw = (float)Math.atan2(objPositionVec[0], -objPositionVec[2]);
//
// Log.i(TAG, "Object position: X: " + objPositionVec[0]
// + " Y: " + objPositionVec[1] + " Z: " + objPositionVec[2]);
// Log.i(TAG, "Object Pitch: " + pitch +" Yaw: " + yaw);
//
// return (Math.abs(pitch) < PITCH_LIMIT) && (Math.abs(yaw) < YAW_LIMIT);
// }
private boolean isLookingAtObject(int i1) {
float[] initVec = {0, 0, 0, 1.0f};
float[] objPositionVec = new float[4];
System.out.println("isLookingAtObject1->i1:"+i1);
// Convert object space to camera space. Use the headView from onNewFrame.
if(i1==1)
{
Matrix.multiplyMM(mModelView, 0, mHeadView, 0, mModelCube, 0);
Matrix.multiplyMV(objPositionVec, 0, mModelView, 0, initVec, 0);
intCurrentI = i1;
}else if(i1 == 0){
Matrix.multiplyMM(mModelView, 0, mHeadView, 0, mModelCube2, 0);
Matrix.multiplyMV(objPositionVec, 0, mModelView, 0, initVec, 0);
intCurrentI = i1;
}
float pitch = (float)Math.atan2(objPositionVec[1], -objPositionVec[2]);
float yaw = (float)Math.atan2(objPositionVec[0], -objPositionVec[2]);
// Log.i(TAG, "Object position: X: " + objPositionVec[0] + " Y: " + objPositionVec[1] + " Z: " + objPositionVec[2]);
// Log.i(TAG, "Object Pitch: " + pitch +" Yaw: " + yaw);
//---------------------------------
// mOverlayView.show3DToast("intCurrentI:"+intCurrentI);
System.out.println("isLookingAtObject1->intCurrentI:"+intCurrentI);
//---------------------------------
boolean bool1 =(Math.abs(pitch) < PITCH_LIMIT) && (Math.abs(yaw) < YAW_LIMIT);
// return (Math.abs(pitch) < PITCH_LIMIT) && (Math.abs(yaw) < YAW_LIMIT);
System.out.println("isLookingAtObject2->intCurrentI:"+intCurrentI+"bool1:"+bool1);
return bool1;
}
}
package com.example.atest22;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class CardboardOverlayView extends LinearLayout {
private static final String TAG = CardboardOverlayView.class.getSimpleName();
private final CardboardOverlayEyeView mLeftView;
private final CardboardOverlayEyeView mRightView;
private AlphaAnimation mTextFadeAnimation;
public CardboardOverlayView(Context context, AttributeSet attrs) {
super(context, attrs);
setOrientation(HORIZONTAL);
LayoutParams params = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1.0f);
params.setMargins(0, 0, 0, 0);
mLeftView = new CardboardOverlayEyeView(context, attrs);
mLeftView.setLayoutParams(params);
addView(mLeftView);
mRightView = new CardboardOverlayEyeView(context, attrs);
mRightView.setLayoutParams(params);
addView(mRightView);
// Set some reasonable defaults.
setDepthOffset(0.016f);
setColor(Color.rgb(150, 255, 180));
setVisibility(View.VISIBLE);
mTextFadeAnimation = new AlphaAnimation(1.0f, 0.0f);
mTextFadeAnimation.setDuration(5000);
}
public void show3DToast(String message) {
setText(message);
setTextAlpha(1f);
mTextFadeAnimation.setAnimationListener(new EndAnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
setTextAlpha(0f);
}
});
startAnimation(mTextFadeAnimation);
}
private abstract class EndAnimationListener implements Animation.AnimationListener {
@Override public void onAnimationRepeat(Animation animation) {}
@Override public void onAnimationStart(Animation animation) {}
}
private void setDepthOffset(float offset) {
mLeftView.setOffset(offset);
mRightView.setOffset(-offset);
}
private void setText(String text) {
mLeftView.setText(text);
mRightView.setText(text);
}
private void setTextAlpha(float alpha) {
mLeftView.setTextViewAlpha(alpha);
mRightView.setTextViewAlpha(alpha);
}
private void setColor(int color) {
mLeftView.setColor(color);
mRightView.setColor(color);
}
/**
* A simple view group containing some horizontally centered text underneath a horizontally
* centered image.
*
* This is a helper class for CardboardOverlayView.
*/
private class CardboardOverlayEyeView extends ViewGroup {
private final ImageView imageView;
private final TextView textView;
private float offset;
public CardboardOverlayEyeView(Context context, AttributeSet attrs) {
super(context, attrs);
imageView = new ImageView(context, attrs);
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageView.setAdjustViewBounds(true); // Preserve aspect ratio.
addView(imageView);
textView = new TextView(context, attrs);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14.0f);
textView.setTypeface(textView.getTypeface(), Typeface.BOLD);
textView.setGravity(Gravity.CENTER);
textView.setShadowLayer(3.0f, 0.0f, 0.0f, Color.DKGRAY);
addView(textView);
}
public void setColor(int color) {
imageView.setColorFilter(color);
textView.setTextColor(color);
}
public void setText(String text) {
textView.setText(text);
}
public void setTextViewAlpha(float alpha) {
textView.setAlpha(alpha);
}
public void setOffset(float offset) {
this.offset = offset;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
// Width and height of this ViewGroup.
final int width = right - left;
final int height = bottom - top;
// The size of the image, given as a fraction of the dimension as a ViewGroup. We multiply
// both width and heading with this number to compute the image's bounding box. Inside the
// box, the image is the horizontally and vertically centered.
final float imageSize = 0.12f;
// The fraction of this ViewGroup's height by which we shift the image off the ViewGroup's
// center. Positive values shift downwards, negative values shift upwards.
final float verticalImageOffset = -0.07f;
// Vertical position of the text, specified in fractions of this ViewGroup's height.
final float verticalTextPos = 0.52f;
// Layout ImageView
float imageMargin = (1.0f - imageSize) / 2.0f;
float leftMargin = (int) (width * (imageMargin + offset));
float topMargin = (int) (height * (imageMargin + verticalImageOffset));
imageView.layout(
(int) leftMargin, (int) topMargin,
(int) (leftMargin + width * imageSize), (int) (topMargin + height * imageSize));
// Layout TextView
leftMargin = offset * width;
topMargin = height * verticalTextPos;
textView.layout(
(int) leftMargin, (int) topMargin,
(int) (leftMargin + width), (int) (topMargin + height * (1.0f - verticalTextPos)));
}
}
}
package com.example.atest22;
public final class WorldLayoutData {
public static final float[] CUBE_COORDS = new float[] {
// Front face
-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
// Right face
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
// Back face
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
// Left face
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
// Top face
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
// Bottom face
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
};
public static final float[] CUBE_COLORS = new float[] {
// front, green
0f, 0.5273f, 0.2656f, 1.0f,
0f, 0.5273f, 0.2656f, 1.0f,
0f, 0.5273f, 0.2656f, 1.0f,
0f, 0.5273f, 0.2656f, 1.0f,
0f, 0.5273f, 0.2656f, 1.0f,
0f, 0.5273f, 0.2656f, 1.0f,
// right, blue
0.0f, 0.3398f, 0.9023f, 1.0f,
0.0f, 0.3398f, 0.9023f, 1.0f,
0.0f, 0.3398f, 0.9023f, 1.0f,
0.0f, 0.3398f, 0.9023f, 1.0f,
0.0f, 0.3398f, 0.9023f, 1.0f,
0.0f, 0.3398f, 0.9023f, 1.0f,
// back, also green
0f, 0.5273f, 0.2656f, 1.0f,
0f, 0.5273f, 0.2656f, 1.0f,
0f, 0.5273f, 0.2656f, 1.0f,
0f, 0.5273f, 0.2656f, 1.0f,
0f, 0.5273f, 0.2656f, 1.0f,
0f, 0.5273f, 0.2656f, 1.0f,
// left, also blue
0.0f, 0.3398f, 0.9023f, 1.0f,
0.0f, 0.3398f, 0.9023f, 1.0f,
0.0f, 0.3398f, 0.9023f, 1.0f,
0.0f, 0.3398f, 0.9023f, 1.0f,
0.0f, 0.3398f, 0.9023f, 1.0f,
0.0f, 0.3398f, 0.9023f, 1.0f,
// top, red
0.8359375f, 0.17578125f, 0.125f, 1.0f,
0.8359375f, 0.17578125f, 0.125f, 1.0f,
0.8359375f, 0.17578125f, 0.125f, 1.0f,
0.8359375f, 0.17578125f, 0.125f, 1.0f,
0.8359375f, 0.17578125f, 0.125f, 1.0f,
0.8359375f, 0.17578125f, 0.125f, 1.0f,
// bottom, also red
0.8359375f, 0.17578125f, 0.125f, 1.0f,
0.8359375f, 0.17578125f, 0.125f, 1.0f,
0.8359375f, 0.17578125f, 0.125f, 1.0f,
0.8359375f, 0.17578125f, 0.125f, 1.0f,
0.8359375f, 0.17578125f, 0.125f, 1.0f,
0.8359375f, 0.17578125f, 0.125f, 1.0f,
};
public static final float[] CUBE_FOUND_COLORS = new float[] {
// front, yellow
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
// right, yellow
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
// back, yellow
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
// left, yellow
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
// top, yellow
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
// bottom, yellow
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
1.0f, 0.6523f, 0.0f, 1.0f,
};
public static final float[] CUBE_NORMALS = new float[] {
// Front face
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
// Right face
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
// Back face
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f,
// Left face
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
// Top face
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
// Bottom face
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f
};
public static final float[] FLOOR_COORDS = new float[] {
200f, 0, -200f,
-200f, 0, -200f,
-200f, 0, 200f,
200f, 0, -200f,
-200f, 0, 200f,
200f, 0, 200f,
};
public static final float[] FLOOR_NORMALS = new float[] {
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
public static final float[] FLOOR_COLORS = new float[] {
0.0f, 0.3398f, 0.9023f, 1.0f,
0.0f, 0.3398f, 0.9023f, 1.0f,
0.0f, 0.3398f, 0.9023f, 1.0f,
0.0f, 0.3398f, 0.9023f, 1.0f,
0.0f, 0.3398f, 0.9023f, 1.0f,
0.0f, 0.3398f, 0.9023f, 1.0f,
};
}