package com.thecrouchmode.level;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import com.thecrouchmode.LWJGL.util.Buffers;
import com.thecrouchmode.graphics.Model;
import com.thecrouchmode.vector.Matrix4f;
import com.thecrouchmode.vector.Vector3f;
public class Level{
public final int width;
public final int height;
public final int[] data;
public final Model model;
public Level(String path) throws IOException{
BufferedImage img = ImageIO.read(new File(path));
width = img.getWidth();
height = img.getHeight();
data = new int[width*height];
img.getRGB(0, 0, width, height, data, 0, width);
model = generateModel();
}
private Model generateModel(){
float tileSize = 2;
float ceilingHeight = 2;
List<Float> data = new ArrayList<>();
List<Integer> indices = new ArrayList<>();
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
System.out.println("Level tile: "+tile(x, y));
if(tile(x, y) != 0){
Level.createFloor(x, y, data, indices, tileSize, ceilingHeight);
Level.createCeiling(x, y, data, indices, tileSize, ceilingHeight);
if(tile(x, y+1) == 0) Level.createNorthWall(x, y, data, indices, tileSize, ceilingHeight);
if(tile(x, y-1) == 0) Level.createSouthWall(x, y, data, indices, tileSize, ceilingHeight);
if(tile(x-1, y) == 0) Level.createWestWall(x, y, data, indices, tileSize, ceilingHeight);
if(tile(x+1, y) == 0) Level.createEastWall(x, y, data, indices, tileSize, ceilingHeight);
}
}
}
System.out.println("Level indices: " + indices.size());
return new Model(
Buffers.floatArrayFromList(data),
Buffers.intArrayFromList(indices),
Matrix4f.identity);
}
private static void createFloor(int x, int y, List<Float> data, List<Integer> indices, float tileSize, float ceilingHeight){
int index = data.size()/8;
data.addAll(new Vector3f(x*tileSize, 0, y*tileSize).list());
data.addAll(Vector3f.yUnit.list());
data.add((float) 0);
data.add((float) 0);
data.addAll(new Vector3f((x+1)*tileSize, 0, y*tileSize).list());
data.addAll(Vector3f.yUnit.list());
data.add((float) 1);
data.add((float) 0);
data.addAll(new Vector3f((x+1)*tileSize, 0, (y+1)*tileSize).list());
data.addAll(Vector3f.yUnit.list());
data.add((float) 1);
data.add((float) 1);
data.addAll(new Vector3f(x*tileSize, 0, (y+1)*tileSize).list());
data.addAll(Vector3f.yUnit.list());
data.add((float) 0);
data.add((float) 1);
indices.add(index);
indices.add(index+3);
indices.add(index+2);
indices.add(index+2);
indices.add(index+1);
indices.add(index);
}
private static void createCeiling(int x, int y, List<Float> data, List<Integer> indices, float tileSize, float ceilingHeight){
int index = data.size()/8;
data.addAll(new Vector3f(x*tileSize, ceilingHeight, y*tileSize).list());
data.addAll(Vector3f.yUnit.negative().list());
data.add((float) 0);
data.add((float) 0);
data.addAll(new Vector3f((x+1)*tileSize, ceilingHeight, y*tileSize).list());
data.addAll(Vector3f.yUnit.negative().list());
data.add((float) 1);
data.add((float) 0);
data.addAll(new Vector3f((x+1)*tileSize, ceilingHeight, (y+1)*tileSize).list());
data.addAll(Vector3f.yUnit.negative().list());
data.add((float) 1);
data.add((float) 1);
data.addAll(new Vector3f(x*tileSize, ceilingHeight, (y+1)*tileSize).list());
data.addAll(Vector3f.yUnit.negative().list());
data.add((float) 0);
data.add((float) 1);
indices.add(index);
indices.add(index+1);
indices.add(index+2);
indices.add(index+2);
indices.add(index+3);
indices.add(index);
}
private static void createNorthWall(int x, int y, List<Float> data, List<Integer> indices, float tileSize, float ceilingHeight){
int index = data.size()/8;
data.addAll(new Vector3f(x*tileSize, 0, (y+1)*tileSize).list());
data.addAll(Vector3f.zUnit.negative().list());
data.add((float) 1);
data.add((float) 1);
data.addAll(new Vector3f((x+1)*tileSize, 0, (y+1)*tileSize).list());
data.addAll(Vector3f.zUnit.negative().list());
data.add((float) 0);
data.add((float) 1);
data.addAll(new Vector3f((x+1)*tileSize, ceilingHeight, (y+1)*tileSize).list());
data.addAll(Vector3f.zUnit.negative().list());
data.add((float) 0);
data.add((float) 0);
data.addAll(new Vector3f(x*tileSize, ceilingHeight, (y+1)*tileSize).list());
data.addAll(Vector3f.zUnit.negative().list());
data.add((float) 1);
data.add((float) 0);
indices.add(index);
indices.add(index+3);
indices.add(index+2);
indices.add(index+2);
indices.add(index+1);
indices.add(index);
}
private static void createSouthWall(int x, int y, List<Float> data, List<Integer> indices, float tileSize, float ceilingHeight){
int index = data.size()/8;
data.addAll(new Vector3f(x*tileSize, 0, (y)*tileSize).list());
data.addAll(Vector3f.zUnit.list());
data.add((float) 0);
data.add((float) 1);
data.addAll(new Vector3f((x+1)*tileSize, 0, (y)*tileSize).list());
data.addAll(Vector3f.zUnit.list());
data.add((float) 1);
data.add((float) 1);
data.addAll(new Vector3f((x+1)*tileSize, ceilingHeight, (y)*tileSize).list());
data.addAll(Vector3f.zUnit.list());
data.add((float) 1);
data.add((float) 0);
data.addAll(new Vector3f(x*tileSize, ceilingHeight, (y)*tileSize).list());
data.addAll(Vector3f.zUnit.list());
data.add((float) 0);
data.add((float) 0);
indices.add(index);
indices.add(index+1);
indices.add(index+2);
indices.add(index+2);
indices.add(index+3);
indices.add(index);
}
private static void createWestWall(int x, int y, List<Float> data, List<Integer> indices, float tileSize, float ceilingHeight){
int index = data.size()/8;
data.addAll(new Vector3f(x*tileSize, 0, y*tileSize).list());
data.addAll(Vector3f.xUnit.list());
data.add((float) 1);
data.add((float) 1);
data.addAll(new Vector3f(x*tileSize, 0, (y+1)*tileSize).list());
data.addAll(Vector3f.xUnit.list());
data.add((float) 0);
data.add((float) 1);
data.addAll(new Vector3f(x*tileSize, ceilingHeight, (y+1)*tileSize).list());
data.addAll(Vector3f.xUnit.list());
data.add((float) 0);
data.add((float) 0);
data.addAll(new Vector3f(x*tileSize, ceilingHeight, y*tileSize).list());
data.addAll(Vector3f.xUnit.list());
data.add((float) 1);
data.add((float) 0);
indices.add(index);
indices.add(index+3);
indices.add(index+2);
indices.add(index+2);
indices.add(index+1);
indices.add(index);
}
private static void createEastWall(int x, int y, List<Float> data, List<Integer> indices, float tileSize, float ceilingHeight){
int index = data.size()/8;
data.addAll(new Vector3f((x+1)*tileSize, 0, y*tileSize).list());
data.addAll(Vector3f.xUnit.negative().list());
data.add((float) 0);
data.add((float) 1);
data.addAll(new Vector3f((x+1)*tileSize, 0, (y+1)*tileSize).list());
data.addAll(Vector3f.xUnit.negative().list());
data.add((float) 1);
data.add((float) 1);
data.addAll(new Vector3f((x+1)*tileSize, ceilingHeight, (y+1)*tileSize).list());
data.addAll(Vector3f.xUnit.negative().list());
data.add((float) 1);
data.add((float) 0);
data.addAll(new Vector3f((x+1)*tileSize, ceilingHeight, y*tileSize).list());
data.addAll(Vector3f.xUnit.negative().list());
data.add((float) 0);
data.add((float) 0);
indices.add(index);
indices.add(index+1);
indices.add(index+2);
indices.add(index+2);
indices.add(index+3);
indices.add(index);
}
public int tile(int x, int y){
if(x < 0 || y < 0 || x >= width || y >= height) return 0;
return getRed(data[coordinatePosition(x, y)]);
}
private int coordinatePosition(int x, int y){
return x + y*width;
}
public static int getAlpha(int ARGB){
return (ARGB >> 24) & 0xFF;
}
public static int getRed(int ARGB){
return (ARGB >> 16) & 0xFF;
}
public static int getGreen(int ARGB){
return (ARGB >> 8) & 0xFF;
}
public static int getBlue(int ARGB){
return (ARGB) & 0xFF;
}
}