kullanarak bir 6DOF Kamerada 'roll' uygulayan problemler Bu konuya birkaç hafta harcadım ve uygun bir çözüm bulamıyorum ve bazı tavsiyelere ihtiyacım var gibi görünmüyor.LWJGL - Kuaterniyonlar ve bir çeviri matrisi
LWJGL/Java kullanarak bir Camera sınıfı oluşturmaya çalışıyorum ve rulman (yaw), pitch ve roll rotasyonlarını işlemek için Quaternions kullanıyorum. Bu kameranın 3D alandaki tüm 6 derecelik hareketleri gerçekleştirmesini ve yuvarlanmasını istiyorum. Rulman, Perde ve Rulo tüm kuaterniyonlardır. Onları bir 'değişim' kuaterniyonuna çarpar ve bundan bir çeviri matrisi oluşturur. Bunu bir float tamponuna koydum ve model matrisini, matrisini içeren arabamla çoğalıyorum.
Doğru şekilde çalışması için rulman ve pitch rotasyonlarını alabilirim, ancak ruloyu uygularken sorunlarım var. Temel olarak, Z ekseni etrafında dönen (haddeleme) işe yaramıyor. Fotoğraf makinesini "yuvarladığımda", yerel kamera yönü ekseni yerine global Z ekseni etrafında dönüyormuş gibi görünüyor. Ben genellikle quaternionları çarptığım sırasına göre 3'lük 2'yi işe alabilirim, ama onları birlikte çalışamıyorum.
Hepsi bağımsız çalıştığından, bunları birleştirip döndürme matrisi oluşturduğum yönlendirme yöntemimde bir sorun olduğunu varsayarak düşünüyorum. Sorunların bütün sınıf yapıştırarak yaşıyorum, işte rotasyona ilişkin yöntemler ve bildirimleri şunlardır:
private final static float DEGTORAD = (float)(Math.PI/180);
//Eye - position of the camera in the 3D world.
private Vector3f eye;
//Camera axis vectors, calculated each time reorient() is called.
//Initialized to global x, y, and z axis initially.
private Vector3f up;
private Vector3f right;
private Vector3f direction;
//Angles of rotation (in degrees)
private float pitchAngle;
private float bearingAngle;
private float rollAngle;
private Quaternion pitch;
private Quaternion bearing;
private Quaternion roll;
private FloatBuffer viewMatrixBuffer = BufferUtils.createFloatBuffer(16);
private Quaternion currentOrientation;
...
/**
* Change the bearing (yaw)
* @param bearing delta in degrees
*/
public void bearing(float bearingDelta){
bearingAngle += bearingDelta;
if(bearingAngle > 360){
bearingAngle -= 360;
}else if(bearingAngle < 0){
bearingAngle += 360;
}
bearing.setFromAxisAngle(new Vector4f(0f, 1f, 0f, bearingAngle * DEGTORAD));
bearing.normalise();
}
/**
* Change the pitch
* @param pitch delta in degrees
*/
public void pitch(float pitchDelta){
pitchAngle += pitchDelta;
if(pitchAngle > 360){
pitchAngle -= 360;
}else if(pitchAngle < 0){
pitchAngle += 360;
}
pitch.setFromAxisAngle(new Vector4f(1f, 0f, 0f, pitchAngle * DEGTORAD));
pitch.normalise();
}
/**
* @param initialRoll
*/
public void roll(float initialRoll) {
rollAngle += initialRoll;
if(rollAngle > 360){
rollAngle -= 360;
}else if(rollAngle < 0){
rollAngle += 360;
}
roll.setFromAxisAngle(new Vector4f(0, 0, 1, rollAngle * DEGTORAD));
roll.normalise();
}
/**
* Change direction to focus on a certain point in the world
* @param eye
*/
public void lookThrough(){
reorient();
GL11.glMultMatrix(viewMatrixBuffer);
}
public void reorient(){
//Multiply in order: bearing, pitch, roll. Non-commutative!
Quaternion change = new Quaternion();
Quaternion.mul(bearing, pitch, change);
Quaternion.mul(roll, change, change);
// orient the camera...
Matrix4f rotationMatrix = getRotationMatrix(change);
//Get the looking direction
direction.x = rotationMatrix.m20;
direction.y = rotationMatrix.m21;
direction.z = rotationMatrix.m22;
//Set the position
rotationMatrix.m30 = eye.x;
rotationMatrix.m31 = eye.y;
rotationMatrix.m32 = eye.z;
rotationMatrix.m33 = 1;
rotationMatrix.invert();
rotationMatrix.store(viewMatrixBuffer);
viewMatrixBuffer.rewind();
Vector3f.cross(new Vector3f(0,1,0), direction, null).normalise(right);
Vector3f.cross(right, direction, null).normalise(up);
}
Vector3f, Kuaterniyon ve Matrix4f tüm lwjgl sınıfları vardır, özel değil.
Bu yüzden sorum, Rulman, Perde ve Ruloları temsil eden 3 Kuaterniyon verildi, bu rotasyonları doğru olarak göstermek için ModelView matrisini nasıl değiştirebilirim?
DÜZENLEME: Bunun çok yakın olduğunu hissediyorum. RiverC'nin yorumunda Gist bağlantısını görün. Çok derece döndükten sonra görünüm, yuvarlanırken normale dönmeden önce etrafa atlar. Onun özü orada, ama hala biraz kapalı.
Güncelleme için teşekkürler. Bu koda bir süre dokunmadım, bu yüzden LWJGl ile hızlanmaya başlıyorum. Sanırım yakınım. Gsimard tarafından önerilen değişikliklerinizi ve değişikliklerinizi yaptıktan sonra, daha da yaklaşıyorum. Ancak, yaw (sorudaki) 0 olduğunda, zift iyidir. Sapw 180 olduğunda, perde tersine çevrilir (perdeli yukarı doğru kamerayı aşağı doğru hareket ettirir). Ayrıca, rotasyon yaklaşık 20 derece döndükten sonra sporadik hale gelir. Dönmeye devam edersem seviyelere çıkar. Yani bir şey hala doğru değil. Kodu github'a koyacağım ve bu soruyu bu gece daha sonra güncelleyeceğim. Sanırım neredeyse orada. Tekrar teşekkürler. – framauro13
Neden oluşturduktan sonra döndürme matrisine bir şeyler yapıyorsunuz? Bir Mat4'ü doğrudan Shader'a gönderebilmeniz ve onu sahnenin köşelerini değiştirmeksizin çoğaltmak için kullanabilmeniz gerekir. Demek istediğim, kodun '// yönünü belirle' kısmı. Kamerayı çarpma yoluyla dengelemek için kullanmaya çalışıyormuşsunuz gibi görünüyor, ama deneyimlerimde bu isabet ve özledim. Onu düşürmeyi dene. –
Ben * düşünüyorum * başlangıçta öyle yaptım ki, vektörü, vektörü, dünyadaki nesnelerle etkileşime geçmek için bir vektör oluşturmak için göz vektörüyle özetleyebilirim. Bir 'toplayıcı' vektör az ya da çok. Ayrıca, sorunu saygısız bir şekilde düzelttim. Yatak ve zift sırasını değiştirdim, böylece satır Quaternion.mul (Quaternion.mul (roll, rulman, change), pitch, change); Okumaya devam ediyor. Miktar. – framauro13