1#include "Generators/MeshGeneratorManager.h"
3#include "Utils/Utils.h"
5#include "Data/ApplicationState.h"
7#include "Generators/ClearMeshGenerator.h"
8#include "Generators/CPUNoiseLayersGenerator.h"
9#include "Generators/GPUNoiseLayerGenerator.h"
10#include "Generators/CPUNodeEditor/CPUNodeEditor.h"
12#include "Base/UIFontManager.h"
20 isRemeshing = &appState->states.remeshing;
26MeshGeneratorManager::~MeshGeneratorManager()
32void MeshGeneratorManager::Generate()
39 if (appState->mode == ApplicationMode::TERRAIN)
41 appState->models.coreTerrain->UploadToGPU();
44 else if (appState->mode == ApplicationMode::CUSTOM_BASE)
46 appState->models.customBase->UploadToGPU();
50 std::thread worker([
this]
54 if(!clearMeshGen->useGPU)
56 clearMeshGen->Generate(
nullptr);
57 ExecuteCPUGenerators();
64 ExecuteCPUGenerators();
67 if(!appState->states.useGPUForNormals )
69 if (appState->mode == ApplicationMode::TERRAIN)
71 appState->models.coreTerrain->mesh->RecalculateNormals();
74 else if (appState->mode == ApplicationMode::CUSTOM_BASE)
76 appState->models.customBase->mesh->RecalculateNormals();
85void MeshGeneratorManager::GenerateSync()
87 while (appState->states.remeshing);
99 ExecuteCPUGenerators();
102 if (appState->mode == ApplicationMode::TERRAIN)
104 appState->models.coreTerrain->mesh->RecalculateNormals();
105 appState->models.coreTerrain->UploadToGPU();
108 else if (appState->mode == ApplicationMode::CUSTOM_BASE)
110 appState->models.customBase->mesh->RecalculateNormals();
111 appState->models.customBase->UploadToGPU();
114 *isRemeshing =
false;
117void MeshGeneratorManager::ShowSettings()
121 ImGui::Begin(
"Mesh Generators", &windowStat);
122 ImGui::PushFont(GetUIFont(
"OpenSans-Semi-Bold"));
123 ImGui::Text(
"Base Mesh Generators");
126 if (ImGui::CollapsingHeader(
"Auto Base Mesh Gen (GPU)", clearMeshGen->uiActive))
128 clearMeshGen->ShowSettings();
132 ImGui::PushFont(GetUIFont(
"OpenSans-Semi-Bold"));
133 ImGui::Text(
"CPU Noise Layer Generators");
136 for (
int i = 0; i < cpuNoiseLayers.size(); i++)
138 if (ImGui::CollapsingHeader((cpuNoiseLayers[i]->name +
"##CPUNL" + std::to_string(i)).c_str()))
140 cpuNoiseLayers[i]->ShowSetting(i);
142 if (ImGui::Button((
"Delete##CPUNOUSELAYER" + std::to_string(i)).c_str()))
144 while (*isRemeshing);
146 cpuNoiseLayers.erase(cpuNoiseLayers.begin() + i);
154 if (ImGui::Button(
"Add##CPULAYER"))
156 while (*isRemeshing);
162 ImGui::PushFont(GetUIFont(
"OpenSans-Semi-Bold"));
163 ImGui::Text(
"GPU Noise Layer Generators");
166 for (
int i = 0; i < gpuNoiseLayers.size(); i++)
168 if (ImGui::CollapsingHeader((gpuNoiseLayers[i]->name +
"##GPUNL" + std::to_string(i)).c_str()))
170 gpuNoiseLayers[i]->ShowSetting(i);
172 if (ImGui::Button((
"Delete##GPUNOUSELAYER" + std::to_string(i)).c_str()))
174 while (*isRemeshing);
176 gpuNoiseLayers.erase(gpuNoiseLayers.begin() + i);
184 if (ImGui::Button(
"Add##GPUNL"))
186 while (*isRemeshing);
192 ImGui::PushFont(GetUIFont(
"OpenSans-Semi-Bold"));
193 ImGui::Text(
"CPU Node Editor Generators");
196 for (
int i = 0; i < cpuNodeEditors.size(); i++)
198 if (ImGui::CollapsingHeader((cpuNodeEditors[i]->name +
"##CPUNE" + std::to_string(i)).c_str()))
200 cpuNodeEditors[i]->ShowSetting(i);
202 if (ImGui::Button((
"Delete##CPNE" + std::to_string(i)).c_str()))
204 while (*isRemeshing);
206 cpuNodeEditors.erase(cpuNodeEditors.begin() + i);
214 if (ImGui::Button(
"Add##CPUNE"))
216 while (*isRemeshing);
222 ImGui::Text(
"Time : %lf ms", time);
226 for (
int i = 0; i < cpuNoiseLayers.size(); i++)
228 cpuNoiseLayers[i]->Update();
231 for (
int i = 0; i < gpuNoiseLayers.size(); i++)
233 gpuNoiseLayers[i]->Update();
236 for (
int i = 0; i < cpuNodeEditors.size(); i++)
238 cpuNodeEditors[i]->Update();
242void MeshGeneratorManager::GenerateForTerrain()
244 int res = appState->globals.resolution;
245 float scale = appState->globals.scale;
246 Model *mod = appState->models.coreTerrain;
248 for (
int i = 0; i < mod->mesh->vertexCount; i++)
252 inp.x = mod->mesh->vert[i].position.x;
254 inp.z = mod->mesh->vert[i].position.z;
261 inp.texX = mod->mesh->vert[i].texCoord.x;
262 inp.texY = mod->mesh->vert[i].texCoord.y;
264 for (
int j = 0; j < cpuNoiseLayers.size(); j++)
266 if(cpuNoiseLayers[j]->enabled)
268 elev += cpuNoiseLayers[j]->EvaluateAt(inp.x, inp.y, inp.z);
272 for(
int j = 0 ; j<cpuNodeEditors.size(); j++)
274 if(cpuNodeEditors[j]->enabled)
276 elev += cpuNodeEditors[j]->EvaluateAt(inp);
280 mod->mesh->vert[i].position.y += elev;
281 mod->mesh->vert[i].extras1.x += elev;
285void MeshGeneratorManager::GenerateForCustomBase()
287 Model *customModel = appState->models.customBase;
288 Model *customModelCopy = appState->models.customBaseCopy;
289 float scale = appState->globals.scale;
290 appState->stats.vertexCount = customModel->mesh->vertexCount;
292 for (
int i = 0; i < customModel->mesh->vertexCount; i++)
294 Vert tmp = customModelCopy->mesh->vert[i];
297 inp.x = tmp.position.x;
299 inp.z = tmp.position.z;
306 inp.texX = tmp.texCoord.x;
307 inp.texY = tmp.texCoord.y;
309 for (
int j = 0; j < cpuNoiseLayers.size(); j++)
311 if(cpuNoiseLayers[j]->enabled)
313 elev += cpuNoiseLayers[j]->EvaluateAt(inp.x, inp.y, inp.z);
317 for(
int j = 0 ; j<cpuNodeEditors.size(); j++)
319 if(cpuNodeEditors[j]->enabled)
321 elev += cpuNodeEditors[j]->EvaluateAt(inp);
325 tmp.position *= scale;
326 tmp.position += elev * tmp.normal;
327 customModel->mesh->vert[i].extras1.x += elev;
328 customModel->mesh->vert[i].position += tmp.position;
332void MeshGeneratorManager::ExecuteKernels()
334 if (appState->mode == ApplicationMode::TERRAIN)
336 if (appState->models.coreTerrain->mesh->res != appState->globals.resolution || appState->models.coreTerrain->mesh->sc != appState->globals.scale)
338 appState->models.coreTerrain->mesh->res = appState->globals.resolution;
339 appState->models.coreTerrain->mesh->sc = appState->globals.scale;
340 appState->models.coreTerrain->mesh->GeneratePlane(appState->globals.resolution, appState->globals.scale);
343 kernels->CreateBuffer(
"mesh", CL_MEM_READ_WRITE, appState->models.coreTerrain->mesh->vertexCount *
sizeof(
Vert));
344 kernels->WriteBuffer(
"mesh",
true, appState->models.coreTerrain->mesh->vertexCount *
sizeof(
Vert), appState->models.coreTerrain->mesh->vert);
346 if(clearMeshGen->useGPU)
348 clearMeshGen->Generate(kernels);
351 for (
int i = 0; i < gpuNoiseLayers.size(); i++)
353 if (gpuNoiseLayers[i]->enabled)
355 gpuNoiseLayers[i]->Generate(kernels);
359 if(clearMeshGen->useGPUForNormals)
361 kernels->CreateBuffer(
"indices", CL_MEM_READ_WRITE, appState->models.coreTerrain->mesh->indexCount *
sizeof(
int));
362 kernels->WriteBuffer(
"indices",
true, appState->models.coreTerrain->mesh->indexCount *
sizeof(
int), appState->models.coreTerrain->mesh->indices);
363 kernels->SetKernelArg(
"gen_normals", 0,
"mesh");
364 kernels->SetKernelArg(
"gen_normals", 1,
"indices");
366 int ic = appState->models.coreTerrain->mesh->indexCount;
373 kernels->ExecuteKernel(
"gen_normals", cl::NDRange(ls), cl::NDRange(ic));
374 kernels->SetKernelArg(
"normalize_normals", 0,
"mesh");
375 kernels->ExecuteKernel(
"normalize_normals", cl::NDRange(1), cl::NDRange(appState->models.coreTerrain->mesh->vertexCount));
378 kernels->ReadBuffer(
"mesh",
true, appState->models.coreTerrain->mesh->vertexCount *
sizeof(
Vert), appState->models.coreTerrain->mesh->vert);
381 else if (appState->mode == ApplicationMode::CUSTOM_BASE)
383 kernels->CreateBuffer(
"mesh", CL_MEM_READ_WRITE, appState->models.customBase->mesh->vertexCount *
sizeof(
Vert));
384 kernels->WriteBuffer(
"mesh",
true, appState->models.customBase->mesh->vertexCount *
sizeof(
Vert), appState->models.customBase->mesh->vert);
385 kernels->CreateBuffer(
"mesh_copy", CL_MEM_READ_WRITE, appState->models.customBase->mesh->vertexCount *
sizeof(
Vert));
386 kernels->WriteBuffer(
"mesh_copy",
true, appState->models.customBase->mesh->vertexCount *
sizeof(
Vert), appState->models.customBaseCopy->mesh->vert);
388 if(clearMeshGen->useGPU)
390 clearMeshGen->Generate(kernels);
393 for (
int i = 0; i < gpuNoiseLayers.size(); i++)
395 if (gpuNoiseLayers[i]->enabled)
397 gpuNoiseLayers[i]->Generate(kernels);
401 if(clearMeshGen->useGPUForNormals)
403 kernels->CreateBuffer(
"indices", CL_MEM_READ_WRITE, appState->models.customBase->mesh->indexCount *
sizeof(
int));
404 kernels->WriteBuffer(
"indices",
true, appState->models.customBase->mesh->indexCount *
sizeof(
int), appState->models.customBase->mesh->indices);
405 kernels->SetKernelArg(
"gen_normals", 0,
"mesh");
406 kernels->SetKernelArg(
"gen_normals", 1,
"indices");
408 int ic = appState->models.customBase->mesh->indexCount;
415 kernels->ExecuteKernel(
"gen_normals", cl::NDRange(ls), cl::NDRange(ic));
416 kernels->SetKernelArg(
"normalize_normals", 0,
"mesh");
417 kernels->ExecuteKernel(
"normalize_normals", cl::NDRange(1), cl::NDRange(appState->models.customBase->mesh->vertexCount));
420 kernels->ReadBuffer(
"mesh",
true, appState->models.customBase->mesh->vertexCount *
sizeof(
Vert), appState->models.customBase->mesh->vert);
424void MeshGeneratorManager::ExecuteCPUGenerators()
426 if (appState->mode == ApplicationMode::TERRAIN)
428 GenerateForTerrain();
431 else if (appState->mode == ApplicationMode::CUSTOM_BASE)
433 GenerateForCustomBase();
437void MeshGeneratorManager::LoadKernels()
440 std::string source = ReadShaderSourceFile(GetExecutableDir() + PATH_SEPARATOR
"Data" PATH_SEPARATOR
"kernels" PATH_SEPARATOR
"generators" PATH_SEPARATOR
"generators.cl", &tmp);
441 kernels->AddSoruce(source);
442 kernels->BuildProgram(
"-I" + appState->globals.kernelsIncludeDir +
" -cl-fast-relaxed-math -cl-mad-enable");
443 kernels->AddKernel(
"clear_mesh_terrain");
444 kernels->AddKernel(
"clear_mesh_custom_base");
445 kernels->AddKernel(
"noise_layer_terrain");
446 kernels->AddKernel(
"noise_layer_custom_base");
447 kernels->AddKernel(
"gen_normals");
448 kernels->AddKernel(
"normalize_normals");
454 data[
"cmg"] = clearMeshGen->Save();
456 for (
int i = 0; i < cpuNoiseLayers.size(); i++)
458 tmp.
push_back(cpuNoiseLayers[i]->Save());
464 for (
int i = 0; i < gpuNoiseLayers.size(); i++)
466 tmp.
push_back(gpuNoiseLayers[i]->Save());
472 for (
int i = 0; i < cpuNodeEditors.size(); i++)
474 tmp.
push_back(cpuNodeEditors[i]->Save());
483 while (*isRemeshing);
485 clearMeshGen->Load(data[
"cmg"]);
487 for (
int i = 0; i < cpuNoiseLayers.size(); i++)
489 delete cpuNoiseLayers[i];
492 cpuNoiseLayers.clear();
494 for (
int i = 0; i < data[
"cpunl"].
size(); i++)
497 cpuNoiseLayers.back()->Load(data[
"cpunl"][i]);
500 for (
int i = 0; i < gpuNoiseLayers.size(); i++)
502 delete gpuNoiseLayers[i];
505 gpuNoiseLayers.clear();
507 for (
int i = 0; i < data[
"gpunl"].
size(); i++)
510 gpuNoiseLayers.back()->Load(data[
"gpunl"][i]);
513 for (
int i = 0; i < cpuNodeEditors.size(); i++)
515 delete cpuNodeEditors[i];
518 cpuNodeEditors.clear();
520 for (
int i = 0; i < data[
"cpune"].
size(); i++)
523 cpuNodeEditors.back()->Load(data[
"cpune"][i]);
size_type size() const noexcept
returns the number of elements
void push_back(basic_json &&val)
add an object to an array
a class to store JSON values
basic_json<> json
default JSON class