📄 globaltime.java
字号:
/* * Copyright (C) 2007 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.android.globaltime;import java.io.ByteArrayInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.Calendar;import java.util.List;import java.util.Locale;import java.util.TimeZone;import javax.microedition.khronos.egl.*;import javax.microedition.khronos.opengles.*;import android.app.Activity;import android.content.Context;import android.content.res.AssetManager;import android.graphics.Canvas;import android.opengl.Object3D;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.os.MessageQueue;import android.util.Log;import android.view.KeyEvent;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.animation.AccelerateDecelerateInterpolator;import android.view.animation.DecelerateInterpolator;import android.view.animation.Interpolator;/** * The main View of the GlobalTime Activity. */class GTView extends SurfaceView implements SurfaceHolder.Callback { /** * A TimeZone object used to compute the current UTC time. */ private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("utc"); /** * The Sun's color is close to that of a 5780K blackbody. */ private static final float[] SUNLIGHT_COLOR = { 1.0f, 0.9375f, 0.91015625f, 1.0f }; /** * The inclination of the earth relative to the plane of the ecliptic * is 23.45 degrees. */ private static final float EARTH_INCLINATION = 23.45f * Shape.PI / 180.0f; /** Seconds in a day */ private static final int SECONDS_PER_DAY = 24 * 60 * 60; /** Flag for the depth test */ private static final boolean PERFORM_DEPTH_TEST= false; /** Use raw time zone offsets, disregarding "summer time." If false, * current offsets will be used, which requires a much longer startup time * in order to sort the city database. */ private static final boolean USE_RAW_OFFSETS = true; /** * The earth's atmosphere. */ private static final Annulus ATMOSPHERE = new Annulus(0.0f, 0.0f, 1.75f, 0.9f, 1.08f, 0.4f, 0.4f, 0.8f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 50); /** * The tesselation of the earth by latitude. */ private static final int SPHERE_LATITUDES = 25; /** * The tesselation of the earth by longitude. */ private static int SPHERE_LONGITUDES = 25; /** * A flattened version of the earth. The normals are computed identically * to those of the round earth, allowing the day/night lighting to be * applied to the flattened surface. */ private static Sphere worldFlat = new LatLongSphere(0.0f, 0.0f, 0.0f, 1.0f, SPHERE_LATITUDES, SPHERE_LONGITUDES, 0.0f, 360.0f, true, true, false, true); /** * The earth. */ private Object3D mWorld; /** * Geometry of the city lights */ private PointCloud mLights; /** * True if the activiy has been initialized. */ boolean mInitialized = false; /** * True if we're in alphabetic entry mode. */ private boolean mAlphaKeySet = false; private EGLContext mEGLContext; private EGLSurface mEGLSurface; private EGLDisplay mEGLDisplay; private EGLConfig mEGLConfig; GLView mGLView; // Rotation and tilt of the Earth private float mRotAngle = 0.0f; private float mTiltAngle = 0.0f; // Rotational velocity of the orbiting viewer private float mRotVelocity = 1.0f; // Rotation of the flat view private float mWrapX = 0.0f; private float mWrapVelocity = 0.0f; private float mWrapVelocityFactor = 0.01f; // Toggle switches private boolean mDisplayAtmosphere = true; private boolean mDisplayClock = false; private boolean mClockShowing = false; private boolean mDisplayLights = false; private boolean mDisplayWorld = true; private boolean mDisplayWorldFlat = false; private boolean mSmoothShading = true; // City search string private String mCityName = ""; // List of all cities private List<City> mClockCities; // List of cities matching a user-supplied prefix private List<City> mCityNameMatches = new ArrayList<City>(); private List<City> mCities; // Start time for clock fade animation private long mClockFadeTime; // Interpolator for clock fade animation private Interpolator mClockSizeInterpolator = new DecelerateInterpolator(1.0f); // Index of current clock private int mCityIndex; // Current clock private Clock mClock; // City-to-city flight animation parameters private boolean mFlyToCity = false; private long mCityFlyStartTime; private float mCityFlightTime; private float mRotAngleStart, mRotAngleDest; private float mTiltAngleStart, mTiltAngleDest; // Interpolator for flight motion animation private Interpolator mFlyToCityInterpolator = new AccelerateDecelerateInterpolator(); private static int sNumLights; private static int[] sLightCoords; // static Map<Float,int[]> cityCoords = new HashMap<Float,int[]>(); // Arrays for GL calls private float[] mClipPlaneEquation = new float[4]; private float[] mLightDir = new float[4]; // Calendar for computing the Sun's position Calendar mSunCal = Calendar.getInstance(UTC_TIME_ZONE); // Triangles drawn per frame private int mNumTriangles; private long startTime; private static final int MOTION_NONE = 0; private static final int MOTION_X = 1; private static final int MOTION_Y = 2; private static final int MIN_MANHATTAN_DISTANCE = 20; private static final float ROTATION_FACTOR = 1.0f / 30.0f; private static final float TILT_FACTOR = 0.35f; // Touchscreen support private float mMotionStartX; private float mMotionStartY; private float mMotionStartRotVelocity; private float mMotionStartTiltAngle; private int mMotionDirection; public void surfaceCreated(SurfaceHolder holder) { EGL10 egl = (EGL10)EGLContext.getEGL(); mEGLSurface = egl.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, this, null); egl.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext); } public void surfaceDestroyed(SurfaceHolder holder) { // nothing to do } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // nothing to do } /** * Set up the view. * * @param context the Context * @param am an AssetManager to retrieve the city database from */ public GTView(Context context) { super(context); getHolder().addCallback(this); getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU); AssetManager am = context.getAssets(); startTime = System.currentTimeMillis(); EGL10 egl = (EGL10)EGLContext.getEGL(); EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); int[] version = new int[2]; egl.eglInitialize(dpy, version); int[] configSpec = { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE }; EGLConfig[] configs = new EGLConfig[1]; int[] num_config = new int[1]; egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config); mEGLConfig = configs[0]; mEGLContext = egl.eglCreateContext(dpy, mEGLConfig, EGL10.EGL_NO_CONTEXT, null); mEGLDisplay = dpy; mClock = new Clock(); setFocusable(true); setFocusableInTouchMode(true); requestFocus(); try { loadAssets(am); } catch (IOException ioe) { ioe.printStackTrace(); throw new RuntimeException(ioe); } catch (ArrayIndexOutOfBoundsException aioobe) { aioobe.printStackTrace(); throw new RuntimeException(aioobe); } } /** * Destroy the view. */ public void destroy() { EGL10 egl = (EGL10)EGLContext.getEGL(); egl.eglMakeCurrent(mEGLDisplay, egl.EGL_NO_SURFACE, egl.EGL_NO_SURFACE, egl.EGL_NO_CONTEXT); egl.eglDestroyContext(mEGLDisplay, mEGLContext); egl.eglDestroySurface(mEGLDisplay, mEGLSurface); egl.eglTerminate(mEGLDisplay); mEGLContext = null; } /** * Begin animation. */ public void startAnimating() { mHandler.sendEmptyMessage(INVALIDATE); } /** * Quit animation. */ public void stopAnimating() { mHandler.removeMessages(INVALIDATE); } /** * Read a two-byte integer from the input stream. */ private int readInt16(InputStream is) throws IOException { int lo = is.read(); int hi = is.read(); return (hi << 8) | lo; } /** * Returns the offset from UTC for the given city. If USE_RAW_OFFSETS * is true, summer/daylight savings is ignored. */ private static float getOffset(City c) { return USE_RAW_OFFSETS ? c.getRawOffset() : c.getOffset(); } private InputStream cache(InputStream is) throws IOException { int nbytes = is.available(); byte[] data = new byte[nbytes]; int nread = 0; while (nread < nbytes) { nread += is.read(data, nread, nbytes - nread); } return new ByteArrayInputStream(data); } /** * Load the city and lights databases. * * @param am the AssetManager to load from. */ private void loadAssets(final AssetManager am) throws IOException { Locale locale = Locale.getDefault(); String language = locale.getLanguage(); String country = locale.getCountry(); InputStream cis = null; try { // Look for (e.g.) cities_fr_FR.dat or cities_fr_CA.dat cis = am.open("cities_" + language + "_" + country + ".dat"); } catch (FileNotFoundException e1) { try { // Look for (e.g.) cities_fr.dat or cities_fr.dat cis = am.open("cities_" + language + ".dat"); } catch (FileNotFoundException e2) { try {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -