我正在尝试使用 Java 和 OpenGL 制作某种 3D 编辑器。现在我正在实现 3D 编辑器的基本功能,例如围绕特定位置旋转相机和缩放。接下来我想做一个 3D Picking,用鼠标在 3D 空间中选择对象、线和顶点。我认为这会很容易,因为当相机对焦时我已经可以选择对象。
以下是使用相机焦点选择对象的示例:
在 Class Camera 中有这个方法:
public boolean isVecInFocus(Vec3 vec) {
//returns the distance between camera and target
float c = new Vec3(posX,posY,posZ).getDistanceTo(vec);
// returns a Vector by drawing an imiginary line with the length of c and the position and rotation of the camera
Vec3 target = getFocusedPoint(c);
//checks if the calculated Vector is near to the target
if(target.x > vec.x - 0.05f && target.x < vec.x + 0.05f && target.y > vec.y - 0.05f && target.y < vec.y + 0.05f && target.z > vec.z - 0.05f && target.z < vec.z + 0.05f) {
return true;
} else {
return false;
}
}
现在,我想对鼠标输入做同样的事情:
//Mouse positions
float mX = Mouse.getX();
float mY = Mouse.getY();
//My test Vector
Vec3 vec = new Vec3(-5,5,-8);
//Camera Position
Vec3 camV = new Vec3(cam.getPosX(),cam.getPosY(),cam.getPosZ());
//Distance from Test Vector to Camera
float c = camV.getDistanceTo(vec);
//Calculating of the aspect between width and height (Because fov_x and fov_y are different because of the Screen Resolution, I think)
float aspect = (float) sb.getDisplayWidth() / (float) sb.getDisplayHeight();
//Normal fov refers to fov_y, so here is the fov_x
float fovx = cam.fov * aspect;
//Changing the Rotations to calculate the target Vector with the values of the Mouse position and rotations , not the Camera
float rotY = cam.getRotationY() + (fovx / (float) sb.getDisplayWidth()) * (mX) - (fovx / 2F);
float rotX = cam.getRotationX() + (cam.fov / (float) sb.getDisplayHeight()) * ((float) sb.getDisplayHeight() - mY) - (cam.fov / 2F);
//Calculating the target Vector with simple Math ...
double xDis = c * Math.sin(Math.toRadians(rotY)) * Math.cos(Math.toRadians(rotX));
double yDis = c * Math.sin(Math.toRadians(rotX));
double zDis = c * Math.cos(Math.toRadians(rotY)) * Math.cos(Math.toRadians(rotX));
float posX = (float) (camV.x + xDis);
float posY = (float) (camV.y - yDis);
float posZ = (float) (camV.z - zDis);
Vec3 target = new Vec3(posX,posY,posZ);
//Check if the target Vector and the Test Vector are the same.
如果我使用此代码,并将鼠标指向测试向量,则结果不正确。Point 的精度越低,Screen-middle 和 Mouse position 之间的差异越大。
我认为它与OpenGL Perspective有关,但我不确定......