• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Refaktoryzacja kodu - proceduralne generowanie jaskiń

VPS Starter Arubacloud
0 głosów
311 wizyt
pytanie zadane 19 września 2019 w C i C++ przez Avernis Nałogowiec (27,400 p.)
edycja 20 września 2019 przez Avernis

Cześć, mam taki problem. Napisałem sobie taki oto kod:
 

void AChunk::createMesh()
{
	int32 X = FMath::FloorToInt(GetActorLocation().X / 100.0f);
	int32 Y = FMath::FloorToInt(GetActorLocation().Y / 100.0f);
	int32 Z = FMath::FloorToInt(GetActorLocation().Z / 100.0f);

	for (int32 x = 0; x < 16; ++x)
	{
		for (int32 y = 0; y < 16; ++y)
		{
			for (int32 z = 0; z < 16; ++z)
			{
				//Jeżeli od dowolnej strony jest odkryty
				float noiseXplus = noise3D((x + X + 1) * generationRange, (y + Y) * generationRange, (z + Z) * generationRange);
				float noiseXminus = noise3D((x + X - 1) * generationRange, (y + Y) * generationRange, (z + Z) * generationRange);

				float noiseYplus = noise3D((x + X) * generationRange, (y + Y + 1) * generationRange, (z + Z) * generationRange);
				float noiseYminus = noise3D((x + X) * generationRange, (y + Y - 1) * generationRange, (z + Z) * generationRange);

				float noiseZplus = noise3D((x + X) * generationRange, (y + Y) * generationRange, (z + Z + 1) * generationRange);
				float noiseZMinus = noise3D((x + X) * generationRange, (y + Y) * generationRange, (z + Z - 1) * generationRange);


				if (noiseYplus > 0.2 || noiseYminus > 0.2 || noiseXplus > 0.2 || noiseXminus > 0.2 || noiseZplus > 0.2 || noiseZMinus > 0.2)
				{
					if (noise3D((x + X) * generationRange, (y + Y) * generationRange, (z + Z) * generationRange) > 0.2)
					{
						
						int32 vFind000 = vertices.Find(FVector(x * 100, y * 100, z * 100));
						int32 vFind100 = vertices.Find(FVector((x + 1) * 100, y * 100, z * 100));
						int32 vFind010 = vertices.Find(FVector(x * 100, (y + 1) * 100, z * 100));
						int32 vFind001 = vertices.Find(FVector(x * 100, y * 100, (z + 1) * 100));
						int32 vFind110 = vertices.Find(FVector((x + 1) * 100, (y + 1) * 100, z * 100));
						int32 vFind101 = vertices.Find(FVector((x + 1) * 100, y * 100, (z + 1) * 100));
						int32 vFind011 = vertices.Find(FVector(x * 100, (y + 1) * 100, (z + 1) * 100));
						int32 vFind111 = vertices.Find(FVector((x + 1) * 100, (y + 1) * 100, (z + 1) * 100));
						
						if (!(noiseXminus > 0.2))
						{
							int32 v1 = 0;
							int32 v2 = 0;
							int32 v3 = 0;
							int32 v4 = 0;

							if (vFind000 == -1)
							{
								vertices.Add(FVector(x * 100, y * 100, z * 100));
								v1 = vertices.Num() - 1;
							}
							else
							{
								v1 = vFind000;
							}
							//***************************************************************
							if (vFind001 == -1)
							{
								vertices.Add(FVector(x * 100, y * 100, (z + 1) * 100));
								v2 = vertices.Num() - 1;
							}
							else
							{
								v2 = vFind001;
							}
							//***************************************************************
							if (vFind011 == -1)
							{
								vertices.Add(FVector(x * 100, (y + 1) * 100, (z + 1) * 100));
								v3 = vertices.Num() - 1;
							}
							else
							{
								v3 = vFind011;
							}
							//***************************************************************
							if (vFind010 == -1)
							{
								vertices.Add(FVector(x * 100, (y + 1) * 100, z * 100));
								v4 = vertices.Num() - 1;
							}
							else
							{
								v4 = vFind010;
							}
							//***************************************************************

							addTriangle(v1, v2, v3);
							addTriangle(v1, v3, v4);
						}

						///***************************************************************************************
						if (!(noiseXplus > 0.2))
						{
							int32 v1 = 0;
							int32 v2 = 0;
							int32 v3 = 0;
							int32 v4 = 0;

							if (vFind100 == -1)
							{
								vertices.Add(FVector((x + 1) * 100, y * 100, z * 100));
								v1 = vertices.Num() - 1;
							}
							else
							{
								v1 = vFind100;
							}
							//***************************************************************
							if (vFind101 == -1)
							{
								vertices.Add(FVector((x + 1) * 100, y * 100, (z + 1) * 100));
								v2 = vertices.Num() - 1;
							}
							else
							{
								v2 = vFind101;
							}
							//***************************************************************
							if (vFind111 == -1)
							{
								vertices.Add(FVector((x + 1) * 100, (y + 1) * 100, (z + 1) * 100));
								v3 = vertices.Num() - 1;
							}
							else
							{
								v3 = vFind111;
							}
							//***************************************************************
							if (vFind110 == -1)
							{
								vertices.Add(FVector((x + 1) * 100, (y + 1) * 100, z * 100));
								v4 = vertices.Num() - 1;
							}
							else
							{
								v4 = vFind110;
							}
							//***************************************************************

							addTriangle(v1, v3, v2);
							addTriangle(v1, v4, v3);
						}
						///***************************************************************************************

						if (!(noiseYplus > 0.2))
						{
							int32 v1 = 0;
							int32 v2 = 0;
							int32 v3 = 0;
							int32 v4 = 0;

							if (vFind010 == -1)
							{
								vertices.Add(FVector(x * 100, (y + 1) * 100, z * 100));
								v1 = vertices.Num() - 1;
							}
							else
							{
								v1 = vFind010;
							}
							//***************************************************************
							if (vFind111 == -1)
							{
								vertices.Add(FVector((x + 1) * 100, (y + 1) * 100, (z + 1) * 100));
								v2 = vertices.Num() - 1;
							}
							else
							{
								v2 = vFind111;
							}
							//***************************************************************
							if (vFind110 == -1)
							{
								vertices.Add(FVector((x + 1) * 100, (y + 1) * 100, z * 100));
								v3 = vertices.Num() - 1;
							}
							else
							{
								v3 = vFind110;
							}
							//***************************************************************
							if (vFind011 == -1)
							{
								vertices.Add(FVector(x * 100, (y + 1) * 100, (z + 1) * 100));
								v4 = vertices.Num() - 1;
							}
							else
							{
								v4 = vFind011;
							}
							//***************************************************************

							addTriangle(v1, v2, v3);
							addTriangle(v1, v4, v2);
						}
						///***************************************************************************************

						if (!(noiseYminus > 0.2))
						{
							int32 v1 = 0;
							int32 v2 = 0;
							int32 v3 = 0;
							int32 v4 = 0;

							if (vFind000 == -1)
							{
								vertices.Add(FVector(x * 100, y * 100, z * 100));
								v1 = vertices.Num() - 1;
							}
							else
							{
								v1 = vFind000;
							}
							//***************************************************************
							if (vFind101 == -1)
							{
								vertices.Add(FVector((x + 1) * 100, y * 100, (z + 1) * 100));
								v2 = vertices.Num() - 1;
							}
							else
							{
								v2 = vFind101;
							}
							//***************************************************************
							if (vFind001 == -1)
							{
								vertices.Add(FVector(x * 100, y * 100, (z + 1) * 100));
								v3 = vertices.Num() - 1;
							}
							else
							{
								v3 = vFind001;
							}
							//***************************************************************
							if (vFind100 == -1)
							{
								vertices.Add(FVector((x + 1) * 100, y * 100, z * 100));
								v4 = vertices.Num() - 1;
							}
							else
							{
								v4 = vFind100;
							}
							//***************************************************************

							addTriangle(v1, v2, v3);
							addTriangle(v1, v4, v2);
						}
						///**************************************************************************************

						if (!(noiseZMinus > 0.2))
						{
							int32 v1 = 0;
							int32 v2 = 0;
							int32 v3 = 0;
							int32 v4 = 0;

							if (vFind000 == -1)
							{
								vertices.Add(FVector(x * 100, y * 100, z * 100));
								v1 = vertices.Num() - 1;
							}
							else
							{
								v1 = vFind000;
							}
							//***************************************************************
							if (vFind110 == -1)
							{
								vertices.Add(FVector((x + 1) * 100, (y + 1) * 100, z * 100));
								v2 = vertices.Num() - 1;
							}
							else
							{
								v2 = vFind110;
							}
							//***************************************************************
							if (vFind100 == -1)
							{
								vertices.Add(FVector((x + 1) * 100, y * 100, z * 100));
								v3 = vertices.Num() - 1;
							}
							else
							{
								v3 = vFind100;
							}
							//***************************************************************
							if (vFind010 == -1)
							{
								vertices.Add(FVector(x * 100, (y + 1) * 100, z * 100));
								v4 = vertices.Num() - 1;
							}
							else
							{
								v4 = vFind010;
							}
							//***************************************************************

							addTriangle(v1, v2, v3);
							addTriangle(v1, v4, v2);
						}

						if (!(noiseZplus > 0.2))
						{
							int32 v1 = 0;
							int32 v2 = 0;
							int32 v3 = 0;
							int32 v4 = 0;

							if (vFind001 == -1)
							{
								vertices.Add(FVector(x * 100, y * 100, (z + 1) * 100));
								v1 = vertices.Num() - 1;
							}
							else
							{
								v1 = vFind001;
							}
							//***************************************************************
							if (vFind101 == -1)
							{
								vertices.Add(FVector((x + 1) * 100, y * 100, (z + 1) * 100));
								v2 = vertices.Num() - 1;
							}
							else
							{
								v2 = vFind101;
							}
							//***************************************************************
							if (vFind111 == -1)
							{
								vertices.Add(FVector((x + 1) * 100, (y + 1) * 100, (z + 1) * 100));
								v3 = vertices.Num() - 1;
							}
							else
							{
								v3 = vFind111;
							}
							//***************************************************************
							if (vFind011 == -1)
							{
								vertices.Add(FVector(x * 100, (y + 1) * 100, (z + 1) * 100));
								v4 = vertices.Num() - 1;
							}
							else
							{
								v4 = vFind011;
							}
							//***************************************************************

							addTriangle(v1, v2, v3);
							addTriangle(v1, v3, v4);
						}
					}
				}
			}
		}
	}
	TArray<FColor> colors;

	TArray<FProcMeshTangent> tangents;

	mesh->CreateMeshSection(0, vertices, triangles, TArray<FVector>(), TArray<FVector2D>(), colors, tangents, true);
}

