MWS/Opis.md
2021-09-16 19:44:41 +02:00

5.4 KiB

Trees in environment

W trakcie tych zajęć wykorzystamy voxel space do zasymulowania wpływu zacienienia na rozwój drzew.

Klasa Environment

Klasa environment znajduje się w Assets\Scripts\env i implementuje voxel space z informacją o zacienieniu. Zawiera ona następujące metody

addShadow

Funkcja addShadow implementuje algorytm shadow propagation. Przyjmuje ona wektor pozycji w przestrzeni świata i siłę zacienienia. Najpierw zwiększa wartość cienia w zadanej pozycji. Następnie przechodzi w pętlach w dół, zmniejszając z każdym poziomem siłę cienia, ale zwiększając szerokość oddziaływania.

for(int j = (int)voxelPosition.y; j >= 0; j--)
{
      for(int i = (int)voxelPosition.x-rotj; i <= (int)voxelPosition.x+rotj; i++)
      {
        for(int k = (int)voxelPosition.z-rotj; k <= (int)voxelPosition.z+rotj; k++)
        { 
            float secondaryStrength = 1.0f*strength;
            secondaryStrength = secondaryStrength / ((Mathf.Abs(k-(int)voxelPosition.z) + 1 + Mathf.Abs(i-(int)voxelPosition.x))/8.0f);
            (...)
        }
      }
}

shadowStrength

Zwraca siłę cienia w zadanej pozycji świata.

inVoxelSpace

Sprawdza, czy dane współrzędne voxela mieszczą się w voxel space.

bool inVoxelSpace(int a, int b, int c)
  {
    return (a<sizeX&&a>=0&&b<sizeY&&b>=0&&c<sizeZ&&c>=0);
  }

positionInVoxel i positionInWorld

Konwertuje positionInVoxel z pozycji w przestrzeni świata do pozycji w przestrzeni voxel space positionInWorld odwrotnie.

 public Vector3 positionInVoxel(Vector3 positionInWorld)

  {
    Vector3 voxelPosition = new Vector3(0.0f,0.0f,0.0f);
    positionInWorld -= gameObject.GetComponent<Transform>().position;
    voxelPosition.x = (int)(0.5f + (positionInWorld.x / voxelSize));
    voxelPosition.y = (int)(0.5f + (positionInWorld.y / voxelSize));
    voxelPosition.z = (int)(0.5f + (positionInWorld.z / voxelSize));
    return voxelPosition;
  }
  public Vector3 positionInWorld(Vector3 positionInVoxel)
  {
    return positionInVoxel*voxelSize+gameObject.GetComponent<Transform>().position;
  }

Zadanie 1

shadowBox
  1. Otwórz Unity Project, wersję na te ćwiczenia. Następnie otwórz scenę "Pipe Model"
  2. Do obiektu shadowBox jest przypięty skrypt Cast Shadow. Otwórz ten skrypt.
  3. Zmodyfikuj skrypt, tak aby ten obiekt rzucał cień w dół: Skrypt zawiera atrybut Environment environment, który obsługuje zacienienie w tej scenie. Wykorzystaj jego metodę addShadow(Vector3 position, sbyte strength) by dodać cień w miejscu, w którym znajduje się obiekt. Wykorzystaj metodę removeShadow(Vector3 position, sbyte strength), by usunąć cień, który powinien zniknąć, po przesunięciu obiektu.

Zadanie 2

inShadow
  1. Do obiektu inShadow podpięty jest skrypt receiveShadow
  2. Tak go zmodyfikuj, żeby jak na ten obiekt spadnie cień, to zmień materiał na inShadow, a jak nie będzie w cieniu, to na noShadow. Wykorzystaj metodę shadowStrength(Vector3 pos) obiektu environment, żeby odczytać stan zacieniowania.

Zadanie 3

treeshadowtreeshadowgreentreeshadow

  1. Wybierz obiekt tree (001)

  2. Jeśli nie jest ustawione, to ustaw odpowiednią ścieżkę (L-System Path) do ShadowModel.txt

  3. Uruchom grę i przejdź kilka kroków (Load File na start i Evaluate - krok)

  4. Gałęzie w cieniu nadal się rozwijają. Wylicz zacienienie do L-Systemu

    1. W skrypcie TurtleLSystemEnvironment uzupełnij metodę lightDirection (20 linijka), od 38 linijki

    2. Zacienienie mierzymy w prostopadłościanie wokół obecnego elementu (2*lookForLightLength x lookForLightLength x 2*lookForLightLength)

      treebox
    3. Zmienna objectTransformation zawiera transformację obecnego elementu. Po jej przekształceniu, pozycję można uzyskać funkcją transformacja.ExtractPosition()

  5. Wyślij wartość zacienienia do L-Systemu

#ignore + - \ / ^ &
#axiom
S(0,0)
#rules
S(a,c) : c>=50 -> S(a+1,0)
S(a,c) : c<50 -> G\(90)[-S(0,0)]S(0,0)

W L-Systemie wartość zacienienia jest opisywana przez drugi parametr, czyli c w powyższym kodzie. By zmodyfikować parametr musisz odwołać sie do zmiennej node, dokładniej do node.literal.values, które jest tablicą zawierającą parametry odczytywanego symbolu.

Zadanie 4

manytrees
  1. Dodaj do objektu Environment więcej drzew (Trees) i zobacz jak drzewa wpływają na siebie nawzajem.
  2. Napisz skrypt, który utworzy 9 drzew (po trzy w trzech rzędach) rozmieszczonych w równych odstępach, przetestuj różne odległości.
  3. Zobacz jak się w takim układzie rozwijają.

Zadanie 5 - domowe

Zintegruj L-System pipe model z wcześniejszych ćwiczeń z obsługą cienia.

Napisz L-System, który modeluje wybrany przez ciebie kształt drzewa. Kształt ma być twój indywidualny, ale możesz się wspomóc:

http://www.algorithmicbotany.org/papers/abop/abop.pdf