Autor Wątek: animacja szkieletowa, wykrywanie kolizji  (Przeczytany 6513 razy)

Offline Goliatus

  • Użytkownik
    • Warsztat - tworzenie gier

# Styczeń 17, 2006, 23:59:43
Pytanie musi mieć dłuższą postać i będę wdzięczny za przeczytanie całości przed udzieleniem odpowiedzi ;)

Zaczne od tego, że nie chce robić tego w ten sposób:

wykonajRuch(0.10d); // 0.10d to byłby stała delta czasu
sprawdźCzySięPrzecinają();

Animacja jest podzielona na klatki i mamy zwyklą liniową interpolacje wartości kątów pomiędzy dwoma klatkami. Teraz nie jestem pewien, czy to co chcę osiągnąć jest wykonalne.

Otóż załóżmy, że mamy jeden wymiar i dwa odcinki na osi, które są animowane tzn. się poruszają i zmieniają długość w różny sposób. Jak się dowiedzieć kiedy one się zetkną? Mozna to zrobić w sposób, który zaprezentowałem na początku, a można inaczej(w jednym wymiarze to łatwo sobie wyobrazić).

Jest sobie jakaś funkcja f:R->RxR, która mówi jaką postać przyjmie odcinek (a,b) po jakimś czasie animacji. Dla każdego z odcinków i animacji jest osobna funkcja. Żeby wykryć kiedy odcinki się zetkną wystarczy obliczyć obrazy tych funkcji, znaleźć ich punkty wspólne(jakieś (a,b)) a następnie obliczyć przeciwobraz tych punktów, którym będzie poszukiwany czas.
Zaleta jest oczywista, bo mamy stały czas wykonywania i nie musimy za każdym razem sprawdzać czy odcinki się przecinają. Dla matematyka obliczenie tego czasu to nie problem jeśli ma podane wzory funkcji. Dla kodera to już troche trudniejsza sprawa i dlatego założyłem ten wątek :)
W tym jednowymiarowym przypadku rzecz sprowadza się do wygenerowania określonej liczby(w zależności od tego jaki zakres czasu wybieramy) dwuwymiarowych odcinków i policzeniu punktów, w których się przecinają. Jedną ze współrzędnych tych punktów, będzie czas przecięcia.

Docelowo chciałbym mieć to samo dla animacji szkieletowej w trzech wymiarach. Czy jest to wykonalne i jak do tego najlepiej podejść? Sprawe upraszcza to, że jak napisałem wcześniej, badany będzie czas pomiędzy dwoma klatkami animacji oraz to, że modele są uproszczone do trójwymiarowych odcinków.

Im bardziej rozgałęziony jest szkielet tym problem wydaje się coraz bardziej awykonalny, bo jak obliczyć tą całą geometrie na podstawie obrotów kości w czterech wymiarach i później liczyć punkty przecięcia?

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

aod

  • Gość
# Styczeń 18, 2006, 15:04:29
Do czego ci to jest potrzebne:
a) kolizja kość-kość w modelu
b) kolizja trójkąt-trójkąt w modelu
c) czy też kolizja model-otoczenie
d) coś innego?

W przypadku a) i b) najsensowniejszym rozwiązaniem jest przeliczenie sobie przecięć wcześniej (np. wyznaczenie par obiektów które mogą ze sobą kolidować, dla każdej klatki) i zapisanie ich w pliku z modelem.

Cytuj
Żeby wykryć kiedy odcinki się zetkną wystarczy obliczyć obrazy tych funkcji, znaleźć ich punkty wspólne(jakieś (a,b)) a następnie obliczyć przeciwobraz tych punktów, którym będzie poszukiwany czas.
Ładnie to brzmi, niestety rzeczywistość jest brutalna ;D. Przede wszystkim dla znakomitej większości funkcji nie da się obliczyć przeciwobrazu bo nie są one odwracalne. Zamiast tego możesz szukac przecięć w przestrzeni (N+1)D (dodając czas jako N+1-szą współrzędną). Wynik można zdefiniować jakoś tak:
Kolizje = { Przecięcie ( Obraz Fi, Obraz Fj ) : i,j należą do <1,N> oraz i!=j } gdzie:
N=ilość funkcji
Fi(t)=(Si(t),t)      Si(t) zwraca koordynaty odcinka w czasie t
Jeśli to się wogóle da zrobić  ;D to mogę cię zapewnić że jest to cholernie trudne i wogóle nie masz się co za to zabierać jeśli nie jesteś specem z matematyki obliczeniowej (metod numerycznych).
Konkludując, powinieneś zrobić to w mniej-więcej taki sposób:
wykonajRuch(0.10d); // 0.10d to byłby stała delta czasu
sprawdźCzySięPrzecinają();
;D
« Ostatnia zmiana: Styczeń 18, 2006, 15:07:32 wysłana przez nadult »

Offline Goliatus

  • Użytkownik
    • Warsztat - tworzenie gier

# Styczeń 21, 2006, 16:12:11
Właściwie już tylko jednej kwestii nie jestem pewien. Czy złożenie kilku obrotów w czasie da kilka płaszczyzn czy jedną bryłe w 4D?