Problem jest jednak z tym, że generuje się to trochę czasu. Najwięcej tego czasu zżera miejsce, gdzie obliczam noiseXplus, noiseXminus itd. zaraz pod komentarzem "//Jeżeli od dowolnej strony jest odkryty". Kod działa w ten sposób, że generuje chunk 16/16/16 składający się z sześcianów, coś ala minecraft. Generuje on niekończące się jaskinie 3d. Samo generowanie siatki wygląda w ten sposób, że dla każdego sześcianu muszę obliczać szum perlina 7 razy. Dla samego sześcianu, a potem sprawdzam czy od jakiejś strony nie przylega inny sześcian, dla których również muszę obliczysz szum. Jest to strasznie zasobożerny algorytm, czy moglibyście podsunąć mi jakiś inny pomysł? Mam też inny pomysł, by to wszystko wpisać w tablicę i obliczać dodatkowo szum jedynie dla "obrzeży" tej tablicy, ale może macie jakieś inne, lepsze rozwiązanie?

Szybki edit: Wypróbowałem drugie rozwiązanie z tablicą i działa szybciej, ale efekt mnie nie zadowala

1
komentarz 20 września 2019 przez tkz Nałogowiec (42,000 p.)
Problem to jest taki, że tak funkcja ma 360 linii... Za 3 miesiąca nie będziesz mógł nic tu zmienić, bo nie będziesz wiedział jak.
komentarz 20 września 2019 przez Avernis Nałogowiec (27,400 p.)
Dlatego proszę o pomoc z refaktoryzacją
komentarz 20 września 2019 przez DragonCoder Nałogowiec (36,500 p.)

Kod działa w ten sposób, że generuje chunk 16/16/16 składający się z sześcianów, coś ala minecraft. Generuje on niekończące się jaskinie 3d. Samo generowanie siatki wygląda w ten sposób, że dla każdego sześcianu muszę obliczać szum perlina 7 razy. Dla samego sześcianu, a potem sprawdzam czy od jakiejś strony nie przylega inny sześcian, dla których również muszę obliczysz szum.

Nie mozesz zrobic tu jednej funkcji, ktora jest odpowiedzialna tylko za generowanie jednego szecianu i wstawic w petla, ktora jak dla mnie moze byc kolejna funkcja. I pozniej sam algorytm szumu perlina wstawic w jedna funkcje? 

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
1 odpowiedź 607 wizyt
pytanie zadane 16 sierpnia 2016 w C i C++ przez Informatyk# Obywatel (1,060 p.)
0 głosów
5 odpowiedzi 497 wizyt
pytanie zadane 17 stycznia 2016 w C i C++ przez Informatyk# Obywatel (1,060 p.)
0 głosów
2 odpowiedzi 239 wizyt

92,454 zapytań

141,262 odpowiedzi

319,089 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...