Package se.llbit.chunky.map

Source Code of se.llbit.chunky.map.BlockLayer

/* Copyright (c) 2014 Jesper Öqvist <jesper@llbit.se>
*
* This file is part of Chunky.
*
* Chunky 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
* (at your option) any later version.
*
* Chunky 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 Chunky.  If not, see <http://www.gnu.org/licenses/>.
*/
package se.llbit.chunky.map;

import java.awt.Graphics;
import java.awt.image.DataBufferInt;

import org.apache.commons.math3.util.FastMath;

import se.llbit.chunky.renderer.scene.Scene;
import se.llbit.chunky.resources.Texture;
import se.llbit.chunky.world.Biomes;
import se.llbit.chunky.world.Block;
import se.llbit.chunky.world.Chunk;
import se.llbit.chunky.world.ChunkView;
import se.llbit.math.Color;

/**
* A layer with block data.
* @author Jesper Öqvist <jesper@llbit.se>
*/
public class BlockLayer extends AbstractLayer {
  private final byte[] blocks;
  private final byte[] biomes;
  private final int avgColor;

  /**
   * Load layer from block data
   * @param blockData
   * @param chunkBiomes
   * @param layer
   */
  public BlockLayer(byte[] blockData, byte[] chunkBiomes, int layer) {
    blocks = new byte[Chunk.X_MAX*Chunk.Z_MAX];
    biomes = new byte[Chunk.X_MAX*Chunk.Z_MAX];
    double[] sum = new double[3];
    double[] rgb = new double[3];
    for (int x = 0; x < Chunk.X_MAX; ++x) {
      for (int z = 0; z < Chunk.Z_MAX; ++z) {
        byte block = blockData[Chunk.chunkIndex(x, layer, z)];
        byte biome = chunkBiomes[Chunk.chunkXZIndex(x, z)];
        blocks[x*Chunk.Z_MAX+z] = block;
        biomes[x*Chunk.Z_MAX+z] = block;
        Color.getRGBComponents(avgBlockColor(block, biome), rgb);
        sum[0] += rgb[0];
        sum[1] += rgb[1];
        sum[2] += rgb[2];
      }
    }
    sum[0] /= Chunk.X_MAX*Chunk.Z_MAX;
    sum[1] /= Chunk.X_MAX*Chunk.Z_MAX;
    sum[2] /= Chunk.X_MAX*Chunk.Z_MAX;
    avgColor = Color.getRGB(sum);
  }

  /**
   * Render this layer
   * @param rbuff
   * @param cx
   * @param cz
   */
  @Override
  public synchronized void render(MapBuffer rbuff, int cx, int cz) {
    ChunkView view = rbuff.getView();
    int x0 = view.chunkScale * (cx - view.px0);
    int z0 = view.chunkScale * (cz - view.pz0);

    if (view.chunkScale == 1) {
      rbuff.setRGB(x0, z0, getAvgColor());
    } else if (view.chunkScale == 16) {

      for (int z = 0; z < Chunk.Z_MAX; ++z) {
        int yp = z0 + z;

        for (int x = 0; x < Chunk.X_MAX; ++x) {
          int xp = x0 + x;

          byte block = blocks[x*Chunk.Z_MAX + z];
          byte biome = biomes[x*Chunk.Z_MAX + z];
          rbuff.setRGB(xp, yp, avgBlockColor(block, biome));
        }
      }
    } else if (view.chunkScale == 16*16) {
      for (int z = 0; z < Chunk.Z_MAX; ++z) {
        int yp0 = z0 + z * 16;

        for (int x = 0; x < Chunk.X_MAX; ++x) {
          int xp0 = x0 + x * 16;

          byte block = blocks[x*Chunk.Z_MAX + z];
          if (block == Block.AIR.id) {
            rbuff.fillRect(xp0, yp0, 16, 16, 0xFFFFFFFF);
            continue;
          }

          switch ((int) block) {
          case Block.GRASS_ID:
          case Block.TALLGRASS_ID:
          case Block.LEAVES_ID:
          case Block.LEAVES2_ID:
          case Block.VINES_ID:
          {
            Texture tex = Block.get(block).getIcon();
            for (int i = 0; i < 16; ++i) {
              for (int j = 0; j < 16; ++j) {
                float[] rgb = tex.getColor(j, i);
                if (rgb[3] != 0) {
                  rbuff.setRGB(xp0 + j, yp0 + i, getBiomeColor(rgb, block, biomes[x*Chunk.Z_MAX+z]));
                } else {
                  rbuff.setRGB(xp0 + j, yp0 + i, 0xFFFFFFFF);
                }
              }
            }
            break;
          }
          default:
          {
            int[] tex = ((DataBufferInt) Block.get(block).getIcon()
                .getImage().getRaster().getDataBuffer())
                .getData();
            for (int i = 0; i < 16; ++i) {
              for (int j = 0; j < 16; ++j) {
                int rgb = tex[i * 16 + j];
                if ((rgb & 0xFF000000) != 0) {
                  rbuff.setRGB(xp0 + j, yp0 + i, rgb);
                } else {
                  rbuff.setRGB(xp0 + j, yp0 + i, 0xFFFFFFFF);
                }
              }
            }
          }
          }
        }
      }
    }
    // unsupported chunkScale if none of the above
  }

