Пример #1
0
void TerrainProceduralDialog::makePertrub(float frequency, float distance)
{
    setWorking(true);
    PerlinNoise perlin;
    perlin.setSeed(1);
    perlin.initGradients();

    int u, v;
    float * temp = new float[m_mapWidth*m_mapDepth];
    for (int i = 0; i < m_mapWidth; ++i)
         for (int j = 0; j < m_mapDepth; ++j)
         {
              u = i + (int)(perlin.noise(frequency * i / (float)m_mapWidth, frequency * j / (float)m_mapDepth, 0) * distance);
              v = j + (int)(perlin.noise(frequency * i / (float)m_mapWidth, frequency * j / (float)m_mapDepth, 1) * distance);
              if (u < 0) u = 0; if (u >= m_mapWidth) u = m_mapWidth - 1;
              if (v < 0) v = 0; if (v >= m_mapDepth) v = m_mapDepth - 1;
              temp[i*m_mapWidth+j] = data[u*m_mapWidth+v];
         }
    for(int i=0;i<m_mapWidth*m_mapDepth;i++)
        data[i]=temp[i];

    delete temp;
    updateImage();
    setWorking(false);
}
Пример #2
0
void generatePerlinNoise(glm::vec3 perlinMatrix[IslandWidth][IslandHeight], double elevation[IslandWidth][IslandHeight]) {

    PerlinNoise pn;
//	int x,y;
//	double n, i, j;
//	for(x = 0; x < IslandWidth; x++){
//		for(y = 0; y < IslandHeight; y++){
//			i = (double) x / IslandWidth;
//			j = (double) y / IslandHeight;
//			n = 20 * pn.noise((double) i, (double) j, 0.0);
//			n = n - floor(n);
//			if(elevation[x][y] == 0){
//				elevation[x][y] += ((int) floor(n) % 2) ? n : -n;
//			}
//		}
//	}

    int i = 0, j = 0, xtemp;
    double n;
    int n_int;
    while(j < IslandHeight) {
        while(i < IslandWidth) {
            n = 2.0 * pn.noise((double) i, (double) j, elevation[i][j]);
            perlinMatrix[i][j].x = 0;
            perlinMatrix[i][j].y = 0;
            perlinMatrix[i][j].z = n;
            i++;
        }
        i = 0;
        j++;
    }

}
Пример #3
0
	T noise(T x, T y, T z)
	{
		T sum = 0;
		T frequency = (T)1;
		T amplitude = (T)1;
		T max = (T)0;  
		for (int32_t i = 0; i < (int32_t)octaves; i++)
		{
			sum += perlinNoise.noise(x * frequency, y * frequency, z * frequency) * amplitude;
			max += amplitude;
			amplitude *= persistence;
			frequency *= (T)2;
		}

		sum = sum / max;
		return (sum + (T)1.0) / (T)2.0;
	}
