Autor Wątek: Jak odwrócić trójkąty w triangle strip?  (Przeczytany 1397 razy)

Offline Reg

  • Administrator
    • Adam Sawicki - Home Page

# Listopad 06, 2012, 09:45:01
Jest taka operacja na siatkach jak Flip Triangles - odwrócenie trójkątów, żeby kolejność wierzchołków w nich była odwrotna, co ma znaczenie, kiedy włączony jest Backface Culling. Załóżmy, że siatka posiada bufor indeksów. Wtedy w przypadku topologii Triangle List operacja jest prosta - dla każdych 3 indeksów tworzących trójkąt trzeba zamienić pierwszy z ostatnim:

for(int i = 0; i < indexCount; i += 3)
  std::swap(Indices[i], Indices[i+2]);

Równie dobrze zadziała zwykłe odwrócenie kolejności całego bufora indeksów:

std::reverse(Indices.begin(), Indices.end());
A co w przypadku topologii Triangle Strip? Myślę, próbuję sobie rozrysować i nijak nie wychodzi mi algorytm, który pozwoliłby odwrócić trójkąty w takiej siatce. Odwrócenie kolejności wszystkich indeksów nie działa - trójkąty zostają zorientowane tak jak były (przynajmniej w przypadku patrzystej liczby trójkątów w stripie). Zamiana pierwszego i trzeciego wierzchołka w pierwszym trójkącie stripa też nie działa - siatka się psuje.

Dodatkowo chcę używać indeksu restartującego 0xFFFF, ale to już tutaj nieważne.

Offline Mr. Spam

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

Offline albireo

  • Użytkownik

# Listopad 06, 2012, 10:15:01
Tak na szybko rozrysowując sobie, wychodzi mi, że wystarczy zdublować pierwszy wierzchołek. Przy nieparzystej liczbie trójkątów możne też odwrócić kolejność wszystkich wierzchołków.

Offline sanyol

  • Użytkownik

# Listopad 06, 2012, 19:02:58
Nalezy zamienic kolejnosc w kazdych kolejnych 2 indexach. Akurat dzisiaj musialem zrobic dokladnie to samo no i ta metodą mi sie to udalo

for(int i=0;i<IndexList.size()-1;i+=2)
{
int iTemp = IndexList[i];
IndexList[i] =  IndexList[i+1];
IndexList[i + 1] =  iTemp ;
}

Offline Reg

  • Administrator
    • Adam Sawicki - Home Page

# Listopad 06, 2012, 22:21:27
sanyol: Wypróbowałem Twoją metodę. Niestety nie działa, kiedy siatka zawiera zdegenerowane trójkąty mające stanowić przejście do nowego stripa (stosowane zamiast strip-cut indeksu).

Na przykład chcemy mieć strip 2 trójkątów, dalej niewidoczne przejście i jeden dodatkowy trójkąt. W tym celu wpisujemy indeksy:
0, 1, 2, 3, 3, 4, 4, 5, 6
Po zastosowaniu Twojego algorytmu to niewidoczne przejście ze zdegenerowanych trójkątów zapełni się błędnymi trójkątami.

albireo: Ostatecznie Twoja metoda zadziałała. Mając daną siatkę z topologią Triangle Strip i cały bufor wierzchołków (kiedy nie ma bufora indeksów) albo też fragment bufora indeksów między strip-cut indeksami (tworzący jeden strip), algorytm na Flip Triangles napisałem taki:

template<typename T>
void CMesh::FlipTriangleStripInArray(std::vector<T>& values, size_t begIndex, size_t endIndex)
{
    const size_t count = endIndex - begIndex;
    if(count < 3) return;
    // Number of elements (and triangles) is odd:
    // Reverse elements.
    if(count % 2)
        std::reverse(values.begin() + begIndex, values.begin() + endIndex);
    // Number of elements (and triangles) is even:
    // Repeat first element.
    else
        values.insert(values.begin() + begIndex, values[begIndex]);
}