尝试参考Sebastian Lague的地形生成教程编写Perlin Noise高度图生成,但是将其从C#移植到UE4中。遇到有关枚举类的错误,我不知道为什么会出现这些错误
尝试将枚举类更改为枚举,尝试将其分隔为单独的类文件,尝试将其包含在类的构造函数中,但出现了更多错误。
WorldGenerationNoise.h
#pragma once
#include <vector>
#include "Math/Vector2D.h"
#include "NoiseSettings.h"
#include "FastNoise.h"
class WorldGenerationNoise {
public:
enum class NormalizeMode {
Local,
Global
};
static std::vector<std::vector<float>> GenerateNoiseMap(int mapSize, NoiseSettings settings, FVector2D sampleCenter);
};
WorldGenerationNoise.cpp
#include "WorldGenerationNoise.h"
#include "NoiseSettings.h"
#include <vector>
#include <float.h>
#include "Math/Vector2D.h"
#include "Math/RandomStream.h"
#include "Kismet/KismetMathLibrary.h"
#define NM WorldGenerationNoise::NormalizeMode
#define UKFClamp UKismetMathLibrary::FClamp
#define UKFNormToRange UKismetMathLibrary::NormalizeToRange
#define HT 100000
std::vector<std::vector<float>> GenerateNoiseMap(int mapSize, NoiseSettings settings, FVector2D sampleCenter) {
std::vector<std::vector<float>> noiseMap(mapSize, std::vector<float>(mapSize, 0));
FRandomStream prng = FRandomStream(settings.seed);
std::vector<FVector2D> octaveOffsets(mapSize, FVector2D(0, 0));
float maxPossibleHeight = 0, amplitude = 1, frequency = 1;
for (int i = 0; i < settings.octaves; i++) {
float offsetX = prng.FRandRange(-HT, HT) + settings.offset.X + sampleCenter.X;
float offsetY = prng.FRandRange(-HT, HT) - settings.offset.Y - sampleCenter.Y;
octaveOffsets[i] = FVector2D(offsetX, offsetY);
maxPossibleHeight += amplitude;
amplitude *= settings.persistance;
}
float maxLocalNoiseHeight = FLT_MIN, minLocalNoiseHeight = FLT_MAX, halfSize = mapSize / 2.0f;
for (int y = 0; y < mapSize; y++) {
for (int x = 0; x < mapSize; x++) {
amplitude = 1;
frequency = 1;
float noiseHeight = 0;
for (int i = 0; i < settings.octaves; i++) {
float sampleX = (x - halfSize + octaveOffsets[i].X) / settings.scale * frequency;
float sampleY = (y - halfSize + octaveOffsets[i].Y) / settings.scale * frequency;
float perlinValue = FastNoise(settings.seed).GetPerlin(sampleX, sampleY) * 2 - 1;
noiseHeight += perlinValue * amplitude;
amplitude *= settings.persistance;
frequency *= settings.lacunarity;
}
if (noiseHeight > maxLocalNoiseHeight) maxLocalNoiseHeight = noiseHeight;
if (noiseHeight < minLocalNoiseHeight) minLocalNoiseHeight = noiseHeight;
noiseMap[x][y] = noiseHeight;
if (settings.normalizeMode == NM::Global) {
float normalizedHeight = (noiseMap[x][y] + 1) / (maxPossibleHeight / 0.9f);
noiseMap[x][y] = UKFClamp(normalizedHeight, 0, INT_MAX);
}
}
}
if (settings.normalizeMode == NM::Local) {
for (int y = 0; y < mapSize; y++) {
for (int x = 0; x < mapSize; x++) {
noiseMap[x][y] = UKFNormToRange(noiseMap[x][y], minLocalNoiseHeight, maxLocalNoiseHeight);
}
}
}
return noiseMap;
}
NoiseSettings.h
#pragma once
#include "Math/UnrealMathUtility.h"
#include "Math/Vector2D.h"
#include "WorldGenerationNoise.h"
#define NM WorldGenerationNoise::NormalizeMode
class NoiseSettings {
public:
NM normalizeMode = NM::Global;
float scale = 50, persistance = 0.6f, lacunarity = 2;
int octaves = 6, seed = FMath::RandRange(-INT_MAX, INT_MAX);
FVector2D offset = FVector2D(0, 0);
void ValidateValues();
};
NoiseSettings.cpp
#include "NoiseSettings.h"
#include <float.h>
#include "Kismet/KismetMathLibrary.h"
#include "Math/UnrealMathUtility.h"
#define UKFMax UKismetMathLibrary::FMax
#define UKIMax UKismetMathLibrary::Max
#define UKFClamp UKismetMathLibrary::FClamp
void NoiseSettings::ValidateValues() {
scale = UKFMax(scale, 0.0f);
octaves = UKIMax(octaves, 1);
lacunarity = UKFMax(lacunarity, 1);
persistance = UKFClamp(persistance, 0.0f, 1.0f);
seed = FMath::FRandRange(-FLT_MAX, FLT_MAX);
}
因此,从理论上讲,我认为它应该编译时没有任何复杂性,但出现以下错误:
WorldGenerationNoise.cpp (0:01.20 at +0:00)
Error: E:\UnrealTests\WorldGeneration\Source\WorldGeneration\Public\NoiseSettings\NoiseSettings.h(12) : error C2653: 'WorldGenerationNoise': is not a class or namespace name
Error: E:\UnrealTests\WorldGeneration\Source\WorldGeneration\Public\NoiseSettings\NoiseSettings.h(12) : error C3646: 'normalizeMode': unknown override specifier
Error: E:\UnrealTests\WorldGeneration\Source\WorldGeneration\Public\NoiseSettings\NoiseSettings.h(12) : error C2059: syntax error: '='
Error: E:\UnrealTests\WorldGeneration\Source\WorldGeneration\Public\NoiseSettings\NoiseSettings.h(12) : error C2238: unexpected token(s) preceding ';'
Error: E:\UnrealTests\WorldGeneration\Source\WorldGeneration\Private\Noise\WorldGenerationNoise.cpp(59) : error C2039: 'normalizeMode': is not a member of 'NoiseSettings'
[2019.11.11-02.07.08:630][748]CompilerResultsLog: Error: E:\UnrealTests\WorldGeneration\Source\WorldGeneration\Private\Noise\WorldGenerationNoise.cpp(66) : error C2039: 'normalizeMode': is not a member of 'NoiseSettings'
NoiseSettings.cpp (0:01.17 at +0:01)
Error: E:\UnrealTests\WorldGeneration\Source\WorldGeneration\Public\Noise\WorldGenerationNoise.h(17) : error C2061: syntax error: identifier 'NoiseSettings'