Tworzę grę, która wykorzystuje całą planetę do swojej mapy. Tesselowałem sferyczną planetę using this technique i teraz dodałem elementy sterujące aparatu.Obracanie kamery do punktu
Sfera ma wymiary 1 do -1, więc każdy punkt na kuli jest również znormalizowanym wektorem. W tym samym czasie jedna z sześciokątnych płytek, które tworzą kulę, jest "wybraną" płytką. Gracz może następnie przenieść zaznaczenie do sąsiednich płytek za pomocą D-pada. Mogą również samodzielnie obracać kamerę za pomocą analogowego drążka analogowego. Muszę wykonać dwie czynności w odniesieniu do wybranej płytki i kamery. Po pierwsze, muszę mieć możliwość przełączenia wyboru na kafelek znajdujący się najbliżej aparatu. Po drugie, muszę wyśrodkować kamerę na podświetlonym kafelku. Kula znajduje się na początku, a kamera znajduje się w punkcie (0,0,1). Silnik graficzny pozwala mi tylko obrócić kamerę wokół osi X i Y, więc aby rozwiązać pierwszy problem, używam kwaternionów do obracania punktu (0,0,1) wokół osi x, a następnie y, aby znaleźć punkt w 3D przestrzeń, w której aparat jest:
private Quaternion quat = new Quaternion(0,0,0,0);
private double[] output = new double[4];
private double[] cam = new double[3];
private double camX = 0;
private double camY = 0;
private double camZ = 1;
private double[] getCamPosition(){
quat.setAxisAngle(1, 0, 0, Math.toRadians(-graphicsEngine.getRotationX()));
quat.RotateVector(camX, camY, camZ, output);
cam[0] = output[0];
cam[1] = output[1];
cam[2] = output[2];
quat.setAxisAngle(0, 1, 0, Math.toRadians(-graphicsEngine.getRotationY()));
quat.RotateVector(cam[0], cam[1], cam[2], output);
cam[0] = output[0];
cam[1] = output[1];
cam[2] = output[2];
return cam;
}
i następnie porównać ich odległości od środka masy każdej płytki i położenia kamery i wziąć płytkę, która jest najbliżej będzie nowo wybrany dachówka.
Jednak, aby rozwiązać drugi problem, chcę zrobić odwrotność. Chcę wziąć środek ciężkości (który już jest w postaci znormalizowanego wektora) i dowiedzieć się, jaki jest obrót wokół osi X, a obrót wokół osi Y jest potrzebny, aby kamera znalazła się na środku.
W tej chwili "obróciłem kamerę z powrotem do punktu (0,0,1), a następnie uzyskałem kąt w osi X i osi Y między (0,0,1) i środkiem ciężkości i używając go do ponownego obrócenia kamery:
private double[] outputArray = new double[2];
/**
* Cam is always (0,0,1)
*/
public void centreOnSelected(double camX, double camY, double camZ){
selectedTile.getCentroidAngles(outputArray);
outputArray[0] -= Math.atan2(camZ, camY);
outputArray[1] -= Math.atan2(camX, camZ);
// this determines if the centroid is pointing away from the camera
// I.e. is on the far side of the sphere to the camera point (0,0,1)
if(!selected.getCentroidDirectionY(camX, camZ)){
outputArray[0] = -Math.PI - outputArray[0];
}
graphicsEngine.rotateCam(Math.toDegrees(outputArray[0]), Math.toDegrees(outputArray[1]));
}
aw selected
(klasy dachówka)
void getCentroidAngles(double[] outputArray){
outputArray[0] = Math.atan2(centroidZ, centroidY);
outputArray[1] = Math.atan2(centroidX, centroidZ);
}
problemem jest to nie działa, (oś X zawsze wydaje się być wyłączona) i jestem prawie pewien, że ma to związek z matematyką uzyskiwania kątów i robienia obrotowego. Uwaga: silnik graficzny obraca się najpierw wokół oś X, następnie wokół Y:
gl.glRotatef(mRotateX, 1, 0, 0);
gl.glRotatef(mRotateY, 0, 1, 0);
w centroidy są w odpowiednim miejscu, a aparat zdecydowanie obraca ją w odpowiednich ilościach, więc jestem pewien, że problem nie jest z silnikiem graficznym. Nie jest również ponowne ustawienie aparatu z powrotem do (0,0,1) jako Sprawdziłem to działa poprzez intensyfikację ramach programu
Mam również film do zilustrowania problemu:
http://www.youtube.com/watch?v=Uvka7ifZMlE
Przez wiele dni było to przyczyną problemów, więc jakakolwiek pomoc w uzyskaniu tego byłoby bardzo cenne!
Thanks James
Interesujące, dzięki! Rozumiem z krążeniem wokół, ale nigdy nie zdawałem sobie sprawy, że ma imię (znacznie mniej, tak zabawne jak twierdzenie Hairy Ball). Takie zachowanie podczas jazdy na kółkach nie jest niczym niezwykłym w grach komputerowych, w które grałem, i prawdopodobnie będzie tylko pomniejszać graficzną irytację podczas grania w moją grę. Wygląda jednak na to, że na razie będę musiał wyśrodkować/obrócić kamerę na środek ciężkości –