Exemple #1
0
void	Chunk::fillTiles(const ChunkData &packet)
{
  unsigned int	index = 0;
  unsigned int	chunkLength = Chunk::height * Chunk::width;
  const google::protobuf::RepeatedField<uint32> &fgTile = packet.fgtilecode();
  const google::protobuf::RepeatedField<uint32> &bgTile = packet.bgtilecode();
  const google::protobuf::RepeatedField<uint32> &fgNumber = packet.fgnumber();
  const google::protobuf::RepeatedField<uint32> &bgNumber = packet.bgnumber();
  unsigned int	fgCounter = 0;
  unsigned int	bgCounter = 0;
  uint32	fgTileCounter = 0;
  uint32	bgTileCounter = 0;

  std::cout << "Filling chunk at pos " << _pos.x << " " << _pos.y << std::endl;
  for (index = 0; index < chunkLength; ++index)
    {
      if (fgTileCounter >= fgNumber.Get(fgCounter))
	{
	  fgTileCounter = 0;
	  ++fgCounter;
	}
      if (bgTileCounter >= bgNumber.Get(bgCounter))
	{
	  bgTileCounter = 0;
	  ++bgCounter;
	}
      _bgTiles[index] = tile(static_cast<TileType>(bgTile.Get(bgCounter)));
      _tiles[index] = tile(static_cast<TileType>(fgTile.Get(fgCounter)));
      ++fgTileCounter;
      ++bgTileCounter;
    }
  _generated = true;
}
Exemple #2
0
void Renderer::draw()
{
	//int dw = al_get_display_width(dpy_);
   //int dh = al_get_display_height(dpy_);

	ALLEGRO_TRANSFORM trans;
	al_identity_transform(&trans);

	al_compose_transform(&trans, &camera_transform_);
	al_rotate_transform_3d(&trans, 1.0, 0.0, 0.0, rx_look);

	setupProjection(&trans);
	al_identity_transform(&trans);


	al_use_transform(&trans);

	getWorldPos(camera_pos_);

	al_copy_transform(&cur3d_transform_, al_get_current_transform());

	glEnable(GL_DEPTH_TEST);
	// Accept fragment if it closer to the camera than the former one
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_CULL_FACE);
	glFrontFace(GL_CCW);
	glEnable(GL_ALPHA_TEST);

	if(!setShader(SHADER_DEFAULT))
	{
		NBT_Debug("failed to set default shader");
	}

	glBindVertexArray(vao_);

	resManager_->setAtlasUniforms();

	for(auto &it: chunkData_)
	{
		ChunkData *cd = it.second;

		ALLEGRO_TRANSFORM ctrans;
		al_identity_transform(&ctrans);
		al_translate_transform_3d(&ctrans, cd->x()*15.0, 0.0, cd->z()*15.0);
		al_use_transform(&ctrans);

		cd->draw(&ctrans);
	}

	glBindVertexArray(0);

	glDisable(GL_DEPTH_TEST);
	glDisable(GL_CULL_FACE);

	//drawSelection();

	resManager_->unsetAtlasUniforms();
}
Exemple #3
0
    /**
     * @brief Loads the next chunk.
     *
     * If the current chunk was the last chunk in the array a new chunk is created.
     * Otherwise the old chunk is reset and loaded as current chunk.
     *
     * Always the position of the nested chunk vector is stored.
     */
    inline void nextChunk() {
      curChunk->store();

      curChunkIndex += 1;
      if(chunks.size() == curChunkIndex) {
        curChunk = new ChunkData(chunkSize);
        chunks.push_back(curChunk);
        positions.push_back(nested.getPosition());
      } else {
        curChunk = chunks[curChunkIndex];
        curChunk->reset();
        positions[curChunkIndex] = nested.getPosition();
      }
    }
Exemple #4
0
    /**
     * @brief Resets the chunk vector to the given position.
     *
     * This method will call reset on all chunks which are behind the
     * given position.
     *
     * It calls also reset on the nested chunk vector.
     *
     * @param pos   The position to reset to.
     */
    void reset(const Position& pos) {
      assert(pos.chunk < chunks.size());
      assert(pos.data < chunkSize);

      for(size_t i = curChunkIndex; i > pos.chunk; --i) {
        chunks[i]->reset();
      }

      curChunk = chunks[pos.chunk];
      curChunk->load();
      curChunk->setUsedSize(pos.data);
      curChunkIndex = pos.chunk;

      nested.reset(pos.inner);
    }
