Aby zasymulować środowisko wykorzystamy voxel space. W środowisku będziemy rozpatrywać tylko jedną cechę - zacienienie.
Klasa environment zawiera voxel space z informacją o zacienieniu.
Funkcja addShadow implementuje metodę shadow propagation. Najpierw zwiększa wartość cienia w zadanej pozycji. Następnie przechodzi w pentlach w dół, zmniejszając z każdym poziomem siłę cienia, ale zwiększając szerokość oddziałowywania.
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);
(...)
}
}
}
Zwraca siłę cienia w zadanej pozycji
Sprawdza, czy dane współrzędne się mieszczą w voxel space
bool inVoxelSpace(int a, int b, int c)
{
return (a<sizeX&&a>=0&&b<sizeY&&b>=0&&c<sizeZ&&c>=0);
}
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;
}
Otwórz Unity Project, wersję na te ćwiczenia. Następnie otwórz scenę "Pipe Model"
Do objektu shadowBox jest przypięty skrypt Cast Shadow. Otwórz ten skrypt.
Zmodyfikuj skrypt, tak aby ten obiekt rzucał cień w dół.
W objekcie inShadow jest skrypt receiveShadow
Zmodyfikuj skrypt - jak na ten objekt spadnie cień, to zmień materiał na inShadow, jak nie będzie w cieniu, to na noShadow
Wybierz objekt tree (001)
Jeśli nie jest ustawione, to ustaw odpowiednią ścieżkę (L-System Path) do ShadowModel.txt
Uruchom grę i przejdź kilka kroków (Load File na start i Evaluate - krok)
Gałęzie w cieniu nadal się rozwijają. Wylicz zacienienie do L-Systemu
Skrypt TurtleLSystemEnvironment, funkcja lightDirection (20 linijka), od 38 linijki
Zacienienie mierzymy w prostopadłościanie wokół obecnego elementu (2*lookForLightLength x lookForLightLength x 2*lookForLightLength)
Transformacja z obecną pozycją (transformation*resultTransformation) funkcja transformacja.ExtractPosition() zwraca pozycję dla transformacji
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)
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