Skip to content

Commit 82febaf

Browse files
committed
Improve sky light rendering performance, fix height map bug
1 parent a4d2341 commit 82febaf

6 files changed

Lines changed: 324 additions & 227 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
J2Blocks aims to provide a simple library for custom map generation. In order to use this library it is not necessary to deal with things like regions, chunks and block data. However it aims to implement all map features that Minecraft offers. Please keep in mind that this is still beta.
44

5+
[→ J2Blocks Documentation](http://docs.morbz.de/j2blocks/)
6+
57
Example
68
------
79
In this example we want to create a Minecraft world that is paved with melon-blocks. We want to create a huge structure of glass and want to set door on top of it. From the [Example.java](https://github.com/MorbZ/J2Blocks/blob/master/doc/Example.java):

src/net/morbz/minecraft/world/Chunk.java

Lines changed: 70 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,18 @@ public class Chunk implements ITagProvider, IBlockContainer {
5858
private Section[] sections = new Section[SECTIONS_PER_CHUNK];
5959
private int[][] heightMap = new int[BLOCKS_PER_CHUNK_SIDE][BLOCKS_PER_CHUNK_SIDE];
6060
private int xPos, zPos;
61+
private IBlockContainer parent;
6162

6263
/**
6364
* Creates a new instance.
6465
*
65-
* @param xPos The X-coordinate within the chunk
66-
* @param zPos The Z-coordinate within the chunk
66+
* @param parent The parent block container
67+
* @param xPos The X-coordinate within the region
68+
* @param zPos The Z-coordinate within the region
6769
* @param layers The default layers. Can be 'null'
6870
*/
69-
public Chunk(int xPos, int zPos, DefaultLayers layers) {
71+
public Chunk(IBlockContainer parent, int xPos, int zPos, DefaultLayers layers) {
72+
this.parent = parent;
7073
this.xPos = xPos;
7174
this.zPos = zPos;
7275

@@ -91,6 +94,20 @@ public Chunk(int xPos, int zPos, DefaultLayers layers) {
9194
}
9295
}
9396

97+
/**
98+
* @return The X-coordinate within the region
99+
*/
100+
public int getX() {
101+
return xPos;
102+
}
103+
104+
/**
105+
* @return The Z-coordinate within the region
106+
*/
107+
public int getZ() {
108+
return zPos;
109+
}
110+
94111
/**
95112
* Sets a block at the given position.
96113
*
@@ -112,45 +129,76 @@ public void setBlock(int x, int y, int z, IBlock block) {
112129
* {@inheritDoc}
113130
*/
114131
@Override
115-
public byte getTransparency(int x, int y, int z) {
132+
public byte getSkyLight(int x, int y, int z) {
116133
// Get section
117134
Section section = getSection(y, false);
118135

119136
if(section != null) {
120137
int blockY = y % Section.SECTION_HEIGHT;
121-
byte light = section.getTransparency(x, blockY, z);
138+
byte light = section.getSkyLight(x, blockY, z);
122139
return light;
123140
}
124-
return World.DEFAULT_TRANSPARENCY;
141+
return World.DEFAULT_SKY_LIGHT;
125142
}
126143

127-
/**
128-
* {@inheritDoc}
129-
*/
130-
@Override
131-
public byte getSkyLight(int x, int y, int z) {
144+
private void setSkyLight(int x, int y, int z, byte light) {
132145
// Get section
133146
Section section = getSection(y, false);
134147

135148
if(section != null) {
136149
int blockY = y % Section.SECTION_HEIGHT;
137-
byte light = section.getSkyLight(x, blockY, z);
138-
return light;
150+
section.setSkyLight(x, blockY, z, light);
139151
}
140-
return World.DEFAULT_SKY_LIGHT;
141152
}
142153

143154
/**
144155
* {@inheritDoc}
145156
*/
146157
@Override
147-
public void setSkyLight(int x, int y, int z, byte light) {
148-
// Get section
149-
Section section = getSection(y, false);
158+
public byte getSkyLightFromParent(IBlockContainer child, int childX, int childY, int childZ) {
159+
// Get total Y
160+
int y = ((Section)child).getY() * Section.SECTION_HEIGHT + childY;
161+
if(y >= World.MAX_HEIGHT) {
162+
return World.DEFAULT_SKY_LIGHT;
163+
}
164+
if(y < 0) {
165+
return 0;
166+
}
150167

151-
if(section != null) {
152-
int blockY = y % Section.SECTION_HEIGHT;
153-
section.setSkyLight(x, blockY, z, light);
168+
// Which chunk?
169+
if(childX >= 0 && childX < BLOCKS_PER_CHUNK_SIDE && childZ >= 0 && childZ < BLOCKS_PER_CHUNK_SIDE) {
170+
// Same chunk
171+
return getSkyLight(childX, y, childZ);
172+
} else {
173+
// Different chunk
174+
return parent.getSkyLightFromParent(this, childX, y, childZ);
175+
}
176+
}
177+
178+
/**
179+
* {@inheritDoc}
180+
*/
181+
@Override
182+
public void spreadSkyLight(byte light) {
183+
for(Section section : sections) {
184+
if(section != null) {
185+
section.spreadSkyLight(light);
186+
}
187+
}
188+
}
189+
190+
/**
191+
* Adds the sky light. Starts from top the top of each column and sets sky light to full, up to
192+
* the first non-transparent block.
193+
*/
194+
public void addSkyLight() {
195+
for(int x = 0; x < BLOCKS_PER_CHUNK_SIDE; x++) {
196+
for(int z = 0; z < BLOCKS_PER_CHUNK_SIDE; z++) {
197+
int highestBlock = getHighestBlock(x, z);
198+
for(int y = World.MAX_HEIGHT - 1; y >= highestBlock; y--) {
199+
setSkyLight(x, y, z, World.DEFAULT_SKY_LIGHT);
200+
}
201+
}
154202
}
155203
}
156204

@@ -173,7 +221,7 @@ private Section getSection(int y, boolean create) {
173221

174222
// Create section
175223
if(section == null && create) {
176-
section = new Section(sectionY);
224+
section = new Section(this, sectionY);
177225
sections[sectionY] = section;
178226
}
179227
return section;
@@ -209,7 +257,7 @@ public void calculateHeightMap() {
209257
if(heightMap[x][z] == 0) {
210258
int height = section.getHighestBlock(x, z);
211259
if(height != -1) {
212-
heightMap[x][z] = y * Section.SECTION_HEIGHT + height;
260+
heightMap[x][z] = y * Section.SECTION_HEIGHT + height + 1;
213261
}
214262
}
215263
}
Lines changed: 62 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,62 @@
1-
package net.morbz.minecraft.world;
2-
3-
/*
4-
* The MIT License (MIT)
5-
*
6-
* Copyright (c) 2014-2015 Merten Peetz
7-
*
8-
* Permission is hereby granted, free of charge, to any person obtaining a copy
9-
* of this software and associated documentation files (the "Software"), to deal
10-
* in the Software without restriction, including without limitation the rights
11-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12-
* copies of the Software, and to permit persons to whom the Software is
13-
* furnished to do so, subject to the following conditions:
14-
*
15-
* The above copyright notice and this permission notice shall be included in all
16-
* copies or substantial portions of the Software.
17-
*
18-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24-
* SOFTWARE.
25-
*/
26-
27-
/**
28-
* The interface for all classes that contain blocks.
29-
*
30-
* @author MorbZ
31-
*/
32-
public interface IBlockContainer {
33-
/**
34-
* Returns the transparency level of the block at given position. If there is no block
35-
* World.DEFAULT_TRANSPARENCY will be returned. 0 means fully opaque, 1 means fully transparent
36-
* and values > 1 mean transparent but the light level is decreased by n at this block.
37-
*
38-
* @param x The local X-coordinate
39-
* @param y The local Y-coordinate
40-
* @param z The local Z-coordinate
41-
* @return The transparency level
42-
*/
43-
public byte getTransparency(int x, int y, int z);
44-
45-
/**
46-
* Returns the sky light level of the block at given position. If there is no block
47-
* World.DEFAULT_SKY_LIGHT will be returned.
48-
*
49-
* @param x The local X-coordinate
50-
* @param y The local Y-coordinate
51-
* @param z The local Z-coordinate
52-
* @return The transparency level
53-
*/
54-
public byte getSkyLight(int x, int y, int z);
55-
56-
/**
57-
* Sets the sky light level of the block at given position.
58-
*
59-
* @param x The local X-coordinate
60-
* @param y The local Y-coordinate
61-
* @param z The local Z-coordinate
62-
* @param light The sky light level
63-
*/
64-
public void setSkyLight(int x, int y, int z, byte light);
65-
}
1+
package net.morbz.minecraft.world;
2+
3+
/*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2014-2015 Merten Peetz
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in all
16+
* copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24+
* SOFTWARE.
25+
*/
26+
27+
/**
28+
* The interface for all classes that contain blocks.
29+
*
30+
* @author MorbZ
31+
*/
32+
public interface IBlockContainer {
33+
/**
34+
* Returns the sky light level of the block at given position. If there is no block
35+
* World.DEFAULT_SKY_LIGHT will be returned.
36+
*
37+
* @param x The local X-coordinate
38+
* @param y The local Y-coordinate
39+
* @param z The local Z-coordinate
40+
* @return The sky light level
41+
*/
42+
public byte getSkyLight(int x, int y, int z);
43+
44+
/**
45+
* Returns the sky light level of a block that is out of bounds of the child block container.
46+
*
47+
* @param child The child block container
48+
* @param childX The local X-coordinate
49+
* @param childY The local Y-coordinate
50+
* @param childZ The local Z-coordinate
51+
* @return The sky light level
52+
*/
53+
public byte getSkyLightFromParent(IBlockContainer child, int childX, int childY, int childZ);
54+
55+
/**
56+
* Spreads the skylight. For each block that has the given light level it's adjacent blocks will
57+
* be lit if their current light level is lower.
58+
*
59+
* @param light The light level
60+
*/
61+
public void spreadSkyLight(byte light);
62+
}

0 commit comments

Comments
 (0)