我正在使用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);
}
}
我首先想到这是因为,当摄像机方向向量和世界向上向量相同时,摄像机右向量(两者之间的叉积)将为零,但这仅意味着控件丢失了一个机芯尺寸;这不会导致整个场景消失。
答案 0 :(得分:0)
我最初提出的想法是,随着每次旋转(在远平面之外的某个点),照相机与聚焦点之间要保持一定距离。解决该问题的方法是使用极坐标系实现轨道控制。因此,在您的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));
}