Opengl GLM:旋转时,如何保持鼠标下的点击点?

Opengl GLM:旋转时,如何保持鼠标下的点击点?,opengl,graphics,linear-algebra,glm-math,arcball,Opengl,Graphics,Linear Algebra,Glm Math,Arcball,我正在尝试使用标准的弧球旋转围绕其原点旋转网格。每当我单击3D对象时,我都会从鼠标投射光线以找到交点。我测量该交点与3D对象原点之间的距离,以创建一个球体,该球体将在该旋转中用作“弧球”(直到释放鼠标)。我在每次旋转开始时这样做的原因是我希望单击的点保持在鼠标下。对象旋转正确,只是旋转幅度较小,因此单击的点不会保留在鼠标下。下面的示例尝试旋转立方体。我在纹理上绘制一个黑色矩形,以跟踪最初单击的点。以下是问题的视频: 这是根据鼠标位置和球半径(ARCABRADIUS RADIUS)在点击上得到的

我正在尝试使用标准的弧球旋转围绕其原点旋转网格。每当我单击3D对象时,我都会从鼠标投射光线以找到交点。我测量该交点与3D对象原点之间的距离,以创建一个球体,该球体将在该旋转中用作“弧球”(直到释放鼠标)。我在每次旋转开始时这样做的原因是我希望单击的点保持在鼠标下。对象旋转正确,只是旋转幅度较小,因此单击的点不会保留在鼠标下。下面的示例尝试旋转立方体。我在纹理上绘制一个黑色矩形,以跟踪最初单击的点。以下是问题的视频:

这是根据鼠标位置和球半径(ARCABRADIUS RADIUS)在点击上得到的函数的函数(我担心这个函数不考虑立方体对象的位置),尽管立方体对象正好位于(0,0,z):


如何使单击的点保持在鼠标下?

将弧球半径设置为单击的点与对象中心之间的距离。换句话说,第一个点是立方体上的光线投射,后续点将是以对象为中心且具有上述半径的虚拟球体上的光线投射


注意:请查看我的,它不会干扰acos和轴角度,只会标准化两次。

我已经在这样做了。第一步是设置arcballRadius变量(相交点和立方体中心之间的距离)的光线投射。您链接的arcball旋转代码将单击的点保持在鼠标下方?@Jubei它的工作arcball代码比轴角度方法更有效(我喜欢插入它)
/**
* Get a normalized vector from the center of the virtual ball O to a
* point P on the virtual ball surface, such that P is aligned on
* screen's (X,Y) coordinates.  If (X,Y) is too far away from the
* sphere, return the nearest point on the virtual ball surface.
*/

glm::vec3 get_arcball_vector(double x, double y) {
glm::vec3 P = glm::vec3(x,y,0);
float OP_squared = P.x * P.x + P.y * P.y;
if (OP_squared <= arcballRadius*arcballRadius)
    P.z = sqrt(arcballRadius*arcballRadius - OP_squared);  // Pythagore
else
 {
   static int i;
   std::cout << i++ << "Nearest point" << std::endl;
   P = glm::normalize(P);  // nearest point
 }
 return P;
}
//get two vectors, one for the previous point and one for the current point
glm::vec3 va = glm::normalize(get_arcball_vector(prevMousePos.x, prevMousePos.y)); //previous point
glm::vec3 vb = glm::normalize(get_arcball_vector(mousePos.x, mousePos.y));         //current point
float angle = acos(glm::dot(va, vb));  //angle between those two vectors based on dot product

//since these axes are in camera coordinates they must be converted before applied to the object
glm::vec3 axis_in_camera_coord = glm::cross(va, vb);   
glm::mat3 camera2object = glm::inverse(glm::mat3(viewMatrix) * glm::mat3(cube.modelMatrix));
glm::vec3 axis_in_object_coord = camera2object * axis_in_camera_coord;

//apply rotation to cube's matrix
cube.modelMatrix = glm::rotate(cube.modelMatrix, angle, axis_in_object_coord);