Saya mencoba untuk membiarkan pengguna aplikasi saya memutar objek 3D yang ditarik di tengah layar dengan menyeret jari mereka di layar. Gerakan horizontal di layar berarti rotasi di sekitar sumbu Y yang tetap, dan gerakan vertikal berarti rotasi di sekitar sumbu X. Masalah yang saya alami adalah bahwa jika saya hanya mengizinkan rotasi di sekitar satu sumbu objek berputar dengan baik, tetapi segera setelah saya memperkenalkan rotasi kedua objek tidak berputar seperti yang diharapkan.
Ini adalah gambar dari apa yang terjadi:
Sumbu biru mewakili sumbu tetap saya. Bayangkan layar memiliki sumbu biru tetap ini. Inilah yang saya ingin objek untuk memutar sehubungan dengan. Apa yang terjadi berwarna merah.
Inilah yang saya tahu:
- Rotasi pertama di sekitar Y (0, 1, 0) menyebabkan model bergerak dari ruang biru (panggil ruang ini A) ke ruang lain (sebut ruang ini B)
- Mencoba memutar lagi menggunakan vektor (1, 0, 0) berputar di sekitar sumbu x di ruang B TIDAK di ruang A yang bukan apa yang saya maksudkan.
Inilah yang saya coba, mengingat apa yang saya (pikirkan) saya tahu (tidak mengikutkan kata W untuk singkatnya):
- Putar pertama di sekitar Y (0, 1, 0) menggunakan Quaternion.
- Konversi rotasi Y Quaternion ke Matrix.
- Kalikan matriks rotasi Y dengan sumbu tetap saya x Vektor (1, 0, 0) untuk mendapatkan sumbu X dalam kaitannya dengan ruang baru.
- Putar sekitar X Vector baru ini menggunakan Quaternion.
Berikut kodenya:
private float[] rotationMatrix() {
final float[] xAxis = {1f, 0f, 0f, 1f};
final float[] yAxis = {0f, 1f, 0f, 1f};
float[] rotationY = Quaternion.fromAxisAngle(yAxis, -angleX).toMatrix();
// multiply x axis by rotationY to put it in object space
float[] xAxisObjectSpace = new float[4];
multiplyMV(xAxisObjectSpace, 0, rotationY, 0, xAxis, 0);
float[] rotationX = Quaternion.fromAxisAngle(xAxisObjectSpace, -angleY).toMatrix();
float[] rotationMatrix = new float[16];
multiplyMM(rotationMatrix, 0, rotationY, 0, rotationX, 0);
return rotationMatrix;
}
Ini tidak berfungsi seperti yang saya harapkan. Rotasi tampaknya bekerja, tetapi pada beberapa titik gerakan horizontal tidak berputar tentang sumbu Y, tampaknya berputar tentang sumbu Z.
Saya tidak yakin apakah pemahaman saya salah, atau jika ada hal lain yang menyebabkan masalah. Saya memiliki beberapa transformasi lain yang saya lakukan pada objek selain rotasi. Saya memindahkan objek ke tengah sebelum menerapkan rotasi. Saya memutarnya menggunakan matriks yang dikembalikan dari fungsi saya di atas, lalu saya menerjemahkan -2 ke arah Z sehingga saya bisa melihat objek. Saya tidak berpikir ini mengacaukan rotasi saya, tetapi di sini adalah kode untuk itu:
private float[] getMvpMatrix() {
// translates the object to where we can see it
final float[] translationMatrix = new float[16];
setIdentityM(translationMatrix, 0);
translateM(translationMatrix, 0, translationMatrix, 0, 0f, 0f, -2);
float[] rotationMatrix = rotationMatrix();
// centers the object
final float[] centeringMatrix = new float[16];
setIdentityM(centeringMatrix, 0);
float moveX = (extents.max[0] + extents.min[0]) / 2f;
float moveY = (extents.max[1] + extents.min[1]) / 2f;
float moveZ = (extents.max[2] + extents.min[2]) / 2f;
translateM(centeringMatrix, 0, //
-moveX, //
-moveY, //
-moveZ //
);
// apply the translations/rotations
final float[] modelMatrix = new float[16];
multiplyMM(modelMatrix, 0, translationMatrix, 0, rotationMatrix, 0);
multiplyMM(modelMatrix, 0, modelMatrix, 0, centeringMatrix, 0);
final float[] mvpMatrix = new float[16];
multiplyMM(mvpMatrix, 0, projectionMatrix, 0, modelMatrix, 0);
return mvpMatrix;
}
Saya sudah terjebak dalam hal ini selama beberapa hari. Bantuan sangat dihargai.
================================================== ================
MEMPERBARUI:
Membuat ini berfungsi di Unity sangatlah mudah. Berikut ini beberapa kode yang merotasi sebuah kubus yang berpusat pada titik asal:
public class CubeController : MonoBehaviour {
Vector3 xAxis = new Vector3 (1f, 0f, 0f);
Vector3 yAxis = new Vector3 (0f, 1f, 0f);
// Update is called once per frame
void FixedUpdate () {
float horizontal = Input.GetAxis ("Horizontal");
float vertical = Input.GetAxis ("Vertical");
transform.Rotate (xAxis, vertical, Space.World);
transform.Rotate (yAxis, -horizontal, Space.World);
}
}
Bagian yang membuat rotasi berperilaku seperti yang saya harapkan adalah Space.World
parameter Rotate
fungsi pada transformasi.
Jika saya bisa menggunakan Unity saya akan, sayangnya saya harus kode perilaku ini sendiri.