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

135 lines
5.4 KiB
Markdown

# 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<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.
```C#
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
<img src="images/treesinenvironment/shadowBox.gif" alt="shadowBox" style="zoom:50%;" />
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
<img src="images/treesinenvironment/inShadow.gif" alt="inShadow" style="zoom:50%;" />
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
<img src="images/treesinenvironment/treeshadow.png" alt="treeshadow" style="zoom:33%;" /><img src="images/treesinenvironment/treeshadowgreen.png" alt="treeshadowgreen" style="zoom:33%;" /><img src="images/treesinenvironment/treeshadow.png" alt="treeshadow" style="zoom:33%;" />
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**)
<img src="images/treesinenvironment/treebox.png" alt="treebox" style="zoom:50%;" />
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
<img src="images/treesinenvironment/manytrees.png" alt="manytrees" style="zoom:50%;" />
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