/* * Copyright 2008-2013, ETH Zürich, Samuel Welten, Michael Kuhn, Tobias Langner, * Sandro Affentranger, Lukas Bossard, Michael Grob, Rahul Jain, * Dominic Langenegger, Sonia Mayor Alonso, Roger Odermatt, Tobias Schlueter, * Yannick Stucki, Sebastian Wendland, Samuel Zehnder, Samuel Zihlmann, * Samuel Zweifel * * This file is part of Jukefox. * * Jukefox is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or any later version. Jukefox is * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * Jukefox. If not, see <http://www.gnu.org/licenses/>. */ package ch.ethz.dcg.pancho3.view.tabs.opengl; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.ShortBuffer; import java.util.ArrayList; import java.util.List; import javax.microedition.khronos.opengles.GL10; import ch.ethz.dcg.jukefox.model.collection.MapAlbum; public class RegionPlaylistCreator { @SuppressWarnings("unused") private static final String TAG = RegionPlaylistCreator.class.getCanonicalName(); private final MapRenderer mapRenderer; private final OnRegionCreatedListener onRegionCreatedListener; private int verts = 1; private FloatBuffer mFVertexBuffer; private ShortBuffer mIndexBuffer; private List<Float> coords; private boolean create = false; public static interface OnRegionCreatedListener { void onRegionCreated(List<MapAlbum> albumsInRegion); } public RegionPlaylistCreator(MapRenderer mapRenderer, OnRegionCreatedListener onRegionCreatedListener, float screenPosX, float screenPosY) { this.mapRenderer = mapRenderer; this.onRegionCreatedListener = onRegionCreatedListener; float[] mapCoords = transformScreenToMapCoordinates(screenPosX, screenPosY); coords = new ArrayList<Float>(); ByteBuffer vbb = ByteBuffer.allocateDirect(verts * 3 * 4); vbb.order(ByteOrder.nativeOrder()); mFVertexBuffer = vbb.asFloatBuffer(); ByteBuffer ibb = ByteBuffer.allocateDirect(verts * 2); ibb.order(ByteOrder.nativeOrder()); mIndexBuffer = ibb.asShortBuffer(); coords.add(mapCoords[0]); coords.add(1f); coords.add(mapCoords[1]); mFVertexBuffer.put(mapCoords[0]); mFVertexBuffer.put(1f); mFVertexBuffer.put(mapCoords[1]); for (int i = 0; i < verts; i++) { mIndexBuffer.put((short) i); } mFVertexBuffer.position(0); mIndexBuffer.position(0); } public float[] transformScreenToMapCoordinates(float screenPosX, float screenPosY) { float coverSize = GlAlbumCover.COVER_SIZE; float camPosZ = mapRenderer.getCamera().getPosZ(); float camPosX = mapRenderer.getCamera().getPosX(); float camPosY = mapRenderer.getCamera().getPosY(); float widthFactor = mapRenderer.getViewRatio() / mapRenderer.getCamera().getFrontClippingPlane(); float heightFactor = 1f / mapRenderer.getCamera().getFrontClippingPlane(); float visibleMinX = camPosX - camPosY * widthFactor - 2 * coverSize; float visibleMaxX = camPosX + camPosY * widthFactor + 2 * coverSize; float visibleMinZ = camPosZ - camPosY * heightFactor - 2 * coverSize; float visibleMaxZ = camPosZ + camPosY * heightFactor + 2 * coverSize; float posX = visibleMinX + (visibleMaxX - visibleMinX) * screenPosX / mapRenderer.getViewWidth(); float posZ = visibleMinZ + (visibleMaxZ - visibleMinZ) * screenPosY / mapRenderer.getViewHeight(); return new float[] { posX, posZ }; } public void addPoint(float screenPosX, float screenPosY) { float[] mapCoords = transformScreenToMapCoordinates(screenPosX, screenPosY); ByteBuffer vbb = ByteBuffer.allocateDirect((verts + 1) * 3 * 4); vbb.order(ByteOrder.nativeOrder()); FloatBuffer tempBuffer1 = vbb.asFloatBuffer(); ByteBuffer ibb = ByteBuffer.allocateDirect((verts + 1) * 2); ibb.order(ByteOrder.nativeOrder()); ShortBuffer tempBuffer2 = ibb.asShortBuffer(); coords.add(mapCoords[0]); coords.add(1f); coords.add(mapCoords[1]); for (Float f : coords) { tempBuffer1.put(f); } for (int i = 0; i < verts + 1; i++) { tempBuffer2.put((short) i); } tempBuffer1.position(0); tempBuffer2.position(0); mFVertexBuffer = tempBuffer1; mIndexBuffer = tempBuffer2; verts++; } public void createPlaylist() { create = true; } public boolean hasToGetAlbums() { return create; } public void getAlbumsInPlaylist(GL10 gl) { float coverSize = GlAlbumCover.COVER_SIZE; float camPosZ = mapRenderer.getCamera().getPosZ(); float camPosX = mapRenderer.getCamera().getPosX(); float camPosY = mapRenderer.getCamera().getPosY(); float widthFactor = mapRenderer.getViewRatio() / mapRenderer.getCamera().getFrontClippingPlane(); float heightFactor = 1f / mapRenderer.getCamera().getFrontClippingPlane(); float visibleMinX = camPosX - camPosY * widthFactor - 2 * coverSize; float visibleMaxX = camPosX + camPosY * widthFactor + 2 * coverSize; float visibleMinZ = camPosZ - camPosY * heightFactor - 2 * coverSize; float visibleMaxZ = camPosZ + camPosY * heightFactor + 2 * coverSize; // Add offset to max/min values to get real visible area float screenMinX = visibleMinX;// + 4*coverSize; float screenMaxX = visibleMaxX;// - 4*coverSize; float screenMinZ = visibleMinZ;// + 4*coverSize; float screenMaxZ = visibleMaxZ;// - 4*coverSize; float rangeX = screenMaxX - screenMinX; float rangeZ = screenMaxZ - screenMinZ; float width = mapRenderer.getViewWidth(); float height = mapRenderer.getViewHeight(); List<GlAlbumCover> albums = mapRenderer.getAlbums(); ByteBuffer result = ByteBuffer.allocate(4); List<MapAlbum> albumsInRegion = new ArrayList<MapAlbum>(); for (GlAlbumCover glAlbum : albums) { float[] coords = glAlbum.getMapAlbum().getGridCoords(); float readX = (coords[0] - screenMinX) * width / rangeX; float readY = (-coords[1] + screenMaxZ) * height / rangeZ; gl.glReadPixels((int) readX, (int) readY, 1, 1, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, result); // Only check items that are on the screen if (readX < 0 || readX > width || readY < 0 || readY > height) { continue; } int res0 = result.get(0) & 0xFF; int res1 = result.get(1) & 0xFF; int res2 = result.get(2) & 0xFF; if (res0 > 0 && res1 > 0 && res2 > 0) { albumsInRegion.add(glAlbum.getMapAlbum()); } } onRegionCreatedListener.onRegionCreated(albumsInRegion); } /** * draw the Plane * * @param gl * the OpenGl object */ public void draw(GL10 gl) { gl.glBindTexture(GL10.GL_TEXTURE_2D, 0); gl.glColor4f(1, 1, 1, 0.2f); gl.glFrontFace(GL10.GL_CCW); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mFVertexBuffer); gl.glDrawElements(GL10.GL_TRIANGLE_FAN, verts, GL10.GL_UNSIGNED_SHORT, mIndexBuffer); } }