Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java LWJGL-实施问题';滚动';在使用四元数和平移矩阵的6自由度相机中_Java_Matrix Multiplication_Lwjgl_Quaternions_Rotational Matrices - Fatal编程技术网

Java LWJGL-实施问题';滚动';在使用四元数和平移矩阵的6自由度相机中

Java LWJGL-实施问题';滚动';在使用四元数和平移矩阵的6自由度相机中,java,matrix-multiplication,lwjgl,quaternions,rotational-matrices,Java,Matrix Multiplication,Lwjgl,Quaternions,Rotational Matrices,我在这个问题上花了几周时间,似乎找不到合适的解决方案,需要一些建议 我正在使用LWJGL/Java创建一个Camera类,并使用四元数来处理轴承(偏航)、俯仰和滚动旋转。我希望这台相机能够处理3D空间中所有6度的运动,然后滚动。轴承、俯仰和滚动都是四元数。我将它们相乘成一个“变化”四元数,并由此创建一个转换矩阵。我把它放在一个浮点缓冲区中,然后用包含旋转矩阵的缓冲区乘以modelview矩阵 我可以让轴承和俯仰旋转正常工作,但当我实现滚动时,我遇到了问题。主要来说,围绕Z轴旋转(滚动)似乎不起作

我在这个问题上花了几周时间,似乎找不到合适的解决方案,需要一些建议

我正在使用LWJGL/Java创建一个Camera类,并使用四元数来处理轴承(偏航)、俯仰和滚动旋转。我希望这台相机能够处理3D空间中所有6度的运动,然后滚动。轴承、俯仰和滚动都是四元数。我将它们相乘成一个“变化”四元数,并由此创建一个转换矩阵。我把它放在一个浮点缓冲区中,然后用包含旋转矩阵的缓冲区乘以modelview矩阵

我可以让轴承和俯仰旋转正常工作,但当我实现滚动时,我遇到了问题。主要来说,围绕Z轴旋转(滚动)似乎不起作用。当我“滚动”摄影机时,它似乎围绕全局Z轴而不是局部摄影机方向轴滚动。根据四元数相乘的顺序,我通常可以得到3个中的2个,但我不能让它们一起工作

因为它们都是独立工作的,所以我假设我的定向方法有问题,我把它们结合起来,建立一个旋转矩阵。我在粘贴整个类时遇到问题,因此以下是与旋转相关的方法和声明:

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;

/**
*更换轴承(偏航)
*@param方位角增量(度)
*/
公共空心轴承(浮动轴承三角形){
轴承角+=轴承三角洲;
如果(轴承角度>360){
轴承角-=360;
}否则如果(轴承角度<0){
轴承角度+=360;
}
轴承。从轴角度设置(新矢量4F(0f、1f、0f,轴承角度*DEGTORAD));
轴承。正常化();
}
/**
*改变音高
*@参数节距增量,单位为度
*/
公共空隙间距(浮动间距){
俯仰角+=俯仰角增量;
如果(俯仰角>360){
俯仰角-=360;
}否则如果(俯仰角<0){
俯仰角+=360;
}
从AxisAngle(新矢量4F(1f、0f、0f,俯仰角*DEGTORAD))设置俯仰角;
基音正常化();
}
/**
*@param initialRoll
*/
公共无效卷(浮动初始卷){
滚动角度+=初始滚动;
如果(滚动角度>360){
滚转角-=360;
}否则如果(滚动角度<0){
滚转角+=360;
}
roll.setFromAxisAngle(新矢量4f(0,0,1,rollAngle*DEGTORAD));
roll.normalise();
}
/**
*改变方向,专注于世界上的某一点
*@param-eye
*/
公共无效查找(){
重新定向();
GL11.glMultMatrix(viewMatrixBuffer);
}    
公共无效重新定向(){
//按顺序乘法:轴承、节距、滚动。非交换!
四元数更改=新四元数();
四元数.mul(轴承、节距、变化);
四元数.mul(滚动,改变,改变);
//调整相机的方向。。。
Matrix4f rotationMatrix=getRotationMatrix(更改);
//找到看的方向
方向.x=旋转矩阵.m20;
方向y=旋转矩阵m21;
方向z=旋转矩阵m22;
//定位
旋转矩阵.m30=眼睛.x;
旋转矩阵.m31=眼睛.y;
旋转矩阵.m32=眼睛.z;
旋转矩阵m33=1;
旋转矩阵;
旋转矩阵存储(viewMatrixBuffer);
viewMatrixBuffer.rewind();
向量3f.交叉(新向量3f(0,1,0),方向,空)。归一化(右);
向量3f.交叉(右、方向、空)。归一化(向上);
}
矢量3f、四元数和矩阵4f都是LWJGL类,不是定制的

所以我的问题是,给定3个表示方位、俯仰和滚动的四元数,我如何修改ModelView矩阵来精确表示这些旋转


编辑:我觉得这很接近。见RiverC评论中的要点链接。在旋转了这么多度之后,视图在滚动时恢复正常之前会跳跃很多次。它的要点就在那里,但还是有点不对劲。

我知道这是老东西,但还是让我猜一下。问题正是你自己说的:

当我“滚动”摄影机时,它似乎围绕全局Z轴而不是局部摄影机方向轴滚动

它这样做是因为您要求它围绕向量(0,0,1),即全局Z轴滚动

这就是单位四元数的作用:它们围绕一个轴旋转一个向量(这里是一组向量,你的旋转矩阵),该轴由它们的虚向量部分(x,y,z)通过w标量的某个角度函数(w=cos(angle/2))指定

如果我理解你想做什么,那就是像从左向右倾斜头部一样滚动相机,那么你应该围绕方向向量构建一个滚动四元数:

 roll.setFromAxisAngle(new Vector4f(direction.x, direction.y, direction.z, rollAngle * DEGTORAD));

我假设你的方向向量是标准化的,或者LWJGL在调用setFromAxisAngle时知道如何处理非酉轴向量。

你的乘法顺序不对

对于两个旋转q1和q2,如果q2跟随q1(因为旋转通常是非交流的),则乘以q2*q1

在框架式系统(如FPS控制装置)中,优先顺序始终为偏航、俯仰和横摇。这将建议进行以下计算:

roll * pitch * yaw
作为java观点,我建议不要为每次更新创建新的四元数,但无论如何

change = Quaternion.mul(Quaternion.mul(roll, pitch, change), yaw, change);
如果查看代码,第三个四元数将被结果覆盖,因此无需在每次帧/更新时重置或重新创建


这种旋转顺序的事情令人困惑,但如果你看看关于四元数的Wiki页面,这是一般规则。

谢谢你的更新。我已经有一段时间没有接触过这段代码了,所以我正在重新熟悉LWJGl。我想我很接近了。在做出您的更改和gsimard建议的更改之后,我离您越来越近了。但是,当偏航(问题中的轴承)为0时,俯仰良好。当偏航为180时,俯仰将反转(俯仰向上移动摄影机而不是向下移动)。此外,旋转大约20度后,旋转变得零星。如果我继续旋转它
change = Quaternion.mul(Quaternion.mul(roll, pitch, change), yaw, change);