Exemple #5
0
    /**
     * @brief Release all the memory, that the chunk vector has acquired.
     *
     * Reverts the chunk vector into its initial state after the construction.
     * Only the memory of one chunk stays allocated.
     */
    void resetHard() {
      for(size_t i = 1; i < chunks.size(); ++i) {
        delete chunks[i];
      }

      chunks.resize(1);
      positions.resize(1);
      curChunk = chunks[0];
      curChunk->load();

      curChunk->setUsedSize(0);
      curChunkIndex = 0;

      nested->resetHard();
    }
Exemple #6
0
    /**
     * @brief Checks if the current chunk has enough items left.
     *
     * If the chunk has not enough items left, the next chunk is
     * loaded.
     *
     * @param items   The maximum number of items to store.
     */
    inline void reserveItems(const size_t items) {
      assert(items <= chunkSize);

      if(chunkSize < curChunk->getUsedSize() + items) {
        nextChunk();
      }
    }
Exemple #7
0
    /**
     * @brief Checks if the current chunk has enough items left.
     *
     * If the chunk has not enough items left, the next chunk is
     * loaded.
     *
     * @param items   The maximum number of items to store.
     */
    CODI_INLINE void reserveItems(const size_t items) {
      codiAssert(items <= chunkSize);

      if(chunkSize < curChunk->getUsedSize() + items) {
        nextChunk();
      }
    }
Exemple #8
0
    /**
     * @brief Get the total number of data items used.
     * @return The number of data items used in all chunks.
     */
    inline size_t getDataSize() {
      size_t size = curChunk->getUsedSize();
      if(getNumChunks() != 0) {
        size += (getNumChunks() - 1) * chunkSize;
      }

      return size;
    }
Exemple #9
0
ChunkData* Region::getChunkData(Int2 pos)
{
	if(mChunks.find(pos)==mChunks.end())
	{
		int offset = getOffset(pos);
		//cout << offset << endl;
		if(offset==-1)
		{
			mChunks[pos] = new ChunkData(pos);
			cout << "Missing Chunk " << pos.first <<" " << pos.second << endl;
			return mChunks[pos];
		}
		mRegionFile.seekg(offset,mRegionFile.beg);
		int length = NBT::ReadSwap<int32_t>(mRegionFile);
		uint8_t format = NBT::Read<uint8_t>(mRegionFile);
		NBT::TagCompound* tag = NBT::ReadNBTFromZlibStream(mRegionFile);
		ChunkData* chunk = new ChunkData(pos);
		chunk->loadFromNBT(tag);
		mChunks[pos] = chunk;
		delete tag;
	}
	return mChunks[pos];
}
Exemple #10
0
bool ChunkMesh::isAirNearBlockFace(const ChunkData & chunkData, int blockX, int blockY, int blockZ, BlockFace face)
{
    switch(face)
    {
    case BlockFace::North:
        return blockZ == 0 || chunkData.getBlock(blockX, blockY, blockZ - 1) == 0;
    case BlockFace::South:
        return blockZ == chunkData.getZSize() - 1 || chunkData.getBlock(blockX, blockY, blockZ + 1) == 0;
    case BlockFace::West:
        return blockX == 0 || chunkData.getBlock(blockX - 1, blockY, blockZ) == 0;
    case BlockFace::East:
        return blockX == chunkData.getXSize() - 1 || chunkData.getBlock(blockX + 1, blockY, blockZ) == 0;
    case BlockFace::Bottom:
        return blockY == 0 || chunkData.getBlock(blockX, blockY - 1, blockZ) == 0;
    case BlockFace::Top:
        return blockY == chunkData.getYSize() - 1 || chunkData.getBlock(blockX, blockY + 1, blockZ) == 0;
    default:
        return false;
    }
}
Exemple #11
0
 CODI_INLINE void setDataAndMove(const Data& ... data) {
   // this method should only be called if reserveItems has been called
   curChunk->setDataAndMove(data...);
 }
