@Override public ByteBuffer getTile(final int clipmapLevel, final Tile tile) throws Exception { final int tileX = tile.getX(); final int tileY = tile.getY(); final byte[] heightMap = maps.get(clipmapLevel); final int heightMapSize = heightMapSizes.get(clipmapLevel); final ByteBuffer data = tileDataPool.get(); for (int y = 0; y < tileSize; y++) { for (int x = 0; x < tileSize; x++) { final int index = x + y * tileSize; final int heightX = tileX * tileSize + x; final int heightY = tileY * tileSize + y; if (heightX < 0 || heightX >= heightMapSize || heightY < 0 || heightY >= heightMapSize) { data.put(index * 3 + 0, (byte) 0); data.put(index * 3 + 1, (byte) 0); data.put(index * 3 + 2, (byte) 0); } else { data.put(index * 3 + 0, heightMap[3 * (heightY * heightMapSize + heightX) + 0]); data.put(index * 3 + 1, heightMap[3 * (heightY * heightMapSize + heightX) + 1]); data.put(index * 3 + 2, heightMap[3 * (heightY * heightMapSize + heightX) + 2]); } } } return data; }
@Override public float[] getTile(final int clipmapLevel, final Tile tile) throws Exception { final int tileX = tile.getX(); final int tileY = tile.getY(); final int baseClipmapLevel = availableClipmapLevels - clipmapLevel - 1; final int levelSize = 1 << baseClipmapLevel; final int size = inMemoryTerrainData.getSide(); final float[] heightData = inMemoryTerrainData.getHeightData(); final float[] data = new float[tileSize * tileSize]; for (int y = 0; y < tileSize; y++) { for (int x = 0; x < tileSize; x++) { final int index = x + y * tileSize; final int heightX = (tileX * tileSize + x) * levelSize; final int heightY = (tileY * tileSize + y) * levelSize; data[index] = getHeight(heightData, size, heightX, heightY); } } return data; }
@Override public Set<Tile> getInvalidTiles( final int clipmapLevel, final int tileX, final int tileY, final int numTilesX, final int numTilesY) throws Exception { final Set<Tile> updatedTiles[] = inMemoryTerrainData.getUpdatedTerrainTiles(); if (updatedTiles == null) { return null; } final int baseClipmapLevel = availableClipmapLevels - clipmapLevel - 1; final Set<Tile> tiles = Sets.newHashSet(); synchronized (updatedTiles[baseClipmapLevel]) { if (updatedTiles[baseClipmapLevel].isEmpty()) { return null; } int checkX, checkY; for (final Iterator<Tile> it = updatedTiles[baseClipmapLevel].iterator(); it.hasNext(); ) { final Tile tile = it.next(); checkX = tile.getX(); checkY = tile.getY(); if (checkX >= tileX && checkX < tileX + numTilesX && checkY >= tileY && checkY < tileY + numTilesY) { tiles.add(tile); it.remove(); } } } return tiles; }
@Override public ByteBuffer getTile(final int clipmapLevel, final Tile tile) throws Exception { final ByteBuffer data = tileDataPool.get(); final int tileX = tile.getX(); final int tileY = tile.getY(); final int baseClipmapLevel = availableClipmapLevels - clipmapLevel - 1; textureLock.lock(); try { for (int y = 0; y < tileSize; y++) { for (int x = 0; x < tileSize; x++) { if (Thread.interrupted()) { return null; } final int heightX = tileX * tileSize + x; final int heightY = tileY * tileSize + y; final double eval = function.eval(heightX << baseClipmapLevel, heightY << baseClipmapLevel, 0) * 0.4167f + 0.5f; final byte colIndex = (byte) (eval * 255); final ReadOnlyColorRGBA c = terrainColors[colIndex & 0xFF]; final int index = (x + y * tileSize) * 3; data.put(index, (byte) (c.getRed() * 255)); data.put(index + 1, (byte) (c.getGreen() * 255)); data.put(index + 2, (byte) (c.getBlue() * 255)); } } } finally { textureLock.unlock(); } return data; }