2013-07-15 19:13:30 -04:00
|
|
|
package com.blarg.gdx.tilemap3d;
|
|
|
|
|
2013-10-20 11:41:47 -04:00
|
|
|
import com.badlogic.gdx.graphics.GL20;
|
|
|
|
import com.badlogic.gdx.graphics.Mesh;
|
|
|
|
import com.badlogic.gdx.graphics.g3d.Renderable;
|
|
|
|
import com.badlogic.gdx.graphics.g3d.RenderableProvider;
|
|
|
|
import com.badlogic.gdx.graphics.g3d.materials.BlendingAttribute;
|
|
|
|
import com.badlogic.gdx.graphics.g3d.materials.Material;
|
|
|
|
import com.badlogic.gdx.graphics.g3d.materials.TextureAttribute;
|
2013-07-15 19:13:30 -04:00
|
|
|
import com.badlogic.gdx.math.Vector3;
|
|
|
|
import com.badlogic.gdx.math.collision.BoundingBox;
|
2013-10-20 11:41:47 -04:00
|
|
|
import com.badlogic.gdx.utils.Array;
|
2013-07-15 19:13:30 -04:00
|
|
|
import com.badlogic.gdx.utils.Disposable;
|
2013-10-20 11:41:47 -04:00
|
|
|
import com.badlogic.gdx.utils.Pool;
|
2013-07-15 19:13:30 -04:00
|
|
|
|
2013-10-20 11:41:47 -04:00
|
|
|
public class TileChunk extends TileContainer implements TileRawDataContainer, RenderableProvider, Disposable {
|
2013-07-15 19:13:30 -04:00
|
|
|
final int x;
|
|
|
|
final int y;
|
|
|
|
final int z;
|
|
|
|
final int width;
|
|
|
|
final int height;
|
|
|
|
final int depth;
|
|
|
|
|
|
|
|
final Tile[] data;
|
|
|
|
final BoundingBox bounds;
|
|
|
|
final BoundingBox tmpBounds = new BoundingBox();
|
|
|
|
final Vector3 position;
|
|
|
|
final Vector3 tmpPosition = new Vector3();
|
|
|
|
|
2013-10-20 11:41:47 -04:00
|
|
|
Mesh opaqueMesh;
|
|
|
|
Mesh alphaMesh;
|
|
|
|
final Material opaqueMaterial = new Material();
|
|
|
|
final Material alphaMaterial = new Material();
|
2013-10-20 12:02:19 -04:00
|
|
|
final BoundingBox meshBounds = new BoundingBox();
|
2013-10-20 11:41:47 -04:00
|
|
|
|
2013-07-15 19:13:30 -04:00
|
|
|
public final TileMap tileMap;
|
|
|
|
|
2013-08-04 10:45:59 -04:00
|
|
|
@Override
|
2013-07-18 19:18:35 -04:00
|
|
|
public Tile[] getData() {
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2013-07-15 19:13:30 -04:00
|
|
|
@Override
|
|
|
|
public int getWidth() {
|
|
|
|
return width;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getHeight() {
|
|
|
|
return height;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getDepth() {
|
|
|
|
return depth;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getMinX() {
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getMinY() {
|
|
|
|
return y;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getMinZ() {
|
|
|
|
return z;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getMaxX() {
|
|
|
|
return x + width - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getMaxY() {
|
|
|
|
return y + height - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getMaxZ() {
|
|
|
|
return z + depth - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Vector3 getPosition() {
|
|
|
|
tmpPosition.set(position);
|
|
|
|
return tmpPosition;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public BoundingBox getBounds() {
|
|
|
|
tmpBounds.set(bounds);
|
|
|
|
return tmpBounds;
|
|
|
|
}
|
|
|
|
|
2013-10-20 12:02:19 -04:00
|
|
|
public BoundingBox getMeshBounds() {
|
|
|
|
tmpBounds.set(meshBounds);
|
|
|
|
return tmpBounds;
|
|
|
|
}
|
|
|
|
|
2013-07-15 19:13:30 -04:00
|
|
|
public int getNumVertices() {
|
2013-10-20 11:41:47 -04:00
|
|
|
return opaqueMesh != null ? opaqueMesh.getNumVertices() : 0;
|
2013-07-15 19:13:30 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
public int getNumAlphaVertices() {
|
2013-10-20 11:41:47 -04:00
|
|
|
return alphaMesh != null ? alphaMesh.getNumVertices() : 0;
|
2013-07-15 19:13:30 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
public TileChunk(int x, int y, int z, int width, int height, int depth, TileMap tileMap) {
|
|
|
|
if (tileMap == null)
|
|
|
|
throw new IllegalArgumentException();
|
|
|
|
|
|
|
|
this.tileMap = tileMap;
|
|
|
|
this.x = x;
|
|
|
|
this.y = y;
|
|
|
|
this.z = z;
|
|
|
|
this.width = width;
|
|
|
|
this.height = height;
|
|
|
|
this.depth = depth;
|
|
|
|
this.position = new Vector3(x, y, z);
|
|
|
|
bounds = new BoundingBox();
|
|
|
|
bounds.min.set(x, y, z);
|
|
|
|
bounds.max.set(x + width, y + height, z + depth);
|
|
|
|
|
|
|
|
int numTiles = width * height * depth;
|
|
|
|
data = new Tile[numTiles];
|
|
|
|
for (int i = 0; i < numTiles; ++i)
|
|
|
|
data[i] = new Tile();
|
|
|
|
|
2013-10-20 11:41:47 -04:00
|
|
|
opaqueMesh = null;
|
|
|
|
alphaMesh = null;
|
|
|
|
opaqueMaterial.set(TextureAttribute.createDiffuse(tileMap.tileMeshes.atlas.texture));
|
|
|
|
alphaMaterial.set(TextureAttribute.createDiffuse(tileMap.tileMeshes.atlas.texture));
|
|
|
|
alphaMaterial.set(new BlendingAttribute());
|
2013-07-15 19:13:30 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
public void updateVertices(ChunkVertexGenerator generator) {
|
2013-10-20 11:41:47 -04:00
|
|
|
ChunkVertexGenerator.GeneratedChunkMeshes generatedMeshes = generator.generate(this);
|
|
|
|
|
2013-10-20 12:02:19 -04:00
|
|
|
meshBounds.clr();
|
|
|
|
|
2013-10-20 11:41:47 -04:00
|
|
|
if (generatedMeshes.opaqueMesh.getNumVertices() > 0) {
|
|
|
|
opaqueMesh = generatedMeshes.opaqueMesh;
|
2013-10-20 12:02:19 -04:00
|
|
|
opaqueMesh.calculateBoundingBox(tmpBounds);
|
|
|
|
meshBounds.ext(tmpBounds);
|
|
|
|
} else
|
2013-10-20 11:41:47 -04:00
|
|
|
opaqueMesh = null;
|
|
|
|
|
|
|
|
if (generatedMeshes.alphaMesh.getNumVertices() > 0) {
|
|
|
|
alphaMesh = generatedMeshes.alphaMesh;
|
2013-10-20 12:02:19 -04:00
|
|
|
alphaMesh.calculateBoundingBox(tmpBounds);
|
|
|
|
meshBounds.ext(tmpBounds);
|
|
|
|
} else
|
2013-10-20 11:41:47 -04:00
|
|
|
alphaMesh = null;
|
2013-07-15 19:13:30 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
public Tile getWithinSelfOrNeighbour(int x, int y, int z) {
|
|
|
|
int checkX = x + this.x;
|
|
|
|
int checkY = y + this.y;
|
|
|
|
int checkZ = z + this.z;
|
|
|
|
return tileMap.get(checkX, checkY, checkZ);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Tile getWithinSelfOrNeighbourSafe(int x, int y, int z) {
|
|
|
|
int checkX = x + this.x;
|
|
|
|
int checkY = y + this.y;
|
|
|
|
int checkZ = z + this.z;
|
|
|
|
if (!tileMap.isWithinBounds(checkX, checkY, checkZ))
|
|
|
|
return null;
|
|
|
|
else
|
|
|
|
return tileMap.get(checkX, checkY, checkZ);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Tile get(int x, int y, int z) {
|
|
|
|
int index = getIndexOf(x, y, z);
|
|
|
|
return data[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Tile getSafe(int x, int y, int z) {
|
|
|
|
if (!isWithinLocalBounds(x, y, z))
|
|
|
|
return null;
|
|
|
|
else
|
|
|
|
return get(x, y, z);
|
|
|
|
}
|
|
|
|
|
|
|
|
private int getIndexOf(int x, int y, int z) {
|
|
|
|
return (y * width * depth) + (z * width) + x;
|
|
|
|
}
|
|
|
|
|
2013-10-20 11:41:47 -04:00
|
|
|
@Override
|
|
|
|
public void getRenderables(Array<Renderable> renderables, Pool<Renderable> pool) {
|
|
|
|
if (opaqueMesh != null)
|
2013-10-20 12:02:19 -04:00
|
|
|
renderables.add(getRenderableFor(pool, opaqueMesh, opaqueMaterial, null));
|
2013-10-20 11:41:47 -04:00
|
|
|
if (alphaMesh != null)
|
2013-10-20 12:02:19 -04:00
|
|
|
renderables.add(getRenderableFor(pool, alphaMesh, alphaMaterial, null));
|
2013-10-20 11:41:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
private Renderable getRenderableFor(Pool<Renderable> pool, Mesh mesh, Material material, Object userData) {
|
|
|
|
Renderable renderable = pool.obtain();
|
|
|
|
renderable.mesh = mesh;
|
|
|
|
renderable.meshPartOffset = 0;
|
|
|
|
renderable.meshPartSize = mesh.getNumVertices();
|
|
|
|
renderable.primitiveType = GL20.GL_TRIANGLES;
|
|
|
|
renderable.bones = null;
|
|
|
|
renderable.lights = null;
|
|
|
|
renderable.shader = null;
|
|
|
|
renderable.userData = userData;
|
|
|
|
renderable.material = material;
|
|
|
|
return renderable;
|
|
|
|
}
|
|
|
|
|
2013-07-15 19:13:30 -04:00
|
|
|
@Override
|
|
|
|
public void dispose() {
|
2013-10-20 11:41:47 -04:00
|
|
|
opaqueMesh.dispose();
|
2013-07-15 19:13:30 -04:00
|
|
|
alphaMesh.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean equals(Object o) {
|
|
|
|
if (this == o)
|
|
|
|
return true;
|
|
|
|
if (o == null || getClass() != o.getClass())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TileChunk tileChunk = (TileChunk)o;
|
|
|
|
|
|
|
|
if (x != tileChunk.x)
|
|
|
|
return false;
|
|
|
|
if (y != tileChunk.y)
|
|
|
|
return false;
|
|
|
|
if (z != tileChunk.z)
|
|
|
|
return false;
|
|
|
|
if (tileMap != null ? !tileMap.equals(tileChunk.tileMap) : tileChunk.tileMap != null)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
int result = x;
|
|
|
|
result = 31 * result + y;
|
|
|
|
result = 31 * result + z;
|
|
|
|
result = 31 * result + (tileMap != null ? tileMap.hashCode() : 0);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|