Exemple #12
0
ChunkMesh ChunkMesh::createFromChunkData(const ChunkData & chunkData)
{
    ChunkMesh mesh;
    mesh.m_isValid = true;

    unsigned int indicesOffset = 0;

    for(int y = 0; y < chunkData.getYSize(); ++y)
    {
        for(int z = 0; z < chunkData.getZSize(); ++z)
        {
            for(int x = 0; x < chunkData.getXSize(); ++x)
            {
                const int blockCode = chunkData.getBlock(x, y, z);
                if(blockCode != 0)
                {
                    if(isAirNearBlockFace(chunkData, x, y, z, BlockFace::North))
                    {
                        mesh.m_vertices.insert(
                            mesh.m_vertices.end(),
                            {
                                1.0f + x, 0.0f + y, 0.0f + z,  0.0f, 0.0f,
                                0.0f + x, 0.0f + y, 0.0f + z,  0.0f, 1.0f,
                                0.0f + x, 1.0f + y, 0.0f + z,  1.0f, 1.0f,
                                1.0f + x, 1.0f + y, 0.0f + z,  1.0f, 0.0f
                            }
                        );

                        mesh.m_indices.insert(
                            mesh.m_indices.end(),
                            {
                                0 + indicesOffset, 1 + indicesOffset, 2 + indicesOffset,
                                0 + indicesOffset, 2 + indicesOffset, 3 + indicesOffset
                            }
                        );

                        indicesOffset += 4;
                    }
                    if(isAirNearBlockFace(chunkData, x, y, z, BlockFace::South))
                    {
                        mesh.m_vertices.insert(
                            mesh.m_vertices.end(),
                            {
                                0.0f + x, 0.0f + y, 1.0f + z,  0.0f, 0.0f,
                                0.0f + x, 1.0f + y, 1.0f + z,  0.0f, 1.0f,
                                1.0f + x, 1.0f + y, 1.0f + z,  1.0f, 1.0f,
                                1.0f + x, 0.0f + y, 1.0f + z,  1.0f, 0.0f
                            }
                        );

                        mesh.m_indices.insert(
                            mesh.m_indices.end(),
                            {
                                0 + indicesOffset, 1 + indicesOffset, 2 + indicesOffset,
                                0 + indicesOffset, 2 + indicesOffset, 3 + indicesOffset
                            }
                        );

                        indicesOffset += 4;
                    }
                    if(isAirNearBlockFace(chunkData, x, y, z, BlockFace::West))
                    {
                        mesh.m_vertices.insert(
                            mesh.m_vertices.end(),
                            {
                                0.0f + x, 0.0f + y, 0.0f + z,  0.0f, 0.0f,
                                0.0f + x, 1.0f + y, 0.0f + z,  0.0f, 1.0f,
                                0.0f + x, 1.0f + y, 1.0f + z,  1.0f, 1.0f,
                                0.0f + x, 0.0f + y, 1.0f + z,  1.0f, 0.0f
                            }
                        );

                        mesh.m_indices.insert(
                            mesh.m_indices.end(),
                            {
                                0 + indicesOffset, 1 + indicesOffset, 2 + indicesOffset,
                                0 + indicesOffset, 2 + indicesOffset, 3 + indicesOffset
                            }
                        );

                        indicesOffset += 4;
                    }
                    if(isAirNearBlockFace(chunkData, x, y, z, BlockFace::East))
                    {
                        mesh.m_vertices.insert(
                            mesh.m_vertices.end(),
                            {
                                1.0f + x, 0.0f + y, 1.0f + z,  0.0f, 0.0f,
                                1.0f + x, 1.0f + y, 1.0f + z,  0.0f, 1.0f,
                                1.0f + x, 1.0f + y, 0.0f + z,  1.0f, 1.0f,
                                1.0f + x, 0.0f + y, 0.0f + z,  1.0f, 0.0f
                            }
                        );

                        mesh.m_indices.insert(
                            mesh.m_indices.end(),
                            {
                                0 + indicesOffset, 1 + indicesOffset, 2 + indicesOffset,
                                0 + indicesOffset, 2 + indicesOffset, 3 + indicesOffset
                            }
                        );

                        indicesOffset += 4;
                    }
                    if(isAirNearBlockFace(chunkData, x, y, z, BlockFace::Bottom))
                    {
                        mesh.m_vertices.insert(
                            mesh.m_vertices.end(),
                            {
                                0.0f + x, 0.0f + y, 0.0f + z,  0.0f, 0.0f,
                                0.0f + x, 0.0f + y, 1.0f + z,  0.0f, 1.0f,
                                1.0f + x, 0.0f + y, 1.0f + z,  1.0f, 1.0f,
                                1.0f + x, 0.0f + y, 0.0f + z,  1.0f, 0.0f
                            }
                        );

                        mesh.m_indices.insert(
                            mesh.m_indices.end(),
                            {
                                0 + indicesOffset, 1 + indicesOffset, 2 + indicesOffset,
                                0 + indicesOffset, 2 + indicesOffset, 3 + indicesOffset
                            }
                        );

                        indicesOffset += 4;
                    }
                    if(isAirNearBlockFace(chunkData, x, y, z, BlockFace::Top))
                    {
                        mesh.m_vertices.insert(
                            mesh.m_vertices.end(),
                            {
                                0.0f + x, 1.0f + y, 1.0f + z,  0.0f, 0.0f,
                                0.0f + x, 1.0f + y, 0.0f + z,  0.0f, 1.0f,
                                1.0f + x, 1.0f + y, 0.0f + z,  1.0f, 1.0f,
                                1.0f + x, 1.0f + y, 1.0f + z,  1.0f, 0.0f
                            }
                        );

                        mesh.m_indices.insert(
                            mesh.m_indices.end(),
                            {
                                0 + indicesOffset, 1 + indicesOffset, 2 + indicesOffset,
                                0 + indicesOffset, 2 + indicesOffset, 3 + indicesOffset
                            }
                        );

                        indicesOffset += 4;
                    }
                }
            }
        }
    }

    return mesh;
}
Exemple #13
0
 /**
  * @brief Get the position of the chunk vector and the nested vectors.
  * @return The position of the chunk vector.
  */
 inline Position getPosition() {
   return Position(curChunkIndex, curChunk->getUsedSize(), nested.getPosition());
 }
