4 VoxelManipulator::VoxelManipulator():
9 VoxelManipulator::~VoxelManipulator()
15 void VoxelManipulator::addArea(VoxelArea area)
17 if(area.getExtent() == v3s16(0,0,0))
22 if(m_area.getExtent() == v3s16(0,0,0))
29 new_area.addArea(area);
32 if(new_area == m_area)
35 s32 new_size = new_area.getVolume();
37 /*dstream<<"adding area ";
39 dstream<<", old area ";
40 m_area.print(dstream);
41 dstream<<", new area ";
42 new_area.print(dstream);
43 dstream<<", new_size="<<new_size;
46 // Allocate and clear new data
48 new_data = new MapNode[new_size];
49 for(s32 i=0; i<new_size; i++)
51 new_data[i].d = MATERIAL_IGNORE;
56 for(s32 z=m_area.MinEdge.Z; z<=m_area.MaxEdge.Z; z++)
57 for(s32 y=m_area.MinEdge.Y; y<=m_area.MaxEdge.Y; y++)
58 for(s32 x=m_area.MinEdge.X; x<=m_area.MaxEdge.X; x++)
60 new_data[new_area.index(z,y,x)] = m_data[m_area.index(x,y,z)];
65 MapNode *old_data = m_data;
70 void VoxelManipulator::print(std::ostream &o)
72 v3s16 em = m_area.getExtent();
73 v3s16 of = m_area.MinEdge;
74 o<<"size: "<<em.X<<"x"<<em.Y<<"x"<<em.Z
75 <<" offset: ("<<of.X<<","<<of.Y<<","<<of.Z<<")"<<std::endl;
77 for(s32 y=m_area.MinEdge.Y; y<=m_area.MaxEdge.Y; y++)
79 if(em.X >= 3 && em.Y >= 3)
81 if(y==m_area.MinEdge.Y+0) o<<"y x-> ";
82 if(y==m_area.MinEdge.Y+1) o<<"| ";
83 if(y==m_area.MinEdge.Y+2) o<<"V ";
86 for(s32 z=m_area.MinEdge.Z; z<=m_area.MaxEdge.Z; z++)
88 for(s32 x=m_area.MinEdge.X; x<=m_area.MaxEdge.X; x++)
90 u8 m = m_data[m_area.index(x,y,z)].d;
92 if(m == MATERIAL_IGNORE)
104 void VoxelManipulator::interpolate(VoxelArea area)
106 VoxelArea emerge_area = area;
107 emerge_area.MinEdge -= v3s16(1,1,1);
108 emerge_area.MaxEdge += v3s16(1,1,1);
111 SharedBuffer<u8> buf(area.getVolume());
113 for(s32 z=area.MinEdge.Z; z<=area.MaxEdge.Z; z++)
114 for(s32 y=area.MinEdge.Y; y<=area.MaxEdge.Y; y++)
115 for(s32 x=area.MinEdge.X; x<=area.MaxEdge.X; x++)
129 //const v3s16 *dirs = g_26dirs;
133 u8 m = MATERIAL_IGNORE;
135 for(s16 i=0; i<8; i++)
136 //for(s16 i=0; i<26; i++)
138 v3s16 p2 = p + dirs[i];
140 MapNode &n = m_data[m_area.index(p2)];
141 if(n.d == MATERIAL_IGNORE)
144 airness += (n.d == MATERIAL_AIR) ? 1 : -1;
147 if(m == MATERIAL_IGNORE && n.d != MATERIAL_AIR)
151 // 1 if air, 0 if not
152 buf[area.index(p)] = airness > -total/2 ? MATERIAL_AIR : m;
153 //buf[area.index(p)] = airness > -total ? MATERIAL_AIR : m;
154 //buf[area.index(p)] = airness >= -7 ? MATERIAL_AIR : m;
157 for(s32 z=area.MinEdge.Z; z<=area.MaxEdge.Z; z++)
158 for(s32 y=area.MinEdge.Y; y<=area.MaxEdge.Y; y++)
159 for(s32 x=area.MinEdge.X; x<=area.MaxEdge.X; x++)
162 m_data[m_area.index(p)].d = buf[area.index(p)];
167 void VoxelManipulator::blitFromNodeContainer
168 (v3s16 p_from, v3s16 p_to, v3s16 size, NodeContainer *c)
170 VoxelArea a_to(p_to, p_to+size-v3s16(1,1,1));
172 for(s16 z=0; z<size.Z; z++)
173 for(s16 y=0; y<size.Y; y++)
174 for(s16 x=0; x<size.X; x++)
178 MapNode n = c->getNode(p_from + p);
179 m_data[m_area.index(p_to + p)] = n;
181 catch(InvalidPositionException &e)
186 MapNode n(MATERIAL_IGNORE);
188 n = c->getNode(p_from + p);
190 catch(InvalidPositionException &e)
193 m_data[m_area.index(p_to + p)] = n;*/
197 void VoxelManipulator::blitToNodeContainer
198 (v3s16 p_from, v3s16 p_to, v3s16 size, NodeContainer *c)
200 for(s16 z=0; z<size.Z; z++)
201 for(s16 y=0; y<size.Y; y++)
202 for(s16 x=0; x<size.X; x++)
206 MapNode &n = m_data[m_area.index(p_from + p)];
207 if(n.d == MATERIAL_IGNORE)
209 c->setNode(p_to + p, n);
211 catch(InvalidPositionException &e)
222 MapVoxelManipulator::MapVoxelManipulator(Map *map)
227 void MapVoxelManipulator::emerge(VoxelArea a)
229 v3s16 size = a.getExtent();
233 for(s16 z=0; z<size.Z; z++)
234 for(s16 y=0; y<size.Y; y++)
235 for(s16 x=0; x<size.X; x++)
239 MapNode n = m_map->getNode(a.MinEdge + p);
240 m_data[m_area.index(a.MinEdge + p)] = n;
242 catch(InvalidPositionException &e)
248 void MapVoxelManipulator::blitBack
249 (core::map<v3s16, MapBlock*> & modified_blocks)
252 Initialize block cache
255 MapBlock *block = NULL;
256 bool block_checked_in_modified = false;
258 for(s32 z=m_area.MinEdge.Z; z<=m_area.MaxEdge.Z; z++)
259 for(s32 y=m_area.MinEdge.Y; y<=m_area.MaxEdge.Y; y++)
260 for(s32 x=m_area.MinEdge.X; x<=m_area.MaxEdge.X; x++)
264 MapNode &n = m_data[m_area.index(p)];
265 if(n.d == MATERIAL_IGNORE)
268 v3s16 blockpos = getNodeBlockPos(p);
273 if(block == NULL || blockpos != blockpos_last){
274 block = m_map->getBlockNoCreate(blockpos);
275 blockpos_last = blockpos;
276 block_checked_in_modified = false;
279 // Calculate relative position in block
280 v3s16 relpos = p - blockpos * MAP_BLOCKSIZE;
282 // Don't continue if nothing has changed here
283 if(block->getNode(relpos) == n)
286 //m_map->setNode(m_area.MinEdge + p, n);
287 block->setNode(relpos, n);
290 Make sure block is in modified_blocks
292 if(block_checked_in_modified == false)
294 modified_blocks[blockpos] = block;
295 block_checked_in_modified = true;
298 catch(InvalidPositionException &e)