# 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. ```C# 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*. ```C# bool inVoxelSpace(int a, int b, int c) { return (a=0&&b=0&&c=0); } ``` ### positionInVoxel i positionInWorld Konwertuje `positionInVoxel` z pozycji w przestrzeni świata do pozycji w przestrzeni *voxel space* `positionInWorld` odwrotnie. ```C# public Vector3 positionInVoxel(Vector3 positionInWorld) { Vector3 voxelPosition = new Vector3(0.0f,0.0f,0.0f); positionInWorld -= gameObject.GetComponent().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().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 ```python #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