W wielu aplikacjach, gdzie napotyka się na problem generowania terenu, pojawia się problem detekcji, aby np. postać, którą stworzymy, nie mogła wychodzić na zbyt strome zbocza. Metod na rozwiązanie tego problemu jest kilka, ja postaram się tutaj przedstawić prostą i skuteczną, a przede wszystkim dość uniwersalną metodę, która w małych projektach powinna się doskonale sprawdzić.Postawione przed nami zadanie, to na wygenerowanym z heightmap’y terenie, wykryć kiedy kolejny ruch naszego aktora (postaci, pojazdu itp.), nie będzie możliwy właśnie ze względu na przekroczenie stromości vertexa, w którego kierunku chcemy zmierzać. Do wygenerowania terrenu, wykorzystamy sample przygotowany przez twórców XNA: Heightmap Collision with Normals, który pozwoli wygenerować nam stosowny model terenu i wyliczy normal’e dla wszystkich vertexów.
Koncepcję, która przyjąłem, jest sprawdzanie, czy vertex w konkretnym punkcie, a właściwie normal do niego przypisany, jest nachylony do płaszczyzny pod odpowiednim kątem, który dobrany został eksperymentalnie (określony jest przez współczynnik i zależy od wielkości wygenerowanych vertexów i skali terenu).
Kluczem do wyliczania stromości, jest metoda, która jest składową klasy terrain (w moim przypadku dziedziczy po DrawableGameComponent i posiada jako składową, klasę HeightMapInfo z ww. przykładu), która to z kolei w zależności od spełnienia warunku stromości wyliczonego w ww. sposób, zwraca bool.
Jej postać jest następująca:
public bool bluff(Vector3 position) { Vector3 normal; heightMapInfo.GetHeightAndNormal(position, out position.Y, out normal); Vector3 angle; Vector3 plane = new Vector3(1, 0, 1); normal.Normalize(); Vector3.Cross(ref plane, ref normal, out angle); angle.Normalize(); if (Math.Abs(angle.Y) < 0.45f) return true; else return false; }
Użycie:
// metoda update, reakcja na klawisz if (terrain.heightMapInfo.IsOnHeightmap(newSpherePosition) && terrain.bluff(newSpherePosition)) { // zmień pozycje i wykonaj opcjonalnie jakieś akcje } else { // nie zmieniaj pozycji }
Innymi metodami, które można zastosować w tym przypadku to mapa kolizji (rejonów po których można się poruszać bądź też nie), czy też np. podpięcie systemu fizyki, który wykonał by "brudną robotę" za nas. Zaletą tego rozwiązania oprócz prostoty, jest jego automatyka - raz zaimplemetowany, działa zawsze. Jestem pewien, że można by jeszcze udoskonalić zaprezentowaną metodę, zatem zainteresowanych zachęcam do przedstawienia swoich metod rozwiązania tego problemu, w komentarzach.
Fotografia: [ Link ]
2 odpowiedzi na “XNA: Detekcja stromych zboczy terenu”
Hello !!
I see that you are using my licensed photo in your website , however I don’t see any credits to my name , I am glad you liked my photo but I request to be credited for my name in your blog
thank you .
ilker ender.
Ofcourse I did – check link at the end of post after „Fotografia” with direct to flickr page, where user can find information about You.