Moved some methods from ChunkData to GenericChunk
- Moved some method definitions from ChunkData to GenericChunk - Moved some method definitions from ChunkData to GenericWritableChunk - Refactored GenericChunk including changing some method signatures - Added some documentation for GenericChunk
This commit is contained in:
parent
3c3f3816df
commit
2532e80f6a
@ -36,6 +36,7 @@ import ru.windcorp.progressia.client.world.tile.TileRender;
|
|||||||
import ru.windcorp.progressia.client.world.tile.TileRenderNone;
|
import ru.windcorp.progressia.client.world.tile.TileRenderNone;
|
||||||
import ru.windcorp.progressia.client.world.tile.TileRenderStack;
|
import ru.windcorp.progressia.client.world.tile.TileRenderStack;
|
||||||
import ru.windcorp.progressia.common.world.ChunkData;
|
import ru.windcorp.progressia.common.world.ChunkData;
|
||||||
|
import ru.windcorp.progressia.common.world.generic.GenericChunk;
|
||||||
import ru.windcorp.progressia.common.world.rels.AxisRotations;
|
import ru.windcorp.progressia.common.world.rels.AxisRotations;
|
||||||
import ru.windcorp.progressia.common.world.rels.RelFace;
|
import ru.windcorp.progressia.common.world.rels.RelFace;
|
||||||
|
|
||||||
@ -76,7 +77,7 @@ public class ChunkRenderModel implements Renderable {
|
|||||||
|
|
||||||
optimizers.forEach(ChunkRenderOptimizer::startRender);
|
optimizers.forEach(ChunkRenderOptimizer::startRender);
|
||||||
|
|
||||||
chunk.forEachBiC(relBlockInChunk -> {
|
GenericChunk.forEachBiC(relBlockInChunk -> {
|
||||||
processBlockAndTiles(relBlockInChunk, sink);
|
processBlockAndTiles(relBlockInChunk, sink);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ import ru.windcorp.progressia.client.world.block.BlockRender;
|
|||||||
import ru.windcorp.progressia.client.world.tile.TileRender;
|
import ru.windcorp.progressia.client.world.tile.TileRender;
|
||||||
import ru.windcorp.progressia.common.util.Vectors;
|
import ru.windcorp.progressia.common.util.Vectors;
|
||||||
import ru.windcorp.progressia.common.world.ChunkData;
|
import ru.windcorp.progressia.common.world.ChunkData;
|
||||||
|
import ru.windcorp.progressia.common.world.generic.GenericChunk;
|
||||||
import ru.windcorp.progressia.common.world.rels.RelFace;
|
import ru.windcorp.progressia.common.world.rels.RelFace;
|
||||||
|
|
||||||
public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer {
|
public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer {
|
||||||
@ -216,7 +217,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer {
|
|||||||
|
|
||||||
Consumer<ShapePart> consumer = shapeParts::add;
|
Consumer<ShapePart> consumer = shapeParts::add;
|
||||||
|
|
||||||
chunk.forEachBiC(relBlockInChunk -> {
|
GenericChunk.forEachBiC(relBlockInChunk -> {
|
||||||
processInnerFaces(relBlockInChunk, consumer);
|
processInnerFaces(relBlockInChunk, consumer);
|
||||||
processOuterFaces(relBlockInChunk, consumer);
|
processOuterFaces(relBlockInChunk, consumer);
|
||||||
});
|
});
|
||||||
@ -315,7 +316,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldRenderWhenFacing(Vec3i relBlockInChunk, RelFace face) {
|
private boolean shouldRenderWhenFacing(Vec3i relBlockInChunk, RelFace face) {
|
||||||
if (chunk.containsBiC(relBlockInChunk)) {
|
if (GenericChunk.containsBiC(relBlockInChunk)) {
|
||||||
return shouldRenderWhenFacingLocal(relBlockInChunk, face);
|
return shouldRenderWhenFacingLocal(relBlockInChunk, face);
|
||||||
} else {
|
} else {
|
||||||
return shouldRenderWhenFacingNeighbor(relBlockInChunk, face);
|
return shouldRenderWhenFacingNeighbor(relBlockInChunk, face);
|
||||||
|
@ -25,14 +25,13 @@ import java.util.Arrays;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import glm.vec._3.i.Vec3i;
|
import glm.vec._3.i.Vec3i;
|
||||||
import ru.windcorp.progressia.common.util.VectorUtil;
|
|
||||||
import ru.windcorp.progressia.common.util.Vectors;
|
import ru.windcorp.progressia.common.util.Vectors;
|
||||||
import ru.windcorp.progressia.common.world.block.BlockData;
|
import ru.windcorp.progressia.common.world.block.BlockData;
|
||||||
import ru.windcorp.progressia.common.world.generic.GenericChunk;
|
import ru.windcorp.progressia.common.world.generic.GenericChunk;
|
||||||
|
import ru.windcorp.progressia.common.world.generic.GenericWritableChunk;
|
||||||
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
||||||
import ru.windcorp.progressia.common.world.rels.BlockFace;
|
import ru.windcorp.progressia.common.world.rels.BlockFace;
|
||||||
import ru.windcorp.progressia.common.world.rels.RelFace;
|
import ru.windcorp.progressia.common.world.rels.RelFace;
|
||||||
@ -42,7 +41,7 @@ import ru.windcorp.progressia.common.world.tile.TileReference;
|
|||||||
import ru.windcorp.progressia.common.world.tile.TileStackIsFullException;
|
import ru.windcorp.progressia.common.world.tile.TileStackIsFullException;
|
||||||
|
|
||||||
public class ChunkData
|
public class ChunkData
|
||||||
implements GenericChunk<ChunkData, BlockData, TileData, TileDataStack> {
|
implements GenericWritableChunk<ChunkData, BlockData, TileData, TileDataStack> {
|
||||||
|
|
||||||
public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE;
|
public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE;
|
||||||
public static final int CHUNK_RADIUS = BLOCKS_PER_CHUNK / 2;
|
public static final int CHUNK_RADIUS = BLOCKS_PER_CHUNK / 2;
|
||||||
@ -83,6 +82,7 @@ public class ChunkData
|
|||||||
return blocks[getBlockIndex(posInChunk)];
|
return blocks[getBlockIndex(posInChunk)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setBlock(Vec3i posInChunk, BlockData block, boolean notify) {
|
public void setBlock(Vec3i posInChunk, BlockData block, boolean notify) {
|
||||||
BlockData previous = blocks[getBlockIndex(posInChunk)];
|
BlockData previous = blocks[getBlockIndex(posInChunk)];
|
||||||
blocks[getBlockIndex(posInChunk)] = block;
|
blocks[getBlockIndex(posInChunk)] = block;
|
||||||
@ -95,6 +95,7 @@ public class ChunkData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setBlockRel(Vec3i relativeBlockInChunk, BlockData block, boolean notify) {
|
public void setBlockRel(Vec3i relativeBlockInChunk, BlockData block, boolean notify) {
|
||||||
Vec3i absoluteBlockInChunk = Vectors.grab3i();
|
Vec3i absoluteBlockInChunk = Vectors.grab3i();
|
||||||
resolve(relativeBlockInChunk, absoluteBlockInChunk);
|
resolve(relativeBlockInChunk, absoluteBlockInChunk);
|
||||||
@ -168,7 +169,7 @@ public class ChunkData
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void checkLocalCoordinates(Vec3i posInChunk) {
|
private static void checkLocalCoordinates(Vec3i posInChunk) {
|
||||||
if (!isInBounds(posInChunk)) {
|
if (!GenericChunk.containsBiC(posInChunk)) {
|
||||||
throw new IllegalCoordinatesException(
|
throw new IllegalCoordinatesException(
|
||||||
"Coordinates (" + posInChunk.x + "; " + posInChunk.y + "; " + posInChunk.z + ") "
|
"Coordinates (" + posInChunk.x + "; " + posInChunk.y + "; " + posInChunk.z + ") "
|
||||||
+ "are not legal chunk coordinates"
|
+ "are not legal chunk coordinates"
|
||||||
@ -176,56 +177,6 @@ public class ChunkData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isBorder(Vec3i blockInChunk, BlockFace face) {
|
|
||||||
final int min = 0, max = BLOCKS_PER_CHUNK - 1;
|
|
||||||
AbsFace absFace = face.resolve(getUp());
|
|
||||||
return (blockInChunk.x == min && absFace == AbsFace.NEG_X) ||
|
|
||||||
(blockInChunk.x == max && absFace == AbsFace.POS_X) ||
|
|
||||||
(blockInChunk.y == min && absFace == AbsFace.NEG_Y) ||
|
|
||||||
(blockInChunk.y == max && absFace == AbsFace.POS_Y) ||
|
|
||||||
(blockInChunk.z == min && absFace == AbsFace.NEG_Z) ||
|
|
||||||
(blockInChunk.z == max && absFace == AbsFace.POS_Z);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void forEachBlock(Consumer<Vec3i> action) {
|
|
||||||
VectorUtil.iterateCuboid(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
BLOCKS_PER_CHUNK,
|
|
||||||
BLOCKS_PER_CHUNK,
|
|
||||||
BLOCKS_PER_CHUNK,
|
|
||||||
action
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void forEachTileStack(Consumer<TileDataStack> action) {
|
|
||||||
forEachBlock(blockInChunk -> {
|
|
||||||
for (AbsFace face : AbsFace.getFaces()) {
|
|
||||||
TileDataStack stack = getTilesOrNull(blockInChunk, face);
|
|
||||||
if (stack == null)
|
|
||||||
continue;
|
|
||||||
action.accept(stack);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterates over all tiles in this chunk.
|
|
||||||
*
|
|
||||||
* @param action the action to perform. {@code TileLocation} refers to each
|
|
||||||
* tile using its primary block
|
|
||||||
*/
|
|
||||||
public void forEachTile(BiConsumer<TileDataStack, TileData> action) {
|
|
||||||
forEachTileStack(stack -> stack.forEach(tileData -> action.accept(stack, tileData)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public WorldData getWorld() {
|
public WorldData getWorld() {
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package ru.windcorp.progressia.common.world.generic;
|
package ru.windcorp.progressia.common.world.generic;
|
||||||
|
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import glm.Glm;
|
import glm.Glm;
|
||||||
@ -29,14 +30,67 @@ import ru.windcorp.progressia.common.world.rels.AbsFace;
|
|||||||
import ru.windcorp.progressia.common.world.rels.AxisRotations;
|
import ru.windcorp.progressia.common.world.rels.AxisRotations;
|
||||||
import ru.windcorp.progressia.common.world.rels.BlockFace;
|
import ru.windcorp.progressia.common.world.rels.BlockFace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An unmodifiable chunk representation. Per default, it is usually one of
|
||||||
|
* {@link ru.windcorp.progressia.common.world.ChunkData ChunkData},
|
||||||
|
* {@link ru.windcorp.progressia.client.world.ChunkRender ChunkRender} or
|
||||||
|
* {@link ru.windcorp.progressia.server.world.ChunkLogic ChunkLogic}, but this
|
||||||
|
* interface may be implemented differently for various reasons.
|
||||||
|
* <p>
|
||||||
|
* A generic chunk contains {@linkplain GenericBlock blocks} and
|
||||||
|
* {@linkplain GenericTileStack tile stacks} and is characterized by its
|
||||||
|
* location. It also bears a discrete up direction. Note that no
|
||||||
|
* {@linkplain GenericWorld world} object is directly accessible through this
|
||||||
|
* interface.
|
||||||
|
* <p>
|
||||||
|
* This interface defines the most common methods for examining a chunk and
|
||||||
|
* implements many of them as default methods. It also contains several static
|
||||||
|
* methods useful when dealing with chunks. {@code GenericChunk} does not
|
||||||
|
* provide a way to modify a chunk; use {@link GenericWritableChunk} methods
|
||||||
|
* when applicable.
|
||||||
|
*
|
||||||
|
* @param <Self> a reference to itself (required to properly reference a
|
||||||
|
* {@link GenericTileStack})
|
||||||
|
* @param <B> block type
|
||||||
|
* @param <T> tile type
|
||||||
|
* @param <TS> tile stack type
|
||||||
|
* @author javapony
|
||||||
|
*/
|
||||||
public interface GenericChunk<Self extends GenericChunk<Self, B, T, TS>, B extends GenericBlock, T extends GenericTile, TS extends GenericTileStack<TS, T, Self>> {
|
public interface GenericChunk<Self extends GenericChunk<Self, B, T, TS>, B extends GenericBlock, T extends GenericTile, TS extends GenericTileStack<TS, T, Self>> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The count of blocks in a side of a chunk. This is guaranteed to be a
|
||||||
|
* power of two. This is always equal to {@link Coordinates#CHUNK_SIZE}.
|
||||||
|
*/
|
||||||
public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE;
|
public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Abstract methods
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the position of this chunk in {@linkplain Coordinates#chunk
|
||||||
|
* coordinates of chunk}. The returned object must not be modified.
|
||||||
|
*
|
||||||
|
* @return this chunk's position
|
||||||
|
*/
|
||||||
Vec3i getPosition();
|
Vec3i getPosition();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the discrete up direction for this chunk.
|
||||||
|
*
|
||||||
|
* @return this chunk's discrete up direction
|
||||||
|
*/
|
||||||
AbsFace getUp();
|
AbsFace getUp();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the block at the location specified by its
|
||||||
|
* {@linkplain Coordinates#blockInChunk chunk coordinates}. During chunk
|
||||||
|
* generation it may be {@code null}.
|
||||||
|
*
|
||||||
|
* @param blockInChunk local coordinates of the block to fetch
|
||||||
|
* @return the block at the requested location or {@code null}.
|
||||||
|
*/
|
||||||
B getBlock(Vec3i blockInChunk);
|
B getBlock(Vec3i blockInChunk);
|
||||||
|
|
||||||
TS getTiles(Vec3i blockInChunk, BlockFace face);
|
TS getTiles(Vec3i blockInChunk, BlockFace face);
|
||||||
@ -178,91 +232,41 @@ public interface GenericChunk<Self extends GenericChunk<Self, B, T, TS>, B exten
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean containsBiC(Vec3i blockInChunk) {
|
public static boolean containsBiC(Vec3i blockInChunk) {
|
||||||
return blockInChunk.x >= 0 && blockInChunk.x < BLOCKS_PER_CHUNK &&
|
return blockInChunk.x >= 0 && blockInChunk.x < BLOCKS_PER_CHUNK &&
|
||||||
blockInChunk.y >= 0 && blockInChunk.y < BLOCKS_PER_CHUNK &&
|
blockInChunk.y >= 0 && blockInChunk.y < BLOCKS_PER_CHUNK &&
|
||||||
blockInChunk.z >= 0 && blockInChunk.z < BLOCKS_PER_CHUNK;
|
blockInChunk.z >= 0 && blockInChunk.z < BLOCKS_PER_CHUNK;
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean containsBiW(Vec3i blockInWorld) {
|
public static boolean isSurfaceBiC(Vec3i blockInChunk) {
|
||||||
Vec3i v = Vectors.grab3i();
|
return Util.getBorderHits(blockInChunk) >= 1;
|
||||||
|
|
||||||
v = Coordinates.getInWorld(getPosition(), Vectors.ZERO_3i, v);
|
|
||||||
v = blockInWorld.sub(v, v);
|
|
||||||
|
|
||||||
boolean result = containsBiC(v);
|
|
||||||
|
|
||||||
Vectors.release(v);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean isSurfaceBiC(Vec3i blockInChunk) {
|
public static boolean isEdgeBiC(Vec3i blockInChunk) {
|
||||||
int hits = 0;
|
return Util.getBorderHits(blockInChunk) >= 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (Coordinates.isOnChunkBorder(blockInChunk.x)) hits++;
|
public static boolean isVertexBiC(Vec3i blockInChunk) {
|
||||||
if (Coordinates.isOnChunkBorder(blockInChunk.y)) hits++;
|
return Util.getBorderHits(blockInChunk) == 3;
|
||||||
if (Coordinates.isOnChunkBorder(blockInChunk.z)) hits++;
|
}
|
||||||
|
|
||||||
return hits >= 1;
|
default boolean containsBiW(Vec3i blockInWorld) {
|
||||||
|
return Util.testBiC(blockInWorld, this, GenericChunk::containsBiC);
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean isSurfaceBiW(Vec3i blockInWorld) {
|
default boolean isSurfaceBiW(Vec3i blockInWorld) {
|
||||||
Vec3i v = Vectors.grab3i();
|
return Util.testBiC(blockInWorld, this, GenericChunk::isSurfaceBiC);
|
||||||
|
|
||||||
v = Coordinates.getInWorld(getPosition(), Vectors.ZERO_3i, v);
|
|
||||||
v = blockInWorld.sub(v, v);
|
|
||||||
|
|
||||||
boolean result = isSurfaceBiC(v);
|
|
||||||
|
|
||||||
Vectors.release(v);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean isEdgeBiC(Vec3i blockInChunk) {
|
|
||||||
int hits = 0;
|
|
||||||
|
|
||||||
if (Coordinates.isOnChunkBorder(blockInChunk.x)) hits++;
|
|
||||||
if (Coordinates.isOnChunkBorder(blockInChunk.y)) hits++;
|
|
||||||
if (Coordinates.isOnChunkBorder(blockInChunk.z)) hits++;
|
|
||||||
|
|
||||||
return hits >= 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean isEdgeBiW(Vec3i blockInWorld) {
|
default boolean isEdgeBiW(Vec3i blockInWorld) {
|
||||||
Vec3i v = Vectors.grab3i();
|
return Util.testBiC(blockInWorld, this, GenericChunk::isEdgeBiC);
|
||||||
|
|
||||||
v = Coordinates.getInWorld(getPosition(), Vectors.ZERO_3i, v);
|
|
||||||
v = blockInWorld.sub(v, v);
|
|
||||||
|
|
||||||
boolean result = isEdgeBiC(v);
|
|
||||||
|
|
||||||
Vectors.release(v);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean isVertexBiC(Vec3i blockInChunk) {
|
|
||||||
int hits = 0;
|
|
||||||
|
|
||||||
if (Coordinates.isOnChunkBorder(blockInChunk.x)) hits++;
|
|
||||||
if (Coordinates.isOnChunkBorder(blockInChunk.y)) hits++;
|
|
||||||
if (Coordinates.isOnChunkBorder(blockInChunk.z)) hits++;
|
|
||||||
|
|
||||||
return hits == 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean isVertexBiW(Vec3i blockInWorld) {
|
default boolean isVertexBiW(Vec3i blockInWorld) {
|
||||||
Vec3i v = Vectors.grab3i();
|
return Util.testBiC(blockInWorld, this, GenericChunk::isVertexBiC);
|
||||||
|
|
||||||
v = Coordinates.getInWorld(getPosition(), Vectors.ZERO_3i, v);
|
|
||||||
v = blockInWorld.sub(v, v);
|
|
||||||
|
|
||||||
boolean result = isVertexBiC(v);
|
|
||||||
|
|
||||||
Vectors.release(v);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void forEachBiC(Consumer<? super Vec3i> action) {
|
public static void forEachBiC(Consumer<? super Vec3i> action) {
|
||||||
VectorUtil.iterateCuboid(
|
VectorUtil.iterateCuboid(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@ -311,4 +315,24 @@ public interface GenericChunk<Self extends GenericChunk<Self, B, T, TS>, B exten
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default void forEachTileStack(Consumer<TS> action) {
|
||||||
|
forEachBiC(blockInChunk -> {
|
||||||
|
for (AbsFace face : AbsFace.getFaces()) {
|
||||||
|
TS stack = getTilesOrNull(blockInChunk, face);
|
||||||
|
if (stack == null)
|
||||||
|
continue;
|
||||||
|
action.accept(stack);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterates over all tiles in this chunk.
|
||||||
|
*
|
||||||
|
* @param action the action to perform
|
||||||
|
*/
|
||||||
|
default void forEachTile(BiConsumer<TS, T> action) {
|
||||||
|
forEachTileStack(stack -> stack.forEach(tileData -> action.accept(stack, tileData)));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Progressia
|
||||||
|
* Copyright (C) 2020-2021 Wind Corporation and contributors
|
||||||
|
*
|
||||||
|
* 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.world.generic;
|
||||||
|
|
||||||
|
import glm.vec._3.i.Vec3i;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.common.world.block.BlockData;
|
||||||
|
|
||||||
|
public interface GenericWritableChunk<Self extends GenericWritableChunk<Self, B, T, TS>, B extends GenericBlock, T extends GenericTile, TS extends GenericTileStack<TS, T, Self>>
|
||||||
|
extends GenericChunk<Self, B, T, TS> {
|
||||||
|
|
||||||
|
void setBlock(Vec3i posInChunk, BlockData block, boolean notify);
|
||||||
|
|
||||||
|
void setBlockRel(Vec3i relativeBlockInChunk, B block, boolean notify);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Progressia
|
||||||
|
* Copyright (C) 2020-2021 Wind Corporation and contributors
|
||||||
|
*
|
||||||
|
* 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.world.generic;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import glm.vec._3.i.Vec3i;
|
||||||
|
import ru.windcorp.progressia.common.util.Vectors;
|
||||||
|
import ru.windcorp.progressia.common.world.Coordinates;
|
||||||
|
|
||||||
|
class Util {
|
||||||
|
|
||||||
|
public static int getBorderHits(Vec3i blockInChunk) {
|
||||||
|
int hits = 0;
|
||||||
|
|
||||||
|
if (Coordinates.isOnChunkBorder(blockInChunk.x)) hits++;
|
||||||
|
if (Coordinates.isOnChunkBorder(blockInChunk.y)) hits++;
|
||||||
|
if (Coordinates.isOnChunkBorder(blockInChunk.z)) hits++;
|
||||||
|
|
||||||
|
return hits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean testBiC(Vec3i blockInWorld, GenericChunk<?, ?, ?, ?> chunk, Predicate<Vec3i> test) {
|
||||||
|
Vec3i v = Vectors.grab3i();
|
||||||
|
|
||||||
|
v = Coordinates.getInWorld(chunk.getPosition(), Vectors.ZERO_3i, v);
|
||||||
|
v = blockInWorld.sub(v, v);
|
||||||
|
|
||||||
|
boolean result = test.test(v);
|
||||||
|
|
||||||
|
Vectors.release(v);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -22,6 +22,7 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
import glm.vec._3.i.Vec3i;
|
import glm.vec._3.i.Vec3i;
|
||||||
import ru.windcorp.progressia.common.world.ChunkData;
|
import ru.windcorp.progressia.common.world.ChunkData;
|
||||||
|
import ru.windcorp.progressia.common.world.generic.GenericChunk;
|
||||||
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
||||||
import ru.windcorp.progressia.server.world.block.BlockTickContext;
|
import ru.windcorp.progressia.server.world.block.BlockTickContext;
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ public interface ChunkTickContext extends TickContext {
|
|||||||
default void forEachBlock(Consumer<BlockTickContext> action) {
|
default void forEachBlock(Consumer<BlockTickContext> action) {
|
||||||
TickContextMutable context = TickContextMutable.uninitialized();
|
TickContextMutable context = TickContextMutable.uninitialized();
|
||||||
|
|
||||||
getChunkData().forEachBlock(blockInChunk -> {
|
GenericChunk.forEachBiC(blockInChunk -> {
|
||||||
context.rebuild().withServer(getServer()).withChunk(getChunk()).withBlockInChunk(blockInChunk).build();
|
context.rebuild().withServer(getServer()).withChunk(getChunk()).withBlockInChunk(blockInChunk).build();
|
||||||
action.accept(context);
|
action.accept(context);
|
||||||
});
|
});
|
||||||
|
@ -38,6 +38,7 @@ import ru.windcorp.progressia.common.world.DecodingException;
|
|||||||
import ru.windcorp.progressia.common.world.WorldData;
|
import ru.windcorp.progressia.common.world.WorldData;
|
||||||
import ru.windcorp.progressia.common.world.block.BlockData;
|
import ru.windcorp.progressia.common.world.block.BlockData;
|
||||||
import ru.windcorp.progressia.common.world.block.BlockDataRegistry;
|
import ru.windcorp.progressia.common.world.block.BlockDataRegistry;
|
||||||
|
import ru.windcorp.progressia.common.world.generic.GenericChunk;
|
||||||
import ru.windcorp.progressia.common.world.io.ChunkCodec;
|
import ru.windcorp.progressia.common.world.io.ChunkCodec;
|
||||||
import ru.windcorp.progressia.common.world.rels.RelFace;
|
import ru.windcorp.progressia.common.world.rels.RelFace;
|
||||||
import ru.windcorp.progressia.common.world.tile.TileData;
|
import ru.windcorp.progressia.common.world.tile.TileData;
|
||||||
@ -124,7 +125,7 @@ public class TestChunkCodec extends ChunkCodec {
|
|||||||
|
|
||||||
private void readBlocks(DataInput input, BlockData[] blockPalette, ChunkData chunk) throws IOException {
|
private void readBlocks(DataInput input, BlockData[] blockPalette, ChunkData chunk) throws IOException {
|
||||||
try {
|
try {
|
||||||
chunk.forEachBiC(guard(v -> {
|
GenericChunk.forEachBiC(guard(v -> {
|
||||||
chunk.setBlock(v, blockPalette[input.readInt()], false);
|
chunk.setBlock(v, blockPalette[input.readInt()], false);
|
||||||
}));
|
}));
|
||||||
} catch (UncheckedIOException e) {
|
} catch (UncheckedIOException e) {
|
||||||
@ -171,7 +172,7 @@ public class TestChunkCodec extends ChunkCodec {
|
|||||||
|
|
||||||
private Palette<BlockData> createBlockPalette(ChunkData chunk) {
|
private Palette<BlockData> createBlockPalette(ChunkData chunk) {
|
||||||
Palette<BlockData> blockPalette = new Palette<>();
|
Palette<BlockData> blockPalette = new Palette<>();
|
||||||
chunk.forEachBiC(v -> blockPalette.add(chunk.getBlock(v)));
|
GenericChunk.forEachBiC(v -> blockPalette.add(chunk.getBlock(v)));
|
||||||
return blockPalette;
|
return blockPalette;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +200,7 @@ public class TestChunkCodec extends ChunkCodec {
|
|||||||
|
|
||||||
private void writeBlocks(ChunkData chunk, Palette<BlockData> blockPalette, DataOutput output) throws IOException {
|
private void writeBlocks(ChunkData chunk, Palette<BlockData> blockPalette, DataOutput output) throws IOException {
|
||||||
try {
|
try {
|
||||||
chunk.forEachBiC(guard(v -> {
|
GenericChunk.forEachBiC(guard(v -> {
|
||||||
output.writeInt(blockPalette.getNid(chunk.getBlock(v)));
|
output.writeInt(blockPalette.getNid(chunk.getBlock(v)));
|
||||||
}));
|
}));
|
||||||
} catch (UncheckedIOException e) {
|
} catch (UncheckedIOException e) {
|
||||||
|
@ -26,6 +26,7 @@ import ru.windcorp.progressia.common.world.ChunkData;
|
|||||||
import ru.windcorp.progressia.common.world.Coordinates;
|
import ru.windcorp.progressia.common.world.Coordinates;
|
||||||
import ru.windcorp.progressia.common.world.block.BlockData;
|
import ru.windcorp.progressia.common.world.block.BlockData;
|
||||||
import ru.windcorp.progressia.common.world.block.BlockDataRegistry;
|
import ru.windcorp.progressia.common.world.block.BlockDataRegistry;
|
||||||
|
import ru.windcorp.progressia.common.world.generic.GenericChunk;
|
||||||
import ru.windcorp.progressia.test.gen.TerrainLayer;
|
import ru.windcorp.progressia.test.gen.TerrainLayer;
|
||||||
import ru.windcorp.progressia.test.gen.surface.SurfaceFloatField;
|
import ru.windcorp.progressia.test.gen.surface.SurfaceFloatField;
|
||||||
import ru.windcorp.progressia.test.gen.surface.SurfaceTerrainGenerator;
|
import ru.windcorp.progressia.test.gen.surface.SurfaceTerrainGenerator;
|
||||||
@ -89,7 +90,7 @@ class PlanetTerrainGenerator {
|
|||||||
|
|
||||||
Vec3 biw = new Vec3();
|
Vec3 biw = new Vec3();
|
||||||
|
|
||||||
chunk.forEachBiC(bic -> {
|
GenericChunk.forEachBiC(bic -> {
|
||||||
|
|
||||||
biw.set(
|
biw.set(
|
||||||
Coordinates.getInWorld(chunk.getX(), bic.x),
|
Coordinates.getInWorld(chunk.getX(), bic.x),
|
||||||
|
Reference in New Issue
Block a user