mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-11 00:23:42 -04:00
get light from edge chunks
This commit is contained in:
parent
959d682eb0
commit
db07729325
@ -12,7 +12,7 @@ Minosoft is an open source minecraft client, written from scratch in kotlin (and
|
|||||||
## Feature overview
|
## Feature overview
|
||||||
|
|
||||||
- Rendering
|
- Rendering
|
||||||
- Connect with any version to any server (1.7 - latest)
|
- Connect with any version to any server (1.7 - 1.19)
|
||||||
- ~~Modding~~
|
- ~~Modding~~
|
||||||
- Bleeding edge performance (e.g. incredible start time)
|
- Bleeding edge performance (e.g. incredible start time)
|
||||||
- Free (as far as we consider original minecraft as free) and open source
|
- Free (as far as we consider original minecraft as free) and open source
|
||||||
@ -125,11 +125,11 @@ Support for macOS is a delicate topic. Let's say it works for now, but it is not
|
|||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
1. Install Maven and java 11+ (On Ubuntu based distributions: `sudo apt install maven openjdk-11-jdk`). For Windows users, download and install java from oracle or openjdk. Also download maven and follow along
|
1. Install Maven and java 11+ (e.g. `sudo apt install maven openjdk-11-jdk`). For Windows users, download and install java from oracle or openjdk. Also download maven and follow along
|
||||||
2. Clone this repository (`git clone https://gitlab.bixilon.de/bixilon/minosoft.git`)
|
2. Clone this repository (`git clone https://gitlab.bixilon.de/bixilon/minosoft.git`)
|
||||||
3. Change directory (`cd minosoft`)
|
3. Change directory (`cd minosoft`)
|
||||||
4. Optional: Checkout a current feature branch (Warning: might be unstable; might not even build) (`git checkout <branch>`)
|
4. Optional: Checkout a current feature branch (Warning: might be unstable; might not even build) (`git checkout <branch>`)
|
||||||
5. Build and run Minosoft with `mvn clean verify exec:java`. If any errors occur, feel free to open an issue. In this early stage it might be helpful to delete the config file
|
5. Build and run Minosoft with `mvn clean verify exec:java`. If any errors occur, feel free to open an issue. In this early stage it might be helpful to delete its configuration files
|
||||||
6. (Optional) Build a fat jar with `mvn package`. You'll find the jar with all dependencies in `target/`. Then you don't need to recompile everytime
|
6. (Optional) Build a fat jar with `mvn package`. You'll find the jar with all dependencies in `target/`. Then you don't need to recompile everytime
|
||||||
|
|
||||||
## Code mirrors
|
## Code mirrors
|
||||||
|
@ -376,26 +376,29 @@ class World(
|
|||||||
val neighboursPositions = getChunkNeighbourPositions(chunkPosition)
|
val neighboursPositions = getChunkNeighbourPositions(chunkPosition)
|
||||||
val neighbours = getChunkNeighbours(neighboursPositions)
|
val neighbours = getChunkNeighbours(neighboursPositions)
|
||||||
|
|
||||||
if (neighbours.received) {
|
val neighboursReceived = neighbours.received
|
||||||
|
if (neighboursReceived) {
|
||||||
chunk.neighbours = neighbours.cast()
|
chunk.neighbours = neighbours.cast()
|
||||||
|
|
||||||
if (!chunk.biomesInitialized && cacheBiomeAccessor != null && chunk.biomeSource != null && neighbours.canBuildBiomeCache) {
|
if (!chunk.biomesInitialized && cacheBiomeAccessor != null && chunk.biomeSource != null && neighbours.canBuildBiomeCache) {
|
||||||
chunk.buildBiomeCache()
|
chunk.buildBiomeCache()
|
||||||
}
|
}
|
||||||
connection.fireEvent(ChunkDataChangeEvent(connection, EventInitiators.UNKNOWN, chunkPosition, chunk))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!checkNeighbours) {
|
if (checkNeighbours) {
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for (index in 0 until 8) {
|
for (index in 0 until 8) {
|
||||||
val neighbour = neighbours[index] ?: continue
|
val neighbour = neighbours[index] ?: continue
|
||||||
onChunkUpdate(neighboursPositions[index], neighbour, false)
|
onChunkUpdate(neighboursPositions[index], neighbour, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (neighboursReceived) {
|
||||||
|
chunk.recalculateLight()
|
||||||
|
connection.fireEvent(ChunkDataChangeEvent(connection, EventInitiators.UNKNOWN, chunkPosition, chunk))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getBrightness(position: Vec3i): Float {
|
fun getBrightness(position: Vec3i): Float {
|
||||||
val light = getLight(position) and 0x0F
|
val light = getLight(position) and 0x0F
|
||||||
return dimension?.lightLevels?.get(light) ?: 0.0f
|
return dimension?.lightLevels?.get(light) ?: 0.0f
|
||||||
|
@ -59,14 +59,13 @@ class Chunk(
|
|||||||
val heightmap = IntArray(ProtocolDefinition.SECTION_WIDTH_X * ProtocolDefinition.SECTION_WIDTH_Z)
|
val heightmap = IntArray(ProtocolDefinition.SECTION_WIDTH_X * ProtocolDefinition.SECTION_WIDTH_Z)
|
||||||
|
|
||||||
var neighbours: Array<Chunk>? = null
|
var neighbours: Array<Chunk>? = null
|
||||||
set(value) {
|
@Synchronized set(value) {
|
||||||
if (field.contentEquals(value)) {
|
if (field.contentEquals(value)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
field = value
|
field = value
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
updateSectionNeighbours(value)
|
updateSectionNeighbours(value)
|
||||||
recalculateLight()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +103,7 @@ class Chunk(
|
|||||||
if (blockEntity == null) {
|
if (blockEntity == null) {
|
||||||
getOrPutBlockEntity(x, y, z)
|
getOrPutBlockEntity(x, y, z)
|
||||||
}
|
}
|
||||||
|
// ToDo: Remove section if isEmpty
|
||||||
|
|
||||||
val neighbours = this.neighbours ?: return
|
val neighbours = this.neighbours ?: return
|
||||||
|
|
||||||
@ -250,12 +250,16 @@ class Chunk(
|
|||||||
if (cacheBiomeAccessor != null && biomesInitialized) {
|
if (cacheBiomeAccessor != null && biomesInitialized) {
|
||||||
section.buildBiomeCache(chunkPosition, sectionHeight, this, neighbours, cacheBiomeAccessor)
|
section.buildBiomeCache(chunkPosition, sectionHeight, this, neighbours, cacheBiomeAccessor)
|
||||||
}
|
}
|
||||||
|
section.neighbours = ChunkUtil.getDirectNeighbours(neighbours, this, sectionHeight)
|
||||||
for (neighbour in neighbours) {
|
for (neighbour in neighbours) {
|
||||||
val neighbourNeighbours = neighbour.neighbours ?: continue
|
val neighbourNeighbours = neighbour.neighbours ?: continue
|
||||||
neighbour.updateNeighbours(neighbourNeighbours, sectionHeight)
|
neighbour.updateNeighbours(neighbourNeighbours, sectionHeight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sections[sectionIndex] = section
|
sections[sectionIndex] = section
|
||||||
|
|
||||||
|
// check light of neighbours to check if their light needs to be traced into our own chunk
|
||||||
|
section.light.propagateFromNeighbours()
|
||||||
}
|
}
|
||||||
return section
|
return section
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ class SectionLight(
|
|||||||
|
|
||||||
private fun startDecreaseTrace(x: Int, y: Int, z: Int) {
|
private fun startDecreaseTrace(x: Int, y: Int, z: Int) {
|
||||||
// that is kind of hacky, but far easier and kind of faster
|
// that is kind of hacky, but far easier and kind of faster
|
||||||
val light = this.light[getIndex(x, y, z)].toInt() and 0x0F
|
val light = this.light[getIndex(x, y, z)].toInt() and BLOCK_LIGHT_MASK
|
||||||
|
|
||||||
decreaseLight(x, y, z, light, true) // just clear the light
|
decreaseLight(x, y, z, light, true) // just clear the light
|
||||||
decreaseLight(x, y, z, light, false) // increase the light in all sections
|
decreaseLight(x, y, z, light, false) // increase the light in all sections
|
||||||
@ -96,7 +96,7 @@ class SectionLight(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get block or next luminance level
|
// get block or next luminance level
|
||||||
val currentLight = light[index].toInt() and 0x0F // we just care about block light
|
val currentLight = light[index].toInt() and BLOCK_LIGHT_MASK // we just care about block light
|
||||||
if (currentLight >= nextLuminance) {
|
if (currentLight >= nextLuminance) {
|
||||||
// light is already higher, no need to trace
|
// light is already higher, no need to trace
|
||||||
return
|
return
|
||||||
@ -202,4 +202,30 @@ class SectionLight(
|
|||||||
override operator fun get(index: Int): Byte {
|
override operator fun get(index: Int): Byte {
|
||||||
return light[index]
|
return light[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun propagateFromNeighbours() {
|
||||||
|
val neighbours = section.neighbours ?: return
|
||||||
|
// ToDo(p): this::traceIncrease checks als the block light level, not needed
|
||||||
|
for (x in 0 until ProtocolDefinition.SECTION_WIDTH_X) {
|
||||||
|
for (z in 0 until ProtocolDefinition.SECTION_WIDTH_Z) {
|
||||||
|
neighbours[Directions.O_DOWN]?.let { traceIncrease(x, 0, z, it.light[x, ProtocolDefinition.SECTION_MAX_Y, z].toInt() and BLOCK_LIGHT_MASK) }
|
||||||
|
neighbours[Directions.O_UP]?.let { traceIncrease(x, ProtocolDefinition.SECTION_MAX_Y, z, it.light[x, 0, z].toInt() and BLOCK_LIGHT_MASK) }
|
||||||
|
}
|
||||||
|
for (y in 0 until ProtocolDefinition.SECTION_HEIGHT_Y) {
|
||||||
|
neighbours[Directions.O_NORTH]?.let { traceIncrease(x, y, 0, it.light[x, y, ProtocolDefinition.SECTION_MAX_Z].toInt() and BLOCK_LIGHT_MASK) }
|
||||||
|
neighbours[Directions.O_SOUTH]?.let { traceIncrease(x, y, ProtocolDefinition.SECTION_MAX_Z, it.light[x, y, 0].toInt() and BLOCK_LIGHT_MASK) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (z in 0 until ProtocolDefinition.SECTION_WIDTH_Z) {
|
||||||
|
for (y in 0 until ProtocolDefinition.SECTION_HEIGHT_Y) {
|
||||||
|
neighbours[Directions.O_WEST]?.let { traceIncrease(0, y, z, it.light[ProtocolDefinition.SECTION_MAX_Z, y, z].toInt() and BLOCK_LIGHT_MASK) }
|
||||||
|
neighbours[Directions.O_UP]?.let { traceIncrease(ProtocolDefinition.SECTION_MAX_X, y, z, it.light[0, y, z].toInt() and BLOCK_LIGHT_MASK) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val BLOCK_LIGHT_MASK = 0x0F
|
||||||
|
const val SKY_LIGHT_MASK = 0xF0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,11 +51,12 @@ public final class ProtocolDefinition {
|
|||||||
|
|
||||||
public static final Pattern MINECRAFT_NAME_VALIDATOR = Pattern.compile("\\w{3,16}");
|
public static final Pattern MINECRAFT_NAME_VALIDATOR = Pattern.compile("\\w{3,16}");
|
||||||
|
|
||||||
public static final int SECTION_WIDTH_X = 16;
|
public static final int SECTION_LENGTH = 16;
|
||||||
|
public static final int SECTION_WIDTH_X = SECTION_LENGTH;
|
||||||
public static final int SECTION_MAX_X = SECTION_WIDTH_X - 1;
|
public static final int SECTION_MAX_X = SECTION_WIDTH_X - 1;
|
||||||
public static final int SECTION_WIDTH_Z = 16;
|
public static final int SECTION_WIDTH_Z = SECTION_LENGTH;
|
||||||
public static final int SECTION_MAX_Z = SECTION_WIDTH_Z - 1;
|
public static final int SECTION_MAX_Z = SECTION_WIDTH_Z - 1;
|
||||||
public static final int SECTION_HEIGHT_Y = 16;
|
public static final int SECTION_HEIGHT_Y = SECTION_LENGTH;
|
||||||
public static final int SECTION_MAX_Y = SECTION_HEIGHT_Y - 1;
|
public static final int SECTION_MAX_Y = SECTION_HEIGHT_Y - 1;
|
||||||
public static final int BLOCKS_PER_SECTION = SECTION_WIDTH_X * SECTION_HEIGHT_Y * SECTION_WIDTH_X;
|
public static final int BLOCKS_PER_SECTION = SECTION_WIDTH_X * SECTION_HEIGHT_Y * SECTION_WIDTH_X;
|
||||||
public static final Vec3i CHUNK_SECTION_SIZE = new Vec3i(ProtocolDefinition.SECTION_WIDTH_X, ProtocolDefinition.SECTION_HEIGHT_Y, ProtocolDefinition.SECTION_WIDTH_Z);
|
public static final Vec3i CHUNK_SECTION_SIZE = new Vec3i(ProtocolDefinition.SECTION_WIDTH_X, ProtocolDefinition.SECTION_HEIGHT_Y, ProtocolDefinition.SECTION_WIDTH_Z);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user