Beispiel #1
0
void World::loadRegion(const PolyVox::ConstVolumeProxy<PolyVox::Material8>& volData, const PolyVox::Region& region) {
    std::stringstream ss;
    ss << "Info: loadRegion() is loading region: " << region.getLowerCorner() << " -> " << region.getUpperCorner();
    Utils::log(ss.str());
    uint8_t material = 2;

    int lo_x = region.getLowerCorner().getX() +1;
    int lo_y = region.getLowerCorner().getY() +1;
    int lo_z = region.getLowerCorner().getZ() +1;

    int hi_x = 7;
    int hi_y = 3;
    int hi_z = 7;

    for (int x=lo_x; x<hi_x; ++x) {
        for (int y=lo_y; y<hi_y; ++y) {
            for (int z=lo_z; z<hi_z; ++z) {
                PolyVox::Material8 voxel = volData.getVoxelAt(x,y,z);
                voxel.setMaterial(material);
                volData.setVoxelAt(x,y,z, voxel);
            }
        }
    }

}
Beispiel #2
0
void VoxelTerrain::requestVolume(
  const PolyVox::ConstVolumeProxy<BYTE>& volume,
  const PolyVox::Region& region)
{
  float interval = 1;
  //std::cout << "Begin filling VoxelTerrain." << std::endl;
  for (float z = region.getLowerCorner().getZ();
       z <= region.getUpperCorner().getZ(); z+=interval) {
    for (float y = region.getLowerCorner().getY();
         y <= region.getUpperCorner().getY(); y+=interval) {
      for (float x = region.getLowerCorner().getX();
           x <= region.getUpperCorner().getX(); x+=interval) {
        //std::cout << x/region.getUpperCorner().getX() << std::endl;

        BYTE voxel_value = ground_cave_multiply.get(
          5*x/region.getUpperCorner().getX(),
          y/region.getUpperCorner().getY(),
          5*z/region.getUpperCorner().getZ())*255;
        
        // if (static_cast<double>(voxel_value) != 0)
        //   std::cout << static_cast<double>(voxel_value) << std::endl;

        volume.setVoxelAt(x, y, z, voxel_value);
      }
    }
  }
  //std::cout << "Done filling VoxelTerrain." << std::endl;
}
Beispiel #3
0
	virtual void pageIn(const PolyVox::Region& region, PagedVolume<MaterialDensityPair44>::Chunk* pChunk)
	{
		Perlin perlin(2, 2, 1, 234);

		for (int x = region.getLowerX(); x <= region.getUpperX(); x++)
		{
			for (int y = region.getLowerY(); y <= region.getUpperY(); y++)
			{
				float perlinVal = perlin.Get(x / static_cast<float>(255 - 1), y / static_cast<float>(255 - 1));
				perlinVal += 1.0f;
				perlinVal *= 0.5f;
				perlinVal *= 255;
				for (int z = region.getLowerZ(); z <= region.getUpperZ(); z++)
				{
					MaterialDensityPair44 voxel;
					if (z < perlinVal)
					{
						const int xpos = 50;
						const int zpos = 100;
						if ((x - xpos)*(x - xpos) + (z - zpos)*(z - zpos) < 200)
						{
							// tunnel
							voxel.setMaterial(0);
							voxel.setDensity(MaterialDensityPair44::getMinDensity());
						}
						else
						{
							// solid
							voxel.setMaterial(245);
							voxel.setDensity(MaterialDensityPair44::getMaxDensity());
						}
					}
					else
					{
						voxel.setMaterial(0);
						voxel.setDensity(MaterialDensityPair44::getMinDensity());
					}

					// Voxel position within a chunk always start from zero. So if a chunk represents region (4, 8, 12) to (11, 19, 15)
					// then the valid chunk voxels are from (0, 0, 0) to (7, 11, 3). Hence we subtract the lower corner position of the
					// region from the volume space position in order to get the chunk space position.
					pChunk->setVoxel(x - region.getLowerX(), y - region.getLowerY(), z - region.getLowerZ(), voxel);
				}
			}
		}
	}
	// This function encodes a Region as a 64-bit integer so that it can be used as a key to access chunk data in the SQLite database.
	// A region actually contains more than 64-bits of data so some has to be lost here. Specifically we assume that we already know
	// the size of the region (so we only have to encode it's lower corner and not its upper corner or extents), and we also restrict
	// the range of valid coordinates. A Region's coordinates are represented by 3-bits of data, but we only support converting to a key 
	// if every coordinate can be represented by 21 bits of data. This way we can fit three coordinates only 63 bits of data. This limits
	// the range of values to +/- 2^20, which is enough for our purposes.
	uint64_t regionToKey(const PolyVox::Region& region)
	{
		// Cast to unsigned values so that bit shifting works predictably.
		uint32_t x = static_cast<uint32_t>(region.getLowerX());
		uint32_t y = static_cast<uint32_t>(region.getLowerY());
		uint32_t z = static_cast<uint32_t>(region.getLowerZ());

		// The magnitude of our input values is fairly restricted, but the values could stil be negative. This means the sign bit could
		// be set and this needs to be encoded as well. We therefore perform a left rotate on the bits to bring the sign bit into the LSB.
		x = rotateLeft(x);
		y = rotateLeft(y);
		z = rotateLeft(z);

		// Now convert to 64-bits
		uint64_t x64 = x;
		uint64_t y64 = y;
		uint64_t z64 = z;

		// Morten-encode the components to give our final key
		uint64_t result = EncodeMorton3(x64, y64, z64);

		// Return the combined value
		return result;
	}
void LargeVoxelSphere::VoxelSpherePager::pageIn(
    const PolyVox::Region& region,
    PolyVox::PagedVolume<BYTE>::Chunk* chunk)
{
 for (int z = region.getLowerCorner().getZ();
      z <= region.getUpperCorner().getZ(); z++) {
   for (int y = region.getLowerCorner().getY();
        y <= region.getUpperCorner().getY(); y++) {
     for (int x = region.getLowerCorner().getX();
          x <= region.getUpperCorner().getX(); x++) {
        PolyVox::Vector3DFloat current_pos(x,y,z);
        PolyVox::Vector3DFloat volume_center(0,0,0);
        float dist_to_center = (current_pos - volume_center).length();

        BYTE voxel_value = 0;
        if(dist_to_center <= 100) {
          voxel_value = 255;
        }

        chunk->setVoxel(x, y, z, voxel_value);
      }
    }
  }
}
Beispiel #6
0
	virtual void pageOut(const PolyVox::Region& region, PagedVolume<MaterialDensityPair44>::Chunk* /*pChunk*/)
	{
		std::cout << "warning unloading region: " << region.getLowerCorner() << " -> " << region.getUpperCorner() << std::endl;
	}
Beispiel #7
0
	UBasicVolume::VolumeType* ImportMagicaVoxel(FArchive& Ar)
	{
		// https://voxel.codeplex.com/wikipage?title=Sample%20Codes
		//auto* Result = new RawVolume(region);
		//return Result;

		const int MV_VERSION = 150;
		const int ID_VOX = MV_ID('V', 'O', 'X', ' ');
		const int ID_MAIN = MV_ID('M', 'A', 'I', 'N');
		const int ID_SIZE = MV_ID('S', 'I', 'Z', 'E');
		const int ID_XYZI = MV_ID('X', 'Y', 'Z', 'I');
		const int ID_RGBA = MV_ID('R', 'G', 'B', 'A');

		int32 magic;
		int32 version;

		// magic number
		Ar << magic;
		if (magic != ID_VOX)
		{
			UE_LOG(LogVoreealVolumeImporter, Warning, TEXT("magic number does not match"));
			return nullptr;
		}

		// version
		Ar << version;
		if (version != MV_VERSION)
		{
			UE_LOG(LogVoreealVolumeImporter, Warning, TEXT("version does not match"));
			return nullptr;
		}

		// main chunk
		vox_chunk_t mainChunk;
		ReadChunk(Ar, mainChunk);
		if (mainChunk.id != ID_MAIN)
		{
			UE_LOG(LogVoreealVolumeImporter, Warning, TEXT("main chunk is not found"));
			return nullptr;
		}

		bool isCustomPalette;
		MV_RGBA palette[256];

		MV_Voxel* voxels = nullptr;

		int32 sizex = 0, sizey = 0, sizez = 0, numVoxels = 0;
		while (!Ar.AtEnd())
		{
			// read chunk header
			vox_chunk_t sub;
			ReadChunk(Ar, sub);

			if (sub.id == ID_SIZE)
			{
				// size
				Ar << sizex << sizey << sizez;
			}
			else if (sub.id == ID_XYZI)
			{
				// numVoxels
				Ar << numVoxels;
				if (numVoxels < 0)
				{
					UE_LOG(LogVoreealVolumeImporter, Warning, TEXT("negative number of voxels"));
					return nullptr;
				}

				// voxels
				if (numVoxels > 0)
				{
					voxels = new MV_Voxel[numVoxels];
					Ar.Serialize(voxels, sizeof(MV_Voxel) * numVoxels);
				}
			}
			else if (sub.id == ID_RGBA)
			{
				// last color is not used, so we only need to read 255 colors
				isCustomPalette = true;
				Ar.Serialize(palette + 1, sizeof(MV_RGBA) * 255);

				// NOTICE : skip the last reserved color
				MV_RGBA reserved;
				Ar.Serialize(&reserved, sizeof(MV_RGBA));
			}
		}

		PolyVox::Region region;
		region.setLowerCorner(PolyVox::Vector3DInt32(0, 0, 0));
		region.setUpperCorner(PolyVox::Vector3DInt32(sizex, sizey, sizez));

		auto* Result = new UBasicVolume::VolumeType(region);

		for (int32 i = 0; i < numVoxels; i++)
		{
			auto voxel = voxels[i];
			auto color = palette[voxel.colorIndex];

			uint32 data =
				(color.r) |
				(color.g) << 8 |
				(color.b) << 16 |
				(color.a) << 24;

			Result->setVoxel(voxel.x, voxel.y, voxel.z, data);
		}

		delete[] voxels;

		//// print model info
		//printf("[Log] MV_VoxelModel :: Model : %d %d %d : %d\n",
		//	sizex, sizey, sizez, numVoxels
		//	);

		return Result;
	}
Beispiel #8
0
void World::unloadRegion(const PolyVox::ConstVolumeProxy<PolyVox::Material8>& volData, const PolyVox::Region& region) {
    std::stringstream ss;
    ss << "Info: unloadRegion() is unloading region: " << region.getLowerCorner() << " -> " << region.getUpperCorner();
    Utils::log(ss.str());
}