Exemple #14
0
 /**
  * @brief The position inside the data of the current chunk.
  * @return The current position in the current chunk.
  */
 inline size_t getChunkPosition() {
   return curChunk->getUsedSize();
 }
Exemple #15
0
ChunkData *ChunkData::Create(Chunk *chunk, ResourceManager *resourceManager)
{
	const uint32_t DATA_VTX_COUNT = MAX_VERTS / MAX_SLICES;
	CustomVertex *data = (CustomVertex*)malloc(sizeof(CustomVertex) * DATA_VTX_COUNT);
	if(!data)
		return nullptr;
		
	memset(data, 0, DATA_VTX_COUNT * sizeof(CustomVertex));
	
	uint32_t total_size = 0;
	
	// TODO: maybe allow putting more than one section per slice if we end up with more than 16 sections.
	//  currently minecraft only uses 16 sections per chunk.
	//assert(num_sections <= MAX_SLICES);

	int32_t x_off = chunk->x() * 16;
	int32_t z_off = chunk->z() * 16;
	
	ChunkData *cdata = new ChunkData(chunk->x(), chunk->z());
	
	CustomVertex *dptr = data; // reset dptr, reuse data memory.
	
	for(uint32_t i = 0; i < chunk->sectionCount(); i++)
	{
		ChunkSection *section = chunk->getSection(i);
		if(!section)
			continue;
		
		//NBT_Debug("new section[%i]: %p", i, section);
		
		int32_t y = section->y() * 16;
		//int32_t y = section_y * 16;
		
#ifdef VIEWER_USE_MORE_VBOS
		dptr = data;
		total_size = 0;
#endif
		
		for(int dy = 0; dy < 16; dy++)
		{
			for(int dz = 0; dz < 16; dz++)
			{
				for(int dx = 0; dx < 16; dx++)
				{
					BlockAddress baddr;
					
					if(!chunk->getBlockAddress(x_off + dx, y + dy, z_off + dz, &baddr))
					{
						NBT_Debug("failed to find block %i, %i, %i", x_off + dx, y + dy, z_off + dz);
						assert(nullptr);
						continue;
					}
					
					//NBT_Debug("block %i,%i,%i: %s", x_off+dx, y+dy, z_off+dz, baddr.toString().c_str());
					
					BlockInfo bi;
					chunk->getBlockInfo(baddr, &bi);
					
					//NBT_Debug("blockInfo: %i:%i:%s", bi.id, bi.data, bi.state_name);
					
					Resource::ID rid = resourceManager->getModelVariant(bi);
					if(rid == Resource::INVALID_ID)
					{
						//NBT_Debug("failed to get model %i:%i:%s", bi.id, bi.data, bi.state_name);
						continue;
					}
					
					//if(bi.id != BLOCK_AIR && bi.id != BLOCK_BARRIER)
					//	NBT_Debug("block:%i:%i %s", bi.id, bi.data, bi.state_name);
					
					ResourceModelVariant *var = resourceManager->getModelVariantResource(rid);
					uint32_t vertex_count = var->getVertexCount();
					CustomVertex *verticies = var->getVertexData();
					
					for(uint32_t i = 0; i < vertex_count; i++)
					{
						CustomVertex &v = verticies[i], &cv = dptr[i];
						float xoff = cdata->x() + dx, yoff = y + dy, zoff = cdata->z() + dz;
						
						cv.pos = { v.pos.f1 + xoff, v.pos.f2 + yoff, v.pos.f3 + zoff };
						//cv.txcoord = { (v.txcoord.f1 * tx_xfact + tx_x), 1-(v.txcoord.f2 * tx_yfact + tx_y) };
						cv.txcoord = { v.txcoord.f1 , 1-v.txcoord.f2 };
						// { 0.25 + 0.25 * v.txcoord.f1,  0.25 + 0.25 * v.txcoord.f2 }; 
						//NBT_Debug("tex: %f, %f", cv.txcoord.f1, cv.txcoord.f2);
						cv.tx_page = v.tx_page;
						cv.color = v.color;
					}
					
					dptr += vertex_count;
					total_size += vertex_count;
				}
			}
		}
		
#ifdef VIEWER_USE_MORE_VBOS
		if(total_size > 0)
			if(!cdata->fillSlice(section->y(), data, total_size))
				NBT_Warn("failed to fill slice %i???", y);
#endif
		
	}
	
#ifndef VIEWER_USE_MORE_VBOS
	if(total_size)
		if(!cdata->fillSlice(0, data, total_size))
			NBT_Warn("failed to fill chunk data");
#endif
	
	free(data);
	
	return cdata;
}
Exemple #16
0
 CODI_INLINE void getDataPointer(Pointers* &... pointers) {
   curChunk->dataPointer(curChunk->usedSize, pointers...);
 }
