轨道控制使场景在一段时间后消失
Orbit controls make scene disappear after a while
我正在使用 JOGL 构建点云查看器,并且我已经实现了自己的轨道控制。它在一段时间内运行良好,但在某些时候(我认为在非常快速地左右拖动鼠标后)场景完全消失了。这是我的代码:
public void mouseDragged(MouseEvent e) {
if (oldX < 0.0005 && oldY < 0.0005) {
// when the mouse drag starts initially
oldX = e.getX();
oldY = e.getY();
} else {
float differenceX = e.getX() - oldX;
float differenceY = e.getY() - oldY;
oldX = e.getX();
oldY = e.getY();
float speedX = differenceX / 2;
float speedY = differenceY / 2;
Vector3f velocityX = new Vector3f();
Vector3f velocityY = new Vector3f();
Vector3f oldTarget = camera.getTarget();
Vector3f cameraRight = new Vector3f();
// getting right vector of the camera in the world space
camera.getDirection().cross(camera.getWorldUp(), cameraRight);
/* moving the camera first along its right vector
* then setting its target to what it was originally
* looking at */
cameraRight.mul(-speedX, velocityX);
camera.translate(velocityX);
camera.setTarget(oldTarget);
/* moving the camera second along its up vector
* then setting its target to what it was originally
* looking at */
camera.getUp().mul(-speedY, velocityY);
camera.translate(velocityY);
camera.setTarget(oldTarget);
}
}
我首先想到的是,当摄像机方向矢量和世界上方向矢量相同时,摄像机右矢量(两者之间的叉积)将为零,但这仅意味着控件失去运动的一个维度;这不应该导致整个场景消失。
我最初提出的想法是在每次旋转时将相机与其焦点分开(在远平面之外的某个点)。解决这个问题的方法是使用极坐标系来实现轨道控制。因此,在您的 mouseDragged()
方法中:
if (oldX < 0.0005 && oldY < 0.0005) {
oldX = e.getX();
oldY = e.getY();
} else {
float differenceX = e.getX() - oldX;
float differenceY = e.getY() - oldY;
oldX = e.getX();
oldY = e.getY();
// getting the current position of the camera in the spherical coordinate system
Vector3f sphericalCoords = MathUtils.toSphericalCoords(camera.getPosition());
float speedY = (float)Math.toRadians(differenceY / 4.0f);
float speedX = (float)Math.toRadians(differenceX / 4.0f);
// adding speedY to the theta angle and speedX to the phi angle
sphericalCoords.add(new Vector3f(0, speedY, speedX));
// making sure the angles are not outside the [0, 2 * PI] interval
polarCoords.y = MathUtils.wrapTo2Pi(sphericalCoords.y);
polarCoords.z = MathUtils.wrapTo2Pi(sphericalCoords.z);
// updating the position of the camera
camera.setPosition(MathUtils.toCartesianCoords(sphericalCoords));
}
我正在使用 JOGL 构建点云查看器,并且我已经实现了自己的轨道控制。它在一段时间内运行良好,但在某些时候(我认为在非常快速地左右拖动鼠标后)场景完全消失了。这是我的代码:
public void mouseDragged(MouseEvent e) {
if (oldX < 0.0005 && oldY < 0.0005) {
// when the mouse drag starts initially
oldX = e.getX();
oldY = e.getY();
} else {
float differenceX = e.getX() - oldX;
float differenceY = e.getY() - oldY;
oldX = e.getX();
oldY = e.getY();
float speedX = differenceX / 2;
float speedY = differenceY / 2;
Vector3f velocityX = new Vector3f();
Vector3f velocityY = new Vector3f();
Vector3f oldTarget = camera.getTarget();
Vector3f cameraRight = new Vector3f();
// getting right vector of the camera in the world space
camera.getDirection().cross(camera.getWorldUp(), cameraRight);
/* moving the camera first along its right vector
* then setting its target to what it was originally
* looking at */
cameraRight.mul(-speedX, velocityX);
camera.translate(velocityX);
camera.setTarget(oldTarget);
/* moving the camera second along its up vector
* then setting its target to what it was originally
* looking at */
camera.getUp().mul(-speedY, velocityY);
camera.translate(velocityY);
camera.setTarget(oldTarget);
}
}
我首先想到的是,当摄像机方向矢量和世界上方向矢量相同时,摄像机右矢量(两者之间的叉积)将为零,但这仅意味着控件失去运动的一个维度;这不应该导致整个场景消失。
我最初提出的想法是在每次旋转时将相机与其焦点分开(在远平面之外的某个点)。解决这个问题的方法是使用极坐标系来实现轨道控制。因此,在您的 mouseDragged()
方法中:
if (oldX < 0.0005 && oldY < 0.0005) {
oldX = e.getX();
oldY = e.getY();
} else {
float differenceX = e.getX() - oldX;
float differenceY = e.getY() - oldY;
oldX = e.getX();
oldY = e.getY();
// getting the current position of the camera in the spherical coordinate system
Vector3f sphericalCoords = MathUtils.toSphericalCoords(camera.getPosition());
float speedY = (float)Math.toRadians(differenceY / 4.0f);
float speedX = (float)Math.toRadians(differenceX / 4.0f);
// adding speedY to the theta angle and speedX to the phi angle
sphericalCoords.add(new Vector3f(0, speedY, speedX));
// making sure the angles are not outside the [0, 2 * PI] interval
polarCoords.y = MathUtils.wrapTo2Pi(sphericalCoords.y);
polarCoords.z = MathUtils.wrapTo2Pi(sphericalCoords.z);
// updating the position of the camera
camera.setPosition(MathUtils.toCartesianCoords(sphericalCoords));
}