mirror of
https://github.com/minetest/minetest.git
synced 2024-12-23 14:42:24 +01:00
Optimize Mapgen::updateLighting(), add setLighting()
This commit is contained in:
parent
f5ab056b38
commit
1f1ad9fd23
117
src/mapgen.cpp
117
src/mapgen.cpp
@ -51,21 +51,19 @@ FlagDesc flagdesc_mapgen[] = {
|
||||
|
||||
void Mapgen::updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nmax) {
|
||||
bool isliquid, wasliquid;
|
||||
u32 i;
|
||||
v3s16 em = vm->m_area.getExtent();
|
||||
|
||||
for (s16 z = nmin.Z; z <= nmax.Z; z++) {
|
||||
for (s16 x = nmin.X; x <= nmax.X; x++) {
|
||||
v2s16 p2d(x, z);
|
||||
wasliquid = true;
|
||||
v3s16 em = vm->m_area.getExtent();
|
||||
i = vm->m_area.index(v3s16(p2d.X, nmax.Y, p2d.Y));
|
||||
|
||||
|
||||
u32 i = vm->m_area.index(x, nmax.Y, z);
|
||||
for (s16 y = nmax.Y; y >= nmin.Y; y--) {
|
||||
isliquid = ndef->get(vm->m_data[i]).isLiquid();
|
||||
|
||||
// there was a change between liquid and nonliquid, add to queue
|
||||
if (isliquid != wasliquid)
|
||||
trans_liquid->push_back(v3s16(p2d.X, y, p2d.Y));
|
||||
trans_liquid->push_back(v3s16(x, y, z));
|
||||
|
||||
wasliquid = isliquid;
|
||||
vm->m_area.add_y(em, i, -1);
|
||||
@ -75,7 +73,108 @@ void Mapgen::updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nm
|
||||
}
|
||||
|
||||
|
||||
void Mapgen::setLighting(v3s16 nmin, v3s16 nmax, u8 light) {
|
||||
ScopeProfiler sp(g_profiler, "EmergeThread: mapgen lighting update", SPT_AVG);
|
||||
VoxelArea a(nmin - v3s16(1,0,1) * MAP_BLOCKSIZE,
|
||||
nmax + v3s16(1,0,1) * MAP_BLOCKSIZE);
|
||||
|
||||
for (int z = a.MinEdge.Z; z <= a.MaxEdge.Z; z++) {
|
||||
for (int y = a.MinEdge.Y; y <= a.MaxEdge.Y; y++) {
|
||||
u32 i = vm->m_area.index(a.MinEdge.X, y, z);
|
||||
for (int x = a.MinEdge.X; x <= a.MaxEdge.X; x++, i++)
|
||||
vm->m_data[i].param1 = light;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Mapgen::lightSpread(VoxelArea &a, v3s16 p, u8 light) {
|
||||
if (light <= 1 || !a.contains(p))
|
||||
return;
|
||||
|
||||
u32 vi = vm->m_area.index(p);
|
||||
MapNode &nn = vm->m_data[vi];
|
||||
|
||||
light--;
|
||||
// should probably compare masked, but doesn't seem to make a difference
|
||||
if (light <= nn.param1 || !ndef->get(nn).light_propagates)
|
||||
return;
|
||||
|
||||
nn.param1 = light;
|
||||
|
||||
lightSpread(a, p + v3s16(0, 0, 1), light);
|
||||
lightSpread(a, p + v3s16(0, 1, 0), light);
|
||||
lightSpread(a, p + v3s16(1, 0, 0), light);
|
||||
lightSpread(a, p - v3s16(0, 0, 1), light);
|
||||
lightSpread(a, p - v3s16(0, 1, 0), light);
|
||||
lightSpread(a, p - v3s16(1, 0, 0), light);
|
||||
}
|
||||
|
||||
|
||||
void Mapgen::updateLighting(v3s16 nmin, v3s16 nmax) {
|
||||
VoxelArea a(nmin - v3s16(1,0,1) * MAP_BLOCKSIZE,
|
||||
nmax + v3s16(1,0,1) * MAP_BLOCKSIZE);
|
||||
bool block_is_underground = (water_level >= nmax.Y);
|
||||
|
||||
ScopeProfiler sp(g_profiler, "EmergeThread: mapgen lighting update", SPT_AVG);
|
||||
//TimeTaker t("updateLighting");
|
||||
|
||||
// first, send vertical rays of sunshine downward
|
||||
v3s16 em = vm->m_area.getExtent();
|
||||
for (int z = a.MinEdge.Z; z <= a.MaxEdge.Z; z++) {
|
||||
for (int x = a.MinEdge.X; x <= a.MaxEdge.X; x++) {
|
||||
// see if we can get a light value from the overtop
|
||||
u32 i = vm->m_area.index(x, a.MaxEdge.Y + 1, z);
|
||||
if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
|
||||
if (block_is_underground)
|
||||
continue;
|
||||
} else if ((vm->m_data[i].param1 & 0x0F) != LIGHT_SUN) {
|
||||
continue;
|
||||
}
|
||||
vm->m_area.add_y(em, i, -1);
|
||||
|
||||
for (int y = a.MaxEdge.Y; y >= a.MinEdge.Y; y--) {
|
||||
MapNode &n = vm->m_data[i];
|
||||
if (!ndef->get(n).sunlight_propagates)
|
||||
break;
|
||||
n.param1 = LIGHT_SUN;
|
||||
vm->m_area.add_y(em, i, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now spread the sunlight and light up any sources
|
||||
for (int z = a.MinEdge.Z; z <= a.MaxEdge.Z; z++) {
|
||||
for (int y = a.MinEdge.Y; y <= a.MaxEdge.Y; y++) {
|
||||
u32 i = vm->m_area.index(a.MinEdge.X, y, z);
|
||||
for (int x = a.MinEdge.X; x <= a.MaxEdge.X; x++, i++) {
|
||||
MapNode &n = vm->m_data[i];
|
||||
if (n.getContent() == CONTENT_IGNORE ||
|
||||
!ndef->get(n).light_propagates)
|
||||
continue;
|
||||
|
||||
u8 light_produced = ndef->get(n).light_source & 0x0F;
|
||||
if (light_produced)
|
||||
n.param1 = light_produced;
|
||||
|
||||
u8 light = n.param1 & 0x0F;
|
||||
if (light) {
|
||||
lightSpread(a, v3s16(x, y, z + 1), light);
|
||||
lightSpread(a, v3s16(x, y + 1, z ), light);
|
||||
lightSpread(a, v3s16(x + 1, y, z ), light);
|
||||
lightSpread(a, v3s16(x, y, z - 1), light);
|
||||
lightSpread(a, v3s16(x, y - 1, z ), light);
|
||||
lightSpread(a, v3s16(x - 1, y, z ), light);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//printf("updateLighting: %dms\n", t.stop());
|
||||
}
|
||||
|
||||
|
||||
void Mapgen::updateLightingOld(v3s16 nmin, v3s16 nmax) {
|
||||
enum LightBank banks[2] = {LIGHTBANK_DAY, LIGHTBANK_NIGHT};
|
||||
|
||||
VoxelArea a(nmin - v3s16(1,0,1) * MAP_BLOCKSIZE,
|
||||
@ -84,14 +183,16 @@ void Mapgen::updateLighting(v3s16 nmin, v3s16 nmax) {
|
||||
bool sunlight = !block_is_underground;
|
||||
|
||||
ScopeProfiler sp(g_profiler, "EmergeThread: mapgen lighting update", SPT_AVG);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
enum LightBank bank = banks[i];
|
||||
std::set<v3s16> light_sources;
|
||||
std::map<v3s16, u8> unlight_from;
|
||||
std::set<v3s16> light_sources;
|
||||
std::map<v3s16, u8> unlight_from;
|
||||
|
||||
voxalgo::clearLightAndCollectSources(*vm, a, bank, ndef,
|
||||
light_sources, unlight_from);
|
||||
voxalgo::propagateSunlight(*vm, a, sunlight, light_sources, ndef);
|
||||
|
||||
vm->unspreadLight(bank, unlight_from, light_sources, ndef);
|
||||
vm->spreadLight(bank, light_sources, ndef);
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ class ManualMapVoxelManipulator;
|
||||
class VoxelManipulator;
|
||||
class INodeDefManager;
|
||||
class BlockMakeData;
|
||||
class VoxelArea;
|
||||
|
||||
struct MapgenParams {
|
||||
std::string mg_name;
|
||||
@ -76,7 +77,10 @@ public:
|
||||
INodeDefManager *ndef;
|
||||
|
||||
void updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nmax);
|
||||
void setLighting(v3s16 nmin, v3s16 nmax, u8 light);
|
||||
void lightSpread(VoxelArea &a, v3s16 p, u8 light);
|
||||
void updateLighting(v3s16 nmin, v3s16 nmax);
|
||||
void updateLightingOld(v3s16 nmin, v3s16 nmax);
|
||||
|
||||
virtual void makeChunk(BlockMakeData *data) {};
|
||||
virtual int getGroundLevelAtPoint(v2s16 p) = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user