Added tiles. Not yet optimized.
This commit is contained in:
parent
21a30e8b97
commit
60fbfa9578
@ -30,6 +30,7 @@ import ru.windcorp.progressia.client.graphics.texture.Atlases;
|
||||
import ru.windcorp.progressia.client.graphics.world.LayerWorld;
|
||||
import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
|
||||
import ru.windcorp.progressia.client.world.renders.BlockRenders;
|
||||
import ru.windcorp.progressia.client.world.renders.TileRenders;
|
||||
import ru.windcorp.progressia.common.resource.ResourceManager;
|
||||
|
||||
public class ClientProxy implements Proxy {
|
||||
@ -47,6 +48,7 @@ public class ClientProxy implements Proxy {
|
||||
}
|
||||
|
||||
BlockRenders.registerTest();
|
||||
TileRenders.registerTest();
|
||||
Atlases.loadAllAtlases();
|
||||
|
||||
GUI.addBottomLayer(new LayerWorld());
|
||||
|
@ -11,13 +11,13 @@ class BlockFaceVectors {
|
||||
|
||||
private static BlockFaceVectors createInner(BlockFaceVectors outer) {
|
||||
ImmutableMap.Builder<BlockFace, Vec3> originBuilder =
|
||||
ImmutableMap.builderWithExpectedSize(count());
|
||||
ImmutableMap.builder();
|
||||
|
||||
ImmutableMap.Builder<BlockFace, Vec3> widthBuilder =
|
||||
ImmutableMap.builderWithExpectedSize(count());
|
||||
ImmutableMap.builder();
|
||||
|
||||
ImmutableMap.Builder<BlockFace, Vec3> heightBuilder =
|
||||
ImmutableMap.builderWithExpectedSize(count());
|
||||
ImmutableMap.builder();
|
||||
|
||||
for (BlockFace face : getFaces()) {
|
||||
Vec3 width = outer.getWidth(face);
|
||||
@ -43,7 +43,7 @@ class BlockFaceVectors {
|
||||
|
||||
static {
|
||||
OUTER = new BlockFaceVectors(
|
||||
ImmutableMap.<BlockFace, Vec3>builderWithExpectedSize(count())
|
||||
ImmutableMap.<BlockFace, Vec3>builder()
|
||||
|
||||
.put(TOP, new Vec3(-0.5f, +0.5f, +0.5f))
|
||||
.put(BOTTOM, new Vec3(-0.5f, -0.5f, -0.5f))
|
||||
@ -54,7 +54,7 @@ class BlockFaceVectors {
|
||||
|
||||
.build(),
|
||||
|
||||
ImmutableMap.<BlockFace, Vec3>builderWithExpectedSize(count())
|
||||
ImmutableMap.<BlockFace, Vec3>builder()
|
||||
|
||||
.put(TOP, new Vec3( 0, -1, 0))
|
||||
.put(BOTTOM, new Vec3( 0, +1, 0))
|
||||
@ -65,7 +65,7 @@ class BlockFaceVectors {
|
||||
|
||||
.build(),
|
||||
|
||||
ImmutableMap.<BlockFace, Vec3>builderWithExpectedSize(count())
|
||||
ImmutableMap.<BlockFace, Vec3>builder()
|
||||
|
||||
.put(TOP, new Vec3(+1, 0, 0))
|
||||
.put(BOTTOM, new Vec3(+1, 0, 0))
|
||||
|
@ -18,9 +18,11 @@
|
||||
package ru.windcorp.progressia.client.world;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import glm.mat._4.Mat4;
|
||||
import glm.vec._3.Vec3;
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.client.graphics.model.Model;
|
||||
import ru.windcorp.progressia.client.graphics.model.Shape;
|
||||
@ -31,9 +33,14 @@ import ru.windcorp.progressia.client.graphics.model.StaticModel.Builder;
|
||||
import ru.windcorp.progressia.client.world.renders.BlockRender;
|
||||
import ru.windcorp.progressia.client.world.renders.BlockRenderNone;
|
||||
import ru.windcorp.progressia.client.world.renders.BlockRenders;
|
||||
import ru.windcorp.progressia.client.world.renders.TileRender;
|
||||
import ru.windcorp.progressia.client.world.renders.TileRenders;
|
||||
import ru.windcorp.progressia.client.world.renders.cro.ChunkRenderOptimizer;
|
||||
import ru.windcorp.progressia.client.world.renders.cro.ChunkRenderOptimizerSupplier;
|
||||
import ru.windcorp.progressia.client.world.renders.cro.ChunkRenderOptimizers;
|
||||
import ru.windcorp.progressia.common.block.BlockFace;
|
||||
import ru.windcorp.progressia.common.block.TileData;
|
||||
import ru.windcorp.progressia.common.util.Vectors;
|
||||
import ru.windcorp.progressia.common.world.ChunkData;
|
||||
|
||||
public class ChunkRender {
|
||||
@ -101,23 +108,8 @@ public class ChunkRender {
|
||||
for (int z = 0; z < ChunkData.BLOCKS_PER_CHUNK; ++z) {
|
||||
cursor.set(x, y, z);
|
||||
|
||||
BlockRender block = getBlock(cursor);
|
||||
|
||||
if (block instanceof BlockRenderNone) {
|
||||
continue;
|
||||
}
|
||||
|
||||
forwardToOptimizers(block, x, y, z, optimizers);
|
||||
|
||||
if (!block.needsOwnRenderable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tryToCreateRenderable(block, x, y, z, builder)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
addRenderAsRenderable(block, x, y, z, builder);
|
||||
buildBlock(cursor, optimizers, builder);
|
||||
buildBlockTiles(cursor, optimizers, builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -133,14 +125,41 @@ public class ChunkRender {
|
||||
needsUpdate = false;
|
||||
}
|
||||
|
||||
private void forwardToOptimizers(
|
||||
private void buildBlock(
|
||||
Vec3i cursor,
|
||||
Collection<ChunkRenderOptimizer> optimizers,
|
||||
Builder builder
|
||||
) {
|
||||
BlockRender block = getBlock(cursor);
|
||||
int x = cursor.x;
|
||||
int y = cursor.y;
|
||||
int z = cursor.z;
|
||||
|
||||
if (block instanceof BlockRenderNone) {
|
||||
return;
|
||||
}
|
||||
|
||||
forwardBlockToOptimizers(block, x, y, z, optimizers);
|
||||
|
||||
if (!block.needsOwnRenderable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tryToCreateBlockRenderable(block, x, y, z, builder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
addBlockRenderAsRenderable(block, x, y, z, builder);
|
||||
}
|
||||
|
||||
private void forwardBlockToOptimizers(
|
||||
BlockRender block, int x, int y, int z,
|
||||
Collection<ChunkRenderOptimizer> optimizers
|
||||
) {
|
||||
optimizers.forEach(bro -> bro.processBlock(block, x, y, z));
|
||||
}
|
||||
|
||||
private boolean tryToCreateRenderable(
|
||||
private boolean tryToCreateBlockRenderable(
|
||||
BlockRender block, int x, int y, int z,
|
||||
Builder builder
|
||||
) {
|
||||
@ -154,7 +173,7 @@ public class ChunkRender {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void addRenderAsRenderable(
|
||||
private void addBlockRenderAsRenderable(
|
||||
BlockRender block, int x, int y, int z,
|
||||
Builder builder
|
||||
) {
|
||||
@ -164,4 +183,66 @@ public class ChunkRender {
|
||||
);
|
||||
}
|
||||
|
||||
private void buildBlockTiles(
|
||||
Vec3i cursor,
|
||||
Collection<ChunkRenderOptimizer> optimizers,
|
||||
Builder builder
|
||||
) {
|
||||
for (BlockFace face : BlockFace.getFaces()) {
|
||||
buildFaceTiles(cursor, face, optimizers, builder);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildFaceTiles(
|
||||
Vec3i cursor, BlockFace face,
|
||||
Collection<ChunkRenderOptimizer> optimizers,
|
||||
Builder builder
|
||||
) {
|
||||
List<TileData> tiles = getData().getTilesOrNull(cursor, face);
|
||||
|
||||
if (tiles == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int layer = 0; layer < tiles.size(); ++layer) {
|
||||
|
||||
if (tiles.get(layer) == null) {
|
||||
System.out.println(tiles.get(layer).getId());
|
||||
}
|
||||
|
||||
buildTile(
|
||||
cursor, face,
|
||||
TileRenders.get(tiles.get(layer).getId()),
|
||||
layer,
|
||||
optimizers, builder
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildTile(
|
||||
Vec3i cursor, BlockFace face,
|
||||
TileRender tile,
|
||||
int layer,
|
||||
Collection<ChunkRenderOptimizer> optimizers,
|
||||
Builder builder
|
||||
) {
|
||||
// TODO implement
|
||||
|
||||
Vec3 pos = Vectors.grab3().set(cursor.x, cursor.y, cursor.z);
|
||||
|
||||
Vec3 offset = Vectors.grab3().set(
|
||||
face.getVector().x, face.getVector().y, face.getVector().z
|
||||
);
|
||||
|
||||
pos.add(offset.mul(1f / 64));
|
||||
|
||||
builder.addPart(
|
||||
tile.createRenderable(face),
|
||||
new Mat4().identity().translate(pos)
|
||||
);
|
||||
|
||||
Vectors.release(pos);
|
||||
Vectors.release(offset);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
package ru.windcorp.progressia.client.world.renders;
|
||||
|
||||
import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
|
||||
import ru.windcorp.progressia.client.graphics.model.WorldRenderable;
|
||||
import ru.windcorp.progressia.client.world.renders.cro.ChunkRenderOptimizer;
|
||||
import ru.windcorp.progressia.common.block.BlockFace;
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
|
||||
public class TileRender extends Namespaced {
|
||||
|
||||
public TileRender(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
}
|
||||
|
||||
public void render(ShapeRenderHelper renderer, BlockFace face) {
|
||||
throw new UnsupportedOperationException(
|
||||
"TileRender.render() not implemented in " + this
|
||||
);
|
||||
}
|
||||
|
||||
public WorldRenderable createRenderable(BlockFace face) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean canBeOptimized(ChunkRenderOptimizer optimizer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean needsOwnRenderable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package ru.windcorp.progressia.client.world.renders;
|
||||
|
||||
import glm.vec._3.Vec3;
|
||||
import ru.windcorp.progressia.client.graphics.backend.Usage;
|
||||
import ru.windcorp.progressia.client.graphics.model.Faces;
|
||||
import ru.windcorp.progressia.client.graphics.model.Shape;
|
||||
import ru.windcorp.progressia.client.graphics.model.ShapeRenderProgram;
|
||||
import ru.windcorp.progressia.client.graphics.model.WorldRenderable;
|
||||
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
||||
import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
|
||||
import ru.windcorp.progressia.common.block.BlockFace;
|
||||
import ru.windcorp.progressia.common.util.Vectors;
|
||||
|
||||
public class TileRenderSimple extends TileRender {
|
||||
|
||||
private final Texture texture;
|
||||
|
||||
public TileRenderSimple(String namespace, String name, Texture texture) {
|
||||
super(namespace, name);
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
public Texture getTexture() {
|
||||
return texture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldRenderable createRenderable(BlockFace face) {
|
||||
ShapeRenderProgram program = WorldRenderProgram.getDefault();
|
||||
|
||||
Vec3 color = Vectors.grab3().set(1, 1, 1);
|
||||
Vec3 center = Vectors.grab3().set(0, 0, 0);
|
||||
|
||||
try {
|
||||
return new Shape(
|
||||
Usage.STATIC, WorldRenderProgram.getDefault(),
|
||||
Faces.createBlockFace(
|
||||
program, texture, color, center, face, false
|
||||
)
|
||||
);
|
||||
} finally {
|
||||
Vectors.release(color);
|
||||
Vectors.release(center);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*******************************************************************************
|
||||
* Progressia
|
||||
* Copyright (C) 2020 Wind Corporation
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
package ru.windcorp.progressia.client.world.renders;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import ru.windcorp.progressia.client.graphics.texture.Atlases;
|
||||
import ru.windcorp.progressia.client.graphics.texture.Atlases.AtlasGroup;
|
||||
import ru.windcorp.progressia.client.graphics.texture.SimpleTexture;
|
||||
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
||||
import ru.windcorp.progressia.common.resource.ResourceManager;
|
||||
|
||||
public class TileRenders {
|
||||
|
||||
private static final Map<String, TileRender> TILE_RENDERS =
|
||||
new HashMap<>();
|
||||
|
||||
private static final AtlasGroup TILES_ATLAS_GROUP =
|
||||
new AtlasGroup("Tiles", 1 << 12);
|
||||
|
||||
private TileRenders() {}
|
||||
|
||||
public static void registerTest() {
|
||||
register(new TileRenderSimple("Test", "Stones", getTexture("stones")));
|
||||
}
|
||||
|
||||
public static TileRender get(String name) {
|
||||
return TILE_RENDERS.get(name);
|
||||
}
|
||||
|
||||
public static void register(TileRender tileRender) {
|
||||
TILE_RENDERS.put(tileRender.getId(), tileRender);
|
||||
}
|
||||
|
||||
public static Texture getTexture(String name) {
|
||||
return new SimpleTexture(
|
||||
Atlases.getSprite(
|
||||
ResourceManager.getTextureResource("tiles/" + name),
|
||||
TILES_ATLAS_GROUP
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,8 @@ package ru.windcorp.progressia.common.block;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
|
||||
public final class BlockFace extends BlockRelation {
|
||||
|
||||
public static final BlockFace
|
||||
@ -35,6 +37,8 @@ public final class BlockFace extends BlockRelation {
|
||||
private static final ImmutableList<BlockFace> PRIMARY_FACES =
|
||||
ImmutableList.of(TOP, NORTH, WEST);
|
||||
|
||||
public static final int BLOCK_FACE_COUNT = ALL_FACES.size();
|
||||
|
||||
public static ImmutableList<BlockFace> getFaces() {
|
||||
return ALL_FACES;
|
||||
}
|
||||
@ -43,10 +47,6 @@ public final class BlockFace extends BlockRelation {
|
||||
return PRIMARY_FACES;
|
||||
}
|
||||
|
||||
public static int count() {
|
||||
return ALL_FACES.size();
|
||||
}
|
||||
|
||||
static {
|
||||
link(TOP, BOTTOM);
|
||||
link(NORTH, SOUTH);
|
||||
@ -58,11 +58,15 @@ public final class BlockFace extends BlockRelation {
|
||||
b.counterFace = a;
|
||||
}
|
||||
|
||||
private static int nextId = 0;
|
||||
|
||||
private final int id;
|
||||
private BlockFace counterFace;
|
||||
private final boolean isPrimary;
|
||||
|
||||
private BlockFace(int x, int y, int z, boolean isPrimary) {
|
||||
super(x, y, z);
|
||||
this.id = nextId++;
|
||||
this.isPrimary = isPrimary;
|
||||
}
|
||||
|
||||
@ -75,9 +79,42 @@ public final class BlockFace extends BlockRelation {
|
||||
else return counterFace;
|
||||
}
|
||||
|
||||
public BlockFace getPrimaryAndMoveCursor(Vec3i cursor) {
|
||||
if (isPrimary) return this;
|
||||
|
||||
cursor.add(getVector());
|
||||
return counterFace;
|
||||
}
|
||||
|
||||
public BlockFace getSecondary() {
|
||||
if (isPrimary) return counterFace;
|
||||
else return this;
|
||||
}
|
||||
|
||||
public BlockFace getSecondaryAndMoveCursor(Vec3i cursor) {
|
||||
if (!isPrimary) return this;
|
||||
|
||||
cursor.add(getVector());
|
||||
return counterFace;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getEuclideanDistance() {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChebyshevDistance() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getManhattanDistance() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
/*******************************************************************************
|
||||
* Progressia
|
||||
* Copyright (C) 2020 Wind Corporation
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
package ru.windcorp.progressia.common.block;
|
||||
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
|
||||
public class TileData extends Namespaced {
|
||||
|
||||
public TileData(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*******************************************************************************
|
||||
* Progressia
|
||||
* Copyright (C) 2020 Wind Corporation
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
package ru.windcorp.progressia.common.block;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class TileDataRegistry {
|
||||
|
||||
private static final Map<String, TileData> REGISTRY = new HashMap<>();
|
||||
|
||||
static {
|
||||
register(new TileData("Test", "Stones"));
|
||||
}
|
||||
|
||||
public static TileData get(String name) {
|
||||
return REGISTRY.get(name);
|
||||
}
|
||||
|
||||
public static void register(TileData tileData) {
|
||||
REGISTRY.put(tileData.getId(), tileData);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package ru.windcorp.progressia.common.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
import com.google.common.collect.ForwardingList;
|
||||
|
||||
public class SizeLimitedList<E> extends ForwardingList<E> {
|
||||
|
||||
private static final class RandomAccessSizeLimitedList<E>
|
||||
extends SizeLimitedList<E>
|
||||
implements RandomAccess {
|
||||
protected RandomAccessSizeLimitedList(List<E> parent, int maxSize) {
|
||||
super(parent, maxSize);
|
||||
}
|
||||
}
|
||||
|
||||
public static <E> List<E> wrap(List<E> list, int maxSize) {
|
||||
if (list instanceof RandomAccess) {
|
||||
return new RandomAccessSizeLimitedList<>(list, maxSize);
|
||||
} else {
|
||||
return new SizeLimitedList<>(list, maxSize);
|
||||
}
|
||||
}
|
||||
|
||||
private final List<E> delegate;
|
||||
|
||||
private final int maxSize;
|
||||
|
||||
protected SizeLimitedList(List<E> parent, int maxSize) {
|
||||
this.delegate = Objects.requireNonNull(parent, "parent");
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends E> collection) {
|
||||
return standardAddAll(collection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(int index, Collection<? extends E> elements) {
|
||||
return standardAddAll(index, elements);
|
||||
}
|
||||
|
||||
public boolean add(E e) {
|
||||
checkMaxSize();
|
||||
return delegate().add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, final E e) {
|
||||
checkMaxSize();
|
||||
delegate().add(index, e);
|
||||
}
|
||||
|
||||
private void checkMaxSize() {
|
||||
if (size() >= maxSize) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Maximum size " + maxSize + " reached"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<E> delegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
}
|
@ -17,9 +17,21 @@
|
||||
*******************************************************************************/
|
||||
package ru.windcorp.progressia.common.world;
|
||||
|
||||
import static ru.windcorp.progressia.common.block.BlockFace.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.block.BlockData;
|
||||
import ru.windcorp.progressia.common.block.BlockDataRegistry;
|
||||
import ru.windcorp.progressia.common.block.BlockFace;
|
||||
import ru.windcorp.progressia.common.block.TileData;
|
||||
import ru.windcorp.progressia.common.block.TileDataRegistry;
|
||||
import ru.windcorp.progressia.common.util.SizeLimitedList;
|
||||
import ru.windcorp.progressia.common.util.Vectors;
|
||||
|
||||
public class ChunkData {
|
||||
|
||||
@ -27,23 +39,33 @@ public class ChunkData {
|
||||
public static final int TILES_PER_FACE = 8;
|
||||
|
||||
private final Vec3i position = new Vec3i();
|
||||
private final WorldData world;
|
||||
|
||||
private final BlockData[] blocks = new BlockData[
|
||||
BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK
|
||||
];
|
||||
|
||||
private final BlockData grass = BlockDataRegistry.get("Test:Grass");
|
||||
private final BlockData dirt = BlockDataRegistry.get("Test:Dirt");
|
||||
private final BlockData stone = BlockDataRegistry.get("Test:Stone");
|
||||
private final BlockData air = BlockDataRegistry.get("Test:Air");
|
||||
@SuppressWarnings("unchecked")
|
||||
private final List<TileData>[] tiles = (List<TileData>[]) new List<?>[
|
||||
BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK *
|
||||
BLOCK_FACE_COUNT
|
||||
];
|
||||
|
||||
public ChunkData(int x, int y, int z) {
|
||||
public ChunkData(int x, int y, int z, WorldData world) {
|
||||
this.position.set(x, y, z);
|
||||
this.world = world;
|
||||
|
||||
tmp_generate();
|
||||
}
|
||||
|
||||
private void tmp_generate() {
|
||||
BlockData grass = BlockDataRegistry.get("Test:Grass");
|
||||
BlockData dirt = BlockDataRegistry.get("Test:Dirt");
|
||||
BlockData stone = BlockDataRegistry.get("Test:Stone");
|
||||
BlockData air = BlockDataRegistry.get("Test:Air");
|
||||
|
||||
TileData stones = TileDataRegistry.get("Test:Stones");
|
||||
|
||||
Vec3i aPoint = new Vec3i(5, 0, BLOCKS_PER_CHUNK + BLOCKS_PER_CHUNK/2);
|
||||
Vec3i pos = new Vec3i();
|
||||
|
||||
@ -74,44 +96,132 @@ public class ChunkData {
|
||||
for (pos.z = BLOCKS_PER_CHUNK - 1; pos.z >= 0 && getBlock(pos) == air; --pos.z);
|
||||
|
||||
setBlock(pos, grass);
|
||||
|
||||
int hash = x*x * 13 ^ y*y * 37 ^ pos.z*pos.z * 129;
|
||||
if (hash % 5 == 0) {
|
||||
getTiles(pos, BlockFace.TOP).add(stones);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BlockData getBlock(Vec3i posInChunk) {
|
||||
if (!isInBounds(posInChunk)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Coordinates " + str(posInChunk) + " "
|
||||
+ "are not legal chunk coordinates"
|
||||
);
|
||||
}
|
||||
|
||||
return blocks[getBlockIndex(posInChunk)];
|
||||
}
|
||||
|
||||
public void setBlock(Vec3i posInChunk, BlockData block) {
|
||||
blocks[getBlockIndex(posInChunk)] = block;
|
||||
}
|
||||
|
||||
public List<TileData> getTilesOrNull(Vec3i blockInChunk, BlockFace face) {
|
||||
return tiles[getTileIndex(blockInChunk, face)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only. Modify a list returned by
|
||||
* {@link #getTiles(Vec3i, BlockFace)} or
|
||||
* {@link #getTilesOrNull(Vec3i, BlockFace)}
|
||||
* to change tiles.
|
||||
*/
|
||||
protected void setTiles(
|
||||
Vec3i blockInChunk, BlockFace face,
|
||||
List<TileData> tiles
|
||||
) {
|
||||
this.tiles[getTileIndex(blockInChunk, face)] = tiles;
|
||||
}
|
||||
|
||||
public boolean hasTiles(Vec3i blockInChunk, BlockFace face) {
|
||||
return getTilesOrNull(blockInChunk, face) != null;
|
||||
}
|
||||
|
||||
public List<TileData> getTiles(Vec3i blockInChunk, BlockFace face) {
|
||||
int index = getTileIndex(blockInChunk, face);
|
||||
|
||||
if (tiles[index] == null) {
|
||||
createTileContainer(blockInChunk, face);
|
||||
}
|
||||
|
||||
return tiles[index];
|
||||
}
|
||||
|
||||
private void createTileContainer(Vec3i blockInChunk, BlockFace face) {
|
||||
if (isBorder(blockInChunk, face)) {
|
||||
createBorderTileContainer(blockInChunk, face);
|
||||
} else {
|
||||
createNormalTileContainer(blockInChunk, face);
|
||||
}
|
||||
}
|
||||
|
||||
private void createNormalTileContainer(Vec3i blockInChunk, BlockFace face) {
|
||||
List<TileData> primaryList =
|
||||
SizeLimitedList.wrap(
|
||||
new ArrayList<>(TILES_PER_FACE), TILES_PER_FACE
|
||||
);
|
||||
|
||||
List<TileData> secondaryList = Lists.reverse(primaryList);
|
||||
|
||||
|
||||
Vec3i cursor = Vectors.grab3i()
|
||||
.set(blockInChunk.x, blockInChunk.y, blockInChunk.z);
|
||||
|
||||
face = face.getPrimaryAndMoveCursor(cursor);
|
||||
setTiles(cursor, face, primaryList);
|
||||
|
||||
face = face.getSecondaryAndMoveCursor(cursor);
|
||||
setTiles(cursor, face, secondaryList);
|
||||
}
|
||||
|
||||
private void createBorderTileContainer(Vec3i blockInChunk, BlockFace face) {
|
||||
// TODO cooperate with neighbours
|
||||
setTiles(
|
||||
blockInChunk, face,
|
||||
SizeLimitedList.wrap(
|
||||
new ArrayList<>(TILES_PER_FACE), TILES_PER_FACE
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private static int getBlockIndex(Vec3i posInChunk) {
|
||||
checkLocalCoordinates(posInChunk);
|
||||
|
||||
return
|
||||
posInChunk.z * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK +
|
||||
posInChunk.y * BLOCKS_PER_CHUNK +
|
||||
posInChunk.x;
|
||||
}
|
||||
|
||||
private static int getTileIndex(Vec3i posInChunk, BlockFace face) {
|
||||
return
|
||||
getBlockIndex(posInChunk) * BLOCK_FACE_COUNT +
|
||||
face.getId();
|
||||
}
|
||||
|
||||
private static void checkLocalCoordinates(Vec3i posInChunk) {
|
||||
if (!isInBounds(posInChunk)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Coordinates " + str(posInChunk) + " "
|
||||
+ "are not legal chunk coordinates"
|
||||
);
|
||||
}
|
||||
|
||||
blocks[getBlockIndex(posInChunk)] = block;
|
||||
}
|
||||
|
||||
private boolean isInBounds(Vec3i posInChunk) {
|
||||
private static boolean isInBounds(Vec3i posInChunk) {
|
||||
return
|
||||
posInChunk.x >= 0 && posInChunk.x < BLOCKS_PER_CHUNK &&
|
||||
posInChunk.y >= 0 && posInChunk.y < BLOCKS_PER_CHUNK &&
|
||||
posInChunk.z >= 0 && posInChunk.z < BLOCKS_PER_CHUNK;
|
||||
}
|
||||
|
||||
private int getBlockIndex(Vec3i posInChunk) {
|
||||
private boolean isBorder(Vec3i blockInChunk, BlockFace face) {
|
||||
final int min = 0, max = BLOCKS_PER_CHUNK - 1;
|
||||
|
||||
return
|
||||
posInChunk.z * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK +
|
||||
posInChunk.y * BLOCKS_PER_CHUNK +
|
||||
posInChunk.x;
|
||||
(blockInChunk.x == min && face == SOUTH ) ||
|
||||
(blockInChunk.x == max && face == NORTH ) ||
|
||||
(blockInChunk.y == min && face == WEST ) ||
|
||||
(blockInChunk.y == max && face == EAST ) ||
|
||||
(blockInChunk.z == min && face == BOTTOM) ||
|
||||
(blockInChunk.z == max && face == TOP );
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
@ -130,6 +240,10 @@ public class ChunkData {
|
||||
return position;
|
||||
}
|
||||
|
||||
public WorldData getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
private static String str(Vec3i v) {
|
||||
return "(" + v.x + "; " + v.y + "; " + v.z + ")";
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public class WorldData {
|
||||
|
||||
for (int x = -(size / 2); x <= (size / 2); ++x) {
|
||||
for (int y = -(size / 2); y <= (size / 2); ++y) {
|
||||
chunks.put(CoordinatePacker.pack3IntsIntoLong(x, y, 0), new ChunkData(x, y, 0));
|
||||
chunks.put(CoordinatePacker.pack3IntsIntoLong(x, y, 0), new ChunkData(x, y, 0, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
BIN
src/main/resources/assets/textures/tiles/stones.png
Normal file
BIN
src/main/resources/assets/textures/tiles/stones.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 464 B |
Reference in New Issue
Block a user