  private int avgBlockColor(byte block, byte biome) {
    if (block == Block.AIR.id) {
      return 0xFFFFFFFF;
    } else {
      switch ((int) block) {
      case Block.GRASS_ID:
      case Block.TALLGRASS_ID:
      case Block.LEAVES_ID:
      case Block.LEAVES2_ID:
      case Block.VINES_ID:
      {
        float[] rgb = Block.get(block).getIcon().getAvgColorLinear();
        return getBiomeColor(rgb, block, biome);
      }
      default:
        return Block.get(block).getIcon().getAvgColor();
      }
    }
  }

  private int getBiomeColor(float[] rgb, byte block, byte biome) {
    float[] biomeColor;
    float alpha = rgb[3];
    switch ((int) block) {
    case Block.GRASS_ID:
    case Block.TALLGRASS_ID:
      biomeColor = Biomes.getGrassColorLinear(biome);
      return Color.getRGB(
          (1-alpha) + alpha * FastMath.pow(rgb[0] * biomeColor[0], Scene.DEFAULT_GAMMA_INV),
          (1-alpha) + alpha * FastMath.pow(rgb[1] * biomeColor[1], Scene.DEFAULT_GAMMA_INV),
          (1-alpha) + alpha * FastMath.pow(rgb[2] * biomeColor[2], Scene.DEFAULT_GAMMA_INV));
    case Block.LEAVES_ID:
    case Block.LEAVES2_ID:
    case Block.VINES_ID:
      biomeColor = Biomes.getFoliageColorLinear(biome);
      return Color.getRGB(
          (1-alpha) + alpha * FastMath.pow(rgb[0] * biomeColor[0], Scene.DEFAULT_GAMMA_INV),
          (1-alpha) + alpha * FastMath.pow(rgb[1] * biomeColor[1], Scene.DEFAULT_GAMMA_INV),
          (1-alpha) + alpha * FastMath.pow(rgb[2] * biomeColor[2], Scene.DEFAULT_GAMMA_INV));
    default:
      return Color.getRGB(
          (1-alpha) + alpha * FastMath.pow(rgb[0], Scene.DEFAULT_GAMMA_INV),
          (1-alpha) + alpha * FastMath.pow(rgb[1], Scene.DEFAULT_GAMMA_INV),
          (1-alpha) + alpha * FastMath.pow(rgb[2], Scene.DEFAULT_GAMMA_INV));
    }
  }

  /**
   * Render block highlight
   * @param rbuff
   * @param cx
   * @param cz
   * @param hlBlock
   * @param highlight
   */
  @Override
  public synchronized void renderHighlight(MapBuffer rbuff, int cx, int cz,
      Block hlBlock, java.awt.Color highlight) {

    ChunkView view = rbuff.getView();
    int x0 = view.chunkScale * (cx - view.px0);
    int z0 = view.chunkScale * (cz - view.pz0);

    if (blocks == null)
      return;

    Graphics g = rbuff.getGraphics();
    g.setColor(new java.awt.Color(1,1,1,0.35f));
    g.fillRect(x0, z0, view.chunkScale, view.chunkScale);
    g.setColor(highlight);

    if (view.chunkScale == 16) {

      for (int x = 0; x < 16; ++x) {
        int xp = x0 + x;

        for (int z = 0; z < 16; ++z) {
          int yp = z0 + z;

          if (hlBlock.id == (0xFF & blocks[x * 16 + z])) {
            rbuff.setRGB(xp, yp, highlight.getRGB());
          }
        }
      }
    } else {
      int blockScale = view.chunkScale / 16;

      for (int x = 0; x < 16; ++x) {
        int xp0 = x0 + x * blockScale;
        int xp1 = xp0 + blockScale;

        for (int z = 0; z < 16; ++z) {
          int yp0 = z0 + z * blockScale;
          int yp1 = yp0 + blockScale;

          if (hlBlock.id == (0xFF & blocks[x * 16 + z])) {
            g.fillRect(xp0, yp0, xp1 - xp0, yp1 - yp0);
          }
        }
      }
    }
  }

  @Override
  public int getAvgColor() {
    return avgColor;
  }
}
TOP

Related Classes of se.llbit.chunky.map.BlockLayer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.