Exemple #17
0
 /**
  * @brief The position inside the data of the current chunk.
  * @return The current position in the current chunk.
  */
 CODI_INLINE size_t getChunkPosition() const {
   return curChunk->getUsedSize();
 }
Exemple #18
0
 /**
  * @brief Get the position of the chunk vector and the nested vectors.
  * @return The position of the chunk vector.
  */
 CODI_INLINE Position getPosition() const {
   return Position(curChunkIndex, curChunk->getUsedSize(), nested->getPosition());
 }
Exemple #19
0
std::string		World::serialize(const Vector2i &chunkId)
{
  ProtocolMessage	msg;
  ChunkData		*chunkData = new ChunkData;
  VectorInt		*vecInt;
  std::string		serialized;
  Chunk			*chunk;
  unsigned int		fgcont = 0;
  unsigned int		bgcont = 0;
  TileType		fgtile;
  TileType		bgtile;
  TileType		oldfgtile;
  TileType		oldbgtile;

  if ((chunk = getChunk(chunkId)) != nullptr)
    {
      for (unsigned int y = 0; y < Chunk::height; ++y)
	{
	  for (unsigned int x = 0; x < Chunk::width; ++x)
	    {
	      fgtile = chunk->getTile(x, y);
	      bgtile = chunk->getBgTile(x, y);
	      if (x == 0 && y == 0)
		{
		  oldfgtile = fgtile;
		  oldbgtile = bgtile;
		}
	      else
		{
		  if (fgtile != oldfgtile)
		    {
		      chunkData->add_fgnumber(fgcont);
		      chunkData->add_fgtilecode(static_cast<unsigned int>(oldfgtile));
		      fgcont = 0;
		      oldfgtile = fgtile;
		    }
		  if (bgtile != oldbgtile)
		    {
		      chunkData->add_bgnumber(bgcont);
		      chunkData->add_bgtilecode(static_cast<unsigned int>(oldbgtile));
		      bgcont = 0;
		      oldbgtile = bgtile;
		    }
		}
	      ++fgcont;
	      ++bgcont;
	    }
	}
    }
  chunkData->add_bgnumber(bgcont);
  chunkData->add_bgtilecode(static_cast<unsigned int>(oldbgtile));
  chunkData->add_fgnumber(fgcont);
  chunkData->add_fgtilecode(static_cast<unsigned int>(oldfgtile));
  vecInt = new VectorInt;
  vecInt->set_x(chunkId.x);
  vecInt->set_y(chunkId.y);
  chunkData->set_allocated_id(vecInt);
  msg.set_content(ProtocolMessage::CHUNK);
  msg.set_allocated_chunkdata(chunkData);
  msg.SerializeToString(&serialized);
  return serialized;
}
Exemple #20
0
 /**
  * @brief Sets the data and increases the used chunk data by one.
  *
  * This method should only be called if 'reserveItems' was called
  * beforehand with enough items to accommodate to all calls to this
  * method.
  *
  * @param data  The data set to the current position in the chunk.
  */
 inline void setDataAndMove(const typename ChunkData::DataValues& data) {
   // this method should only be called if reserveItems has been called
   curChunk->setDataAndMove(data);
 }