aod

  • Gość
# Styczeń 21, 2006, 18:24:42
Właściwie już tylko jednej kwestii nie jestem pewien. Czy złożenie kilku obrotów w czasie da kilka płaszczyzn czy jedną bryłe w 4D?
Łatwo można to sobie wyobrazić jeśli obracasz obiekty w 2D: obracanie odcinka dałoby ci ciągłą (jak ciągłą zależy od tego jak interpolujesz obroty), pogiętą powierzchnię, a obracanie wielokąta bryłę. W 3D jest tak samo: obracanie odcinka w 3D tez da ci jakąś powierzchnię a wielokąt bryłę z tą różnicą że nie będą one leżały na jednej płaszczyźnie prostopadłej do osi czasu; tzn. będą mogły być trochę bardziej pokrzywione  ;).

aod

  • Gość
# Styczeń 21, 2006, 18:54:16
Sorry, moze sie czepiam :P, ale co to znaczy?
Cytat: Goliatus
Żeby wykryć kiedy odcinki się zetkną wystarczy obliczyć obrazy tych funkcji, znaleźć ich punkty wspólne(jakieś (a,b)) a następnie obliczyć przeciwobraz tych punktów, którym będzie poszukiwany czas.
Raz, ze przeciwobraz jest zbiorem, a dwa, ze nie rozumiem, przeciwobraz czego chcialbys liczyc?

Offline Goliatus

  • Użytkownik
    • Warsztat - tworzenie gier

# Styczeń 22, 2006, 12:17:36
Właściwie już tylko jednej kwestii nie jestem pewien. Czy złożenie kilku obrotów w czasie da kilka płaszczyzn czy jedną bryłe w 4D?
Łatwo można to sobie wyobrazić jeśli obracasz obiekty w 2D: obracanie odcinka dałoby ci ciągłą (jak ciągłą zależy od tego jak interpolujesz obroty), pogiętą powierzchnię, a obracanie wielokąta bryłę. W 3D jest tak samo: obracanie odcinka w 3D tez da ci jakąś powierzchnię a wielokąt bryłę z tą różnicą że nie będą one leżały na jednej płaszczyźnie prostopadłej do osi czasu; tzn. będą mogły być trochę bardziej pokrzywione  ;).
W takim razie wystarczy wygenerować siatke trójkątów i znaleźć, te które się przecinają.

Sorry, moze sie czepiam :P, ale co to znaczy?
Cytat: Goliatus
Żeby wykryć kiedy odcinki się zetkną wystarczy obliczyć obrazy tych funkcji, znaleźć ich punkty wspólne(jakieś (a,b)) a następnie obliczyć przeciwobraz tych punktów, którym będzie poszukiwany czas.
Raz, ze przeciwobraz jest zbiorem, a dwa, ze nie rozumiem, przeciwobraz czego chcialbys liczyc?
Przeciwobraz zbioru jest zbiorem, a przeciwobraz elementu jest elementem.

aod

  • Gość
# Styczeń 22, 2006, 14:35:13
Ale przeciez masz kilka funkcji, wzgledem ktorej chcesz liczyc przeciwobraz? No i nie wiem od kiedy przeciwobraz elementu jest elementem, skoro moze byc ich wiecej niz jeden?

Offline Goliatus

  • Użytkownik
    • Warsztat - tworzenie gier

# Styczeń 22, 2006, 16:57:40
A w jakim przypadku będzie ich więcej niż jeden?

aod

  • Gość
# Styczeń 22, 2006, 17:44:07
No wystarczy, zeby funkcja nie byla roznowartosciowa...

Offline Goliatus

  • Użytkownik
    • Warsztat - tworzenie gier

# Styczeń 22, 2006, 19:33:49
Masz racje, ale piszesz nie na temat ;D

aod

  • Gość
# Styczeń 22, 2006, 19:50:14
No na temat, bo zupelnie nie rozumiem tego, co napisales w pierwszym poscie :)

Offline Goliatus

  • Użytkownik
    • Warsztat - tworzenie gier

# Styczeń 22, 2006, 20:33:53
nadult zrozumiał, lub pomimo tego, że to mogło być niezrozumiałe wydedukował o co chodzi i przeszedł do meritum sprawy i za to go serdecznie pozdrawiam ;)

Offline naleth

  • Użytkownik

# Styczeń 22, 2006, 22:08:02
Nie zapominaj, że wykrywanie kolizji dla poszczególnych klatek nie będzie zachodziło tak bardzo często, bo lwia część geometrii będzie odpadała na testach wstępnych, np. AABB obiektów czy co tam sobie chcesz, następnie AABB poszczególnych klatek,  dopiero jeśli te uproszczone testy pokażą, iż istnieje szansa kolizji, zaczynasz się martwić, czy wystąpi ona przy danej klatce animacji. Biorąc pod uwagę dodatkowy fakt, że testów kolizji nie przeprowadza się w praktyce na siatkach w pełnej szczegółowości, tylko na siatkach uproszczonych i pewnych hierarchiach prostych brył, np. elipsoid czy prostopadłościanów, to jest to do zniesienia.