2011-01-02 16 views
6

Tworzę klon Minecraft jako mój pierwszy projekt OpenGL i utknąłem w części wyboru pudełka. Jaka byłaby najlepsza metoda dokonania rzetelnego wyboru pudełka?Najlepsza metoda wyboru pudełka dla klona Minecrafta

Przeszedłem przez niektóre algorytmy AABB, ale żadne z nich nie wyjaśnia wystarczająco dobrze, co dokładnie robią (szczególnie te super podrasowane) i nie chcę używać rzeczy, których nie rozumiem.

Ponieważ świat składa się z kostek użyłem octrees usunąć pewne obciążenie obliczeniami ray odlewanych, w zasadzie jedyną rzeczą, potrzebne jest to funkcja:

float cube_intersect(Vector ray, Vector origin, Vector min, Vector max) 
{ 
    //??? 
} 

Promień i pochodzenie są łatwo uzyskać z

Vector ray, origin, point_far; 
double mx, my, mz; 

gluUnProject(viewport[2]/2, viewport[3]/2, 1.0, (double*)modelview, (double*)projection, viewport, &mx, &my, &mz); 
point_far = Vector(mx, my, mz); 
gluUnProject(viewport[2]/2, viewport[3]/2, 0.0, (double*)modelview, (double*)projection, viewport, &mx, &my, &mz); 
origin = Vector(mx, my, mz); 
ray = point_far-origin; 

min i max to przeciwległe wierzchołki sześcianu.

Nie jestem nawet pewien, czy to jest właściwy sposób, biorąc pod uwagę liczbę kostek, które musiałbym sprawdzić, nawet z ośmioma.

Próbowałem również gluProject, działa, ale jest bardzo niewiarygodne i nie daje mi wybraną twarz sześcianu.


EDIT

Więc to co zrobiłem: obliczyć położenie w przestrzeni z promieniem:

float t = 0; 
for(int i=0; i<10; i++) 
{ 
    Vector p = ray*t+origin; 
    while(visible octree) 
    { 
     if(p inside octree) 
     { 
      // then call recursive function until a cube is found 
      break; 
     } 
     octree = octree->next; 
    } 
    if(found a cube) 
    { 
     break; 
    } 
    t += .5; 
} 

To rzeczywiście zaskakująco szybko i zatrzymuje się po raz pierwszy znaleziono kostka .

alt text

Jak widać promień musi przejść koryta wielu octrees zanim znajdzie Cube (faktycznie położeniu w przestrzeni) - istnieje krzyżyk na środku ekranu. Im niższy stopień kroku, tym dokładniejszy jest wybór, ale także wolniejszy.

Odpowiedz

5

Praca z pudełkami jako prymitywami to przesada w wymaganiach dotyczących pamięci i mocy obliczeniowej. Kostki są dobre do renderowania, a nawet tam można znaleźć bardziej zaawansowane algorytmy, które dają lepszy obraz końcowy (kostki marszowe). Grafika Minecrafta jest bardzo prymitywna w tym sensie, ponieważ renderowanie wokseli istnieje już od dawna i dokonano znacznego postępu.

Zasadniczo powinieneś wykorzystać fakt, że wszystkie twoje pudełka są równomiernie rozmieszczone i tego samego rozmiaru. Są to tak zwane woksele. Raycasting w siatce jest trywialne w porównaniu do tego, co masz - test AABB o szerokim zakresie fazowym i test fazy wąskofazowej. Sugeruję, abyś zbadał nieco na temat wokseli i wokseli ustawiania wykrywania kolizji/raycasting, ponieważ znajdziesz oba algorytmy, które są łatwiejsze do wdrożenia i które działałyby szybciej.

+0

Kopiowanie wklejono to, co powiedziałeś do Google, i okazało się, że: http://www.metanetsoftware.com/technique/tutorialB.html Dzięki, o wiele lepiej niż moje rozwiązanie. – Solenoid

+0

Zgadzam się .. Pracowałem na klonie dla Xboksa i odkryłem, że przetwarzanie wierzchołków jest intensywne. Przełączono na maszerujące kostki dla mojej następnej gry i działa znacznie szybciej (jako aplikacja chrome w javascript!) [Mine mars] (http: // youtu.be/_oML6USPs20) –

0

Nie potrzebujesz żadnej jawnej struktury ósemkowej w pamięci. Wszystko, czego potrzeba, to bajt [,,]. Po prostu generuj 8 dzieci w pudełku leniwie podczas wyszukiwania (jak silnik szachowy generuje stany gier dla dzieci).

0

Twierdzę również, że nie trzeba polegać na faktycznych raycastach, aby określić, co należy renderować. Biorąc pod uwagę, że jesteś w predefiniowanym składzie siatki, naprawdę nie jesteś zakładnikiem "dokładnie widocznych" wymagań.Jeśli można śledzić położenie aparatu i przeznaczyć kompas NSWE niektórych rodzajów można także używać, aby określić, czy bufor GPU powinien nawet rozważyć szereg wierzchołek dla renderowania ..

omówię tę teorię tu szczegółowo https://stackoverflow.com/a/18028366/94167

Ale korzystając z ustawienia Octree i Camera + odległość/ograniczenia kamery, w zasadzie wiesz, co użytkownik widzi, nie musząc uciekać się do raytrace (s) dla dokładnych? Jeśli możesz skonsolidować trójkąty w większe w celu renderowania, a następnie użyć tekstury, aby przełamać widoczność dużego tyłu do kształtu sześciennego (nieznacznie z ręki), znacznie zmniejszysz liczbę wierzchołków. Wtedy jest to tylko kwestia renderowania kadłuba i śledzenia tego, jaki jest twój kierunek i gdzie znajduje się xyz, dzięki czemu możesz pozbyć się twarzy, które nie powinny być wyświetlane, ponieważ będzie to miało minimalny wpływ na wydajność (szczególnie jeśli twoje shadery wykonują również część pracy)

Eksperymentuję dalej, śledząc punkt środkowy kamery, aby określić jej poziomy punkt ogniskowania, a następnie określić kąt, który z kolei określa głębokość kawałek, który prawdopodobnie zobaczysz w kierunku, w którym się znajduje.

Powiązane problemy