Add basic horizontal light spread to fallback sky lighting
This commit is contained in:
parent
0452ab1dac
commit
833b25615a
2 changed files with 90 additions and 19 deletions
|
|
@ -117,33 +117,99 @@ public class GenericChunk {
|
||||||
// Generate simple sky lighting (must be after all sections have been added)
|
// Generate simple sky lighting (must be after all sections have been added)
|
||||||
public Builder generateSky() {
|
public Builder generateSky() {
|
||||||
int sky[] = new int[256]; // ZX array
|
int sky[] = new int[256]; // ZX array
|
||||||
|
boolean nonOpaque[] = new boolean[256]; // ZX array of non opaque blocks (atten < 15)
|
||||||
Arrays.fill(sky, 15); // Start fully lit at top
|
Arrays.fill(sky, 15); // Start fully lit at top
|
||||||
GenericChunkSection.Builder bld = new GenericChunkSection.Builder();
|
GenericChunkSection.Builder bld = new GenericChunkSection.Builder();
|
||||||
boolean allzero = false;
|
boolean allzero = false;
|
||||||
// Make light array for each section, start from top
|
// Make light array for each section, start from top
|
||||||
for (int i = (sections.length - 1); i >= 0; i--) {
|
for (int i = (sections.length - 1); i >= 0; i--) {
|
||||||
if (sections[i] == null) continue;
|
GenericChunkSection sect = sections[i];
|
||||||
|
if (sect == null) continue;
|
||||||
|
if (allzero) { // Start section with all zero already, just zero it and move on
|
||||||
|
// Replace section with new all zero light
|
||||||
|
sections[i] = bld.buildFrom(sect, 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
byte[] ssky = new byte[2048];
|
byte[] ssky = new byte[2048];
|
||||||
if (!allzero) {
|
int allfullcnt = 0;
|
||||||
for (int x = 0; x < 16; x++) {
|
// Top to bottom
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int y = 15; (y >= 0) && (!allzero); y--) {
|
||||||
int idx = (z << 4) + x;
|
int totalval = 0; // Use for allzero or allfull
|
||||||
for (int y = 15; y >= 0; y--) {
|
int yidx = y << 7;
|
||||||
DynmapBlockState bs = sections[i].blocks.getBlock(x, y, z); // Get block
|
// Light next layer down
|
||||||
int atten = bs.getLightAttenuation();
|
for (int x = 0; x < 16; x++) {
|
||||||
sky[idx] = (sky[idx] >= atten) ? (sky[idx] - atten) : 0;
|
for (int z = 0; z < 16; z++) {
|
||||||
ssky[(y << 7) | (z << 3) | (x >> 1)] |= (sky[idx] << (4 * (x & 1)));
|
int idx = (z << 4) + x;
|
||||||
}
|
int val = sky[idx];
|
||||||
}
|
DynmapBlockState bs = sect.blocks.getBlock(x, y, z); // Get block
|
||||||
}
|
int atten = bs.getLightAttenuation();
|
||||||
// Check if we're all dark
|
if ((atten > 0) && (val > 0)) {
|
||||||
allzero = true;
|
val = (val >= atten) ? (val - atten) : 0;
|
||||||
for (int v = 0; v < 256; v++) {
|
sky[idx] = val;
|
||||||
if (sky[v] > 0) { allzero = false; break; }
|
}
|
||||||
}
|
nonOpaque[idx] = atten < 15;
|
||||||
|
totalval += val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
allzero = (totalval == 0);
|
||||||
|
boolean allfull = (totalval == (15 * 256));
|
||||||
|
if (allfull) allfullcnt++;
|
||||||
|
// If not all fully lit nor all zero, handle horizontal spread
|
||||||
|
if (! (allfull || allzero)) {
|
||||||
|
// Now do horizontal spread
|
||||||
|
boolean changed;
|
||||||
|
do {
|
||||||
|
changed = false;
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
int idx = (z << 4) + x;
|
||||||
|
int cur = sky[idx];
|
||||||
|
boolean curnonopaq = nonOpaque[idx];
|
||||||
|
if (x < 15) { // If not right edge, check X spread
|
||||||
|
int right = sky[idx+1];
|
||||||
|
boolean rightnonopaq = nonOpaque[idx+1];
|
||||||
|
// If spread right
|
||||||
|
if (rightnonopaq && ((cur - 1) > right)) {
|
||||||
|
sky[idx+1] = cur - 1; changed = true;
|
||||||
|
}
|
||||||
|
// If spread left
|
||||||
|
else if (curnonopaq && (cur < (right - 1))) {
|
||||||
|
sky[idx] = cur = right - 1; changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (z < 15) { // If not bottom edge, check Z spread
|
||||||
|
int down = sky[idx+16];
|
||||||
|
boolean downnonopaq = nonOpaque[idx+16];
|
||||||
|
// If spread down
|
||||||
|
if (downnonopaq && ((cur - 1) > down)) {
|
||||||
|
sky[idx+16] = cur - 1; changed = true;
|
||||||
|
}
|
||||||
|
// If spread up
|
||||||
|
else if (curnonopaq && (cur < (down - 1))) {
|
||||||
|
sky[idx] = down - 1; changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (changed);
|
||||||
|
// Save values
|
||||||
|
for (int v = 0; v < 128; v++) {
|
||||||
|
ssky[yidx | v] = (byte)(sky[v << 1] | (sky[(v << 1) + 1] << 4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (allfull) { // All light, just fill it
|
||||||
|
for (int v = 0; v < 128; v++) {
|
||||||
|
ssky[yidx | v] = (byte) 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Replace section with new one with new lighting
|
// Replace section with new one with new lighting
|
||||||
sections[i] = bld.buildFrom(sections[i], ssky);
|
if (allfullcnt == 16) { // Just full?
|
||||||
|
sections[i] = bld.buildFrom(sect, 15);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sections[i] = bld.buildFrom(sect, ssky);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,11 @@ public class GenericChunkSection {
|
||||||
LightingAccess skyA = new LightingAccess3D(sky);
|
LightingAccess skyA = new LightingAccess3D(sky);
|
||||||
return new GenericChunkSection(s.blocks, s.biomes, skyA, s.emitted, s.isEmpty);
|
return new GenericChunkSection(s.blocks, s.biomes, skyA, s.emitted, s.isEmpty);
|
||||||
}
|
}
|
||||||
|
// Build copy from existing section with new single value skylight
|
||||||
|
public GenericChunkSection buildFrom(GenericChunkSection s, int singlesky) {
|
||||||
|
LightingAccess skyA = new LightingAccessSingle(singlesky);
|
||||||
|
return new GenericChunkSection(s.blocks, s.biomes, skyA, s.emitted, s.isEmpty);
|
||||||
|
}
|
||||||
|
|
||||||
// Build section based on current builder state
|
// Build section based on current builder state
|
||||||
public GenericChunkSection build() {
|
public GenericChunkSection build() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue