Tôi đã dành một vài tuần cho vấn đề này và dường như không tìm được giải pháp phù hợp và cần một số lời khuyên.LWJGL - Các sự cố khi triển khai 'cuộn' trong Máy ảnh 6DOF sử dụng quaternions và ma trận dịch
Tôi đang làm việc để tạo lớp Máy ảnh bằng LWJGL/Java và đang sử dụng Quaternions để xử lý vòng bi (yaw), xoay vòng và xoay. Tôi muốn máy ảnh này xử lý tất cả 6 độ chuyển động trong không gian 3D và cuộn. Bearing, Pitch and Roll là tất cả các quaternions. Tôi nhân chúng thành một quaternion 'thay đổi', và tạo ra một ma trận dịch từ đó. Tôi đặt nó trong một bộ đệm float, và nhân ma trận modelview bởi bộ đệm của tôi chứa ma trận xoay.
Tôi có thể có vòng bi và vòng quay để hoạt động bình thường, nhưng khi tôi triển khai cuộn, tôi đang gặp sự cố. Chủ yếu, xoay quanh trục Z (cán) dường như không hoạt động. Khi bao giờ tôi "cuộn" máy ảnh, nó dường như cuộn quanh trục Z toàn cầu thay vì trục hướng máy ảnh cục bộ. Tôi thường có thể nhận được 2 trong số 3 để làm việc tùy thuộc vào thứ tự tôi nhân các quaternions, nhưng tôi không thể làm cho họ làm việc cùng nhau.
Vì tất cả đều hoạt động độc lập, tôi giả định có điều gì đó sai với phương pháp định hướng của tôi, nơi tôi kết hợp chúng và tạo ma trận xoay vòng. Tôi đang gặp vấn đề dán toàn bộ lớp trong, vì vậy đây là những phương pháp và tuyên bố liên quan đến luân chuyển:
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, tec non, và Matrix4f là mọi tầng lớp LWJGL, không được tùy chỉnh. Vì vậy, câu hỏi của tôi là, cho 3 Quaternions đại diện cho Bearing, Pitch và Roll, làm thế nào để tôi sửa đổi ma trận ModelView để biểu diễn chính xác những phép quay này?
EDIT: Tôi cảm thấy điều này rất gần. Xem liên kết Gist trong bình luận của RiverC. Sau khi xoay quá nhiều độ, chế độ xem nhảy xung quanh rất nhiều trước khi trở lại bình thường khi lăn. Ý chính của nó là ở đó, nhưng nó vẫn hơi tắt.
Cảm ơn bạn đã cập nhật. Đã không chạm vào mã này trong một thời gian, vì vậy tôi đang trở lại với tốc độ với LWJGl. Tôi nghĩ rằng tôi gần gũi. Sau khi thực hiện các thay đổi và thay đổi do gsimard đề xuất, tôi đang tiến gần hơn. Tuy nhiên, khi ngáp (mang trong câu hỏi) là 0, sân là tốt. Khi ngáp ở 180, độ dốc được đảo ngược (thay vào đó, độ cao sẽ di chuyển máy ảnh xuống). Ngoài ra, quay trở nên rời rạc sau khi quay khoảng 20 độ. Nếu tôi tiếp tục xoay nó ra. Vì vậy, một cái gì đó vẫn không hoàn toàn đúng. Tôi sẽ đặt mã trên github và cập nhật câu hỏi này vào tối nay. Tôi nghĩ nó gần như ở đó. Cảm ơn một lần nữa. – framauro13
Tại sao bạn làm công cụ cho ma trận xoay sau khi tạo nó? Bạn sẽ có thể gửi một Mat4 trực tiếp đến Shader và sử dụng nó để nhân các đỉnh của cảnh mà không sửa đổi nó. Ý tôi là, '// đặt hướng' một phần của mã. Nó có vẻ như bạn đang cố gắng sử dụng để bù đắp cho máy ảnh thông qua phép nhân, nhưng trong kinh nghiệm của tôi, điều này đã bị đánh và bỏ lỡ. Hãy thử bỏ điều đó. –
Tôi * nghĩ * lý do tôi đã làm điều đó ban đầu là để tôi có thể tổng hợp véc tơ hướng với vectơ mắt để tạo ra một vectơ tương tác với các vật thể trên thế giới. Một 'chọn' véc tơ nhiều hơn hoặc ít hơn. Ngoài ra, tôi đã khắc phục vấn đề với lật sân. Tôi đổi thứ tự của mang và pitch, do đó, dòng đọc 'Quaternion.mul (Quaternion.mul (cuộn, mang, thay đổi), pitch, thay đổi);' Vẫn đang cố gắng tìm ra lý do tại sao cuộn được wonky sau khi lăn một số số tiền. – framauro13