Пример #4
0
void TerrainProceduralDialog::makePerlinNoise(float seed, float frequency)
{
    setWorking(true);

    PerlinNoise perlin;
    perlin.setSeed(seed);
    perlin.initGradients();

    for(int i=0; i<m_mapWidth;i++)
        for(int j=0; j<m_mapDepth;j++)
        {
            float value=perlin.noise(frequency * i / (float)m_mapWidth, frequency * j / (float)m_mapDepth, 0);

            data[i*m_mapWidth+j]=value;
        }
    updateImage();
    setWorking(false);
}
Пример #5
0
// Called when the game starts or when spawned
void APDemo::BeginPlay()
{
	Super::BeginPlay();

	FString GameDir = FPaths::GameDir();
	FString CompleteFilePath = GameDir + "map_settings.txt";

	FString FileData = "";
	FFileHelper::LoadFileToString(FileData, *CompleteFilePath);
	int map_hash = FCString::Atoi(*FileData);
	//UE_LOG(LogTemp, Warning, TEXT("map_hash is %i and the path is %s"), map_hash, *CompleteFilePath);
	pn = PerlinNoise(map_hash);

	// Create an empty PPM image
	ppm image(width, height);

	unsigned int kk = 0;
	// Visit every pixel of the image and assign a color generated with Perlin noise
	for (unsigned int i = 0; i < height; ++i) {     // y
		for (unsigned int j = 0; j < width; ++j) {  // x
			double x = (double)j / ((double)width);
			double y = (double)i / ((double)height);
			// Typical Perlin noise
			double n = pn.noise(10 * x, 10 * y, 0.8);
			// Wood like structure
			//n = 20 * pn.noise(x, y, 0.8);
			//n = n - floor(n);

			n = n < noise_threshold ? 0 : n;//used to create a clear distinction between space and land
			// Map the values to the [0, 255] interval, for simplicity we use 
			// tones of grey
			image.r[kk] = floor(255 * n);
			image.g[kk] = floor(255 * n);
			image.b[kk] = floor(255 * n);
			kk++;
		}
	}

	// Save the image in a binary PPM file
	int result = image.write("figure_8_R.ppm");
}
Пример #6
0
double * adjustVoronoi(int ** voronoiPositions, double ** voronoiColors, double elevation[IslandWidth][IslandHeight], glm::vec3 landColor[IslandWidth][IslandHeight], int idx){
	int x = 0, y = 0, i = 0;
	double currHeight;
	double * resVorPos;
	*voronoiColors =  (double *) calloc( idx,  sizeof(double) );
	resVorPos =  (double *) calloc( idx,  sizeof(double) );
	double maxElev = 0;
	double elevThresh = 0.4;

	PerlinNoise pn;
	double n;
	int maxrad = 1000, rad ;
	glm::vec2 center;
	glm::vec2 loc;

	center.x = IslandWidth / 2;
	center.y = IslandHeight / 2;
	double distanceFromCtr;



	while(i < idx){
		x = (*voronoiPositions)[i];
		y = (*voronoiPositions)[i + 1];
		loc.x = x;
		loc.y = y;


		if(
			(x >= 0 && x < IslandWidth) &&
			(y >= 0 && y < IslandHeight)
		){

			distanceFromCtr = (double) glm::length(loc - center);
			n = pn.noise( (double) x / IslandWidth, (double) y / IslandHeight, 0.0);
			rad = maxrad * (n - floor(n));
			//n = sin(x + y);
			n *= 1800;

			resVorPos[i] = normalize(x, IslandWidth);
			resVorPos[i + 1] = normalize(y, IslandHeight);
			//z-value
			currHeight = elevation[x][y];
			if(maxElev < currHeight){ maxElev = currHeight ; }
//			(*voronoiPositions)[i + 2] = -currHeight;
//			resVorPos[i + 2] = (distanceFromCtr < (IslandRadius + n)) ? -currHeight:0.0f;
			resVorPos[i + 2] = -currHeight;
			if(resVorPos[i + 2] > elevThresh){ resVorPos[i + 2] = elevThresh; }
//			printf("Voronoi pos: (%d, %d) E: %f\n", x, y, resVorPos[i + 2]);

//			*voronoiColors =  (double *) realloc((*voronoiColors), (i+ 3) *  sizeof(double) );
			// r
			(*voronoiColors)[i] = landColor[x][y].r;
//			(*voronoiColors)[i] *= 1.3;
			// g
			(*voronoiColors)[i + 1] = landColor[x][y].g;
//			(*voronoiColors)[i + 1] *= 1.3;
			// b
			(*voronoiColors)[i + 2] = landColor[x][y].b;
//			(*voronoiColors)[i + 2] *= 0.4;

//			}

		} else{
			if(x < 0){
				resVorPos[i] = -1;
			}

			if(x >= IslandWidth){
				resVorPos[i] = 1;
			}
			if(y < 0){
				resVorPos[i + 1] = -1;
			}

			if(y >= IslandHeight){
				resVorPos[i + 1] = 1;
			}
			resVorPos[i + 2] = 0;
		}


		i += 3;

	}
	printf("Max voronoi height: %f", maxElev);
	return resVorPos;

}
Пример #7
0
// Thoughout the function we delete all in-world coordinates by 200.
// This is to make a cube in the real world be equal to a pixel from the map image.
void APDemo::Tick( float DeltaTime )
{	
	Super::Tick( DeltaTime );
	
	UWorld* World = GetWorld();
	APlayerCameraManager* PlayerCameraManager = World->GetFirstPlayerController()->PlayerCameraManager;
	FVector cam_position = PlayerCameraManager->GetCameraLocation();
	
	if (br != 0){ //go through brick_to... and remove the marked ones from bricks
		for (unsigned int i = 0; i < br; ++i){
			ABrick* Brick = bricks[bricks_to_be_removed[i]];
			bricks.erase(bricks_to_be_removed[i]);
			Brick->Destroy();
			bricks_to_be_removed[i] = "";
		}
		br = 0;
	}
	
	//now go through bricks and mark the new bricks to be removed next frame
	for (auto it = bricks.begin(); it != bricks.end(); ++it){
		FVector brick_loc = it->second->GetActorLocation();
		float distance = ( (brick_loc - cam_position).Size() )/200;
		if (distance >= despawn_dist){
			bricks_to_be_removed[br] = it->first;
			++br;
		}
	}

	//int spawn_height_sector = (int)floor(cam_position.Z / 200) / 80;
	//spawn_height = 160 * spawn_height_sector;

	//this magic tho
	int spawn_height_sector = (int)floor(cam_position.Z / 200);
	int sector_offset = spawn_height_sector == 0 ? 0 : (spawn_height_sector / abs(spawn_height_sector)) * 80;
	spawn_height_sector += sector_offset;
	spawn_height_sector = spawn_height_sector / 160;	
	spawn_height = 160 * spawn_height_sector;
	

	int distance_fwd = 60;
	int distance_left = 60;
	int start_i = (int)floor(cam_position.X / 200);
	int start_j = (int)floor(cam_position.Y / 200);
	for (int i = start_i - distance_fwd; i < start_i + distance_fwd; ++i) {     // y
		for (int j = start_j - distance_left; j < start_j + distance_left; ++j) {  // x
			double x = (double)(abs(j) % width) / ((double)width);// we use % to make sure we never go out of the defined map
			double y = (double)(abs(i) % height) / ((double)height);

			double n = pn.noise(10 * x, 10 * y, 0.8);
			n = n < noise_threshold ? 0 : n;//used to create a clear distinction between space and land
			FVector brick_position = FVector(i * 200, j * 200, spawn_height * 200);
			float distance = ((brick_position - cam_position).Size()) / 200;

			if (distance < despawn_dist){
				string key = to_string(i) + to_string(j);

				if (n > 0 && !bricks[key]){
					float brick_height = n;
					ABrick* Brick = World->SpawnActor<ABrick>(ABrick::StaticClass());
					Brick->SetPositionAndHeight(brick_position, brick_height, noise_threshold);
					bricks[key] = Brick;
				}
			}
		}
	}	
}
Пример #8
0
	// Generate randomized noise and upload it to the 3D texture using staging
	void updateNoiseTexture()
	{
		const uint32_t texMemSize = texture.width * texture.height * texture.depth;

		uint8_t *data = new uint8_t[texMemSize];
		memset(data, 0, texMemSize);

		// Generate perlin based noise
		std::cout << "Generating " << texture.width << " x " << texture.height << " x " << texture.depth << " noise texture..." << std::endl;

		auto tStart = std::chrono::high_resolution_clock::now();

		PerlinNoise<float> perlinNoise;
		FractalNoise<float> fractalNoise(perlinNoise);

		std::default_random_engine rndEngine(std::random_device{}());
		const int32_t noiseType = rand() % 2;
		const float noiseScale = static_cast<float>(rand() % 10) + 4.0f;

#pragma omp parallel for
		for (int32_t z = 0; z < (int32_t)texture.depth; z++)
		{
			for (int32_t y = 0; y < (int32_t)texture.height; y++)
			{
				for (int32_t x = 0; x < (int32_t)texture.width; x++)
				{
					float nx = (float)x / (float)texture.width;
					float ny = (float)y / (float)texture.height;
					float nz = (float)z / (float)texture.depth;
#define FRACTAL
#ifdef FRACTAL
					float n = fractalNoise.noise(nx * noiseScale, ny * noiseScale, nz * noiseScale);
#else
					float n = 20.0 * perlinNoise.noise(nx, ny, nz);
#endif
					n = n - floor(n);

					data[x + y * texture.width + z * texture.width * texture.height] = static_cast<uint8_t>(floor(n * 255));
				}
			}
		}

		auto tEnd = std::chrono::high_resolution_clock::now();
		auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();

		std::cout << "Done in " << tDiff << "ms" << std::endl;

		// Create a host-visible staging buffer that contains the raw image data
		VkBuffer stagingBuffer;
		VkDeviceMemory stagingMemory;

		// Buffer object
		VkBufferCreateInfo bufferCreateInfo = vkTools::initializers::bufferCreateInfo();
		bufferCreateInfo.size = texMemSize;
		bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
		bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;			
		VK_CHECK_RESULT(vkCreateBuffer(device, &bufferCreateInfo, nullptr, &stagingBuffer));

		// Allocate host visible memory for data upload
		VkMemoryAllocateInfo memAllocInfo = vkTools::initializers::memoryAllocateInfo();
		VkMemoryRequirements memReqs = {};
		vkGetBufferMemoryRequirements(device, stagingBuffer, &memReqs);
		memAllocInfo.allocationSize = memReqs.size;
		memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
		VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &stagingMemory));
		VK_CHECK_RESULT(vkBindBufferMemory(device, stagingBuffer, stagingMemory, 0));

		// Copy texture data into staging buffer
		uint8_t *mapped;
		VK_CHECK_RESULT(vkMapMemory(device, stagingMemory, 0, memReqs.size, 0, (void **)&mapped));
		memcpy(mapped, data, texMemSize);
		vkUnmapMemory(device, stagingMemory);

		VkCommandBuffer copyCmd = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true);

		// Image barrier for optimal image

		// The sub resource range describes the regions of the image we will be transition
		VkImageSubresourceRange subresourceRange = {};
		subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
		subresourceRange.baseMipLevel = 0;
		subresourceRange.levelCount = 1;
		subresourceRange.layerCount = 1;

		// Optimal image will be used as destination for the copy, so we must transfer from our
		// initial undefined image layout to the transfer destination layout
		vkTools::setImageLayout(
			copyCmd,
			texture.image,
			VK_IMAGE_ASPECT_COLOR_BIT,
			VK_IMAGE_LAYOUT_UNDEFINED,
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
			subresourceRange);

		// Copy 3D noise data to texture

		// Setup buffer copy regions
		VkBufferImageCopy bufferCopyRegion{};
		bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
		bufferCopyRegion.imageSubresource.mipLevel = 0;
		bufferCopyRegion.imageSubresource.baseArrayLayer = 0;
		bufferCopyRegion.imageSubresource.layerCount = 1;
		bufferCopyRegion.imageExtent.width = texture.width;
		bufferCopyRegion.imageExtent.height = texture.height;
		bufferCopyRegion.imageExtent.depth = texture.depth;

		vkCmdCopyBufferToImage(
			copyCmd,
			stagingBuffer,
			texture.image,
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
			1, 
			&bufferCopyRegion);

		// Change texture image layout to shader read after all mip levels have been copied
		texture.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
		vkTools::setImageLayout(
			copyCmd,
			texture.image,
			VK_IMAGE_ASPECT_COLOR_BIT,
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
			texture.imageLayout,
			subresourceRange);

		VulkanExampleBase::flushCommandBuffer(copyCmd, queue, true);

		// Clean up staging resources
		delete[] data;
		vkFreeMemory(device, stagingMemory, nullptr);
		vkDestroyBuffer(device, stagingBuffer, nullptr);
		regenerateNoise = false;
	}