如何检查相机前面是否有物体?

Joe*_*200 13 java opengl math lwjgl

我有一些树,这些树大大落后于游戏,所以我想检查一下树是否在镜头前. 一张狡猾的照片

我从数学论坛得到了一些帮助,还看了一下这个链接,帮助我将俯仰/偏航转换为所需的方向向量.

但出于某种原因,每当我将摄像机向左移动时,树木都会变得可见,每当我向右移动它们时,它们就会变得不可见(因此,如果摄像机指向Z轴上的+1,它似乎正在渲染树,但Z轴上的-1,似乎没有渲染它们). 树的GIF是愚蠢的 (请参阅http://i.gyazo.com/cdd05dc3f5dbdc07577c6e41fab3a549以获得不那么跳跃的.mp4)

我使用以下代码检查对象是否在相机前面:

Ship you = shipsID.get(UID);
int dis = 300;
Vector3f X = new Vector3f(camera.x(), camera.y(), camera.z());
float x = (float) (Math.cos(Math.toRadians(camera.yaw()))*Math.cos(Math.toRadians(camera.pitch())));
float y = (float) (Math.sin(Math.toRadians(camera.yaw()))*Math.cos(Math.toRadians(camera.pitch())));
float z = (float) Math.sin(Math.toRadians(camera.pitch()));
Vector3f V = new Vector3f(x, y, z);

for (Tree tree : trees){
    Vector3f Y = new Vector3f(tree.location.x, tree.location.y, tree.location.z);
    Vector3f YMinusX = Y.negate(X);//new Vector3f(Y.x - X.x, Y.y - X.y, Y.z - X.z);
    float dot = Vector3f.dot(YMinusX, V);
    if (dot > 0){
        tree.render();
    }
}
Run Code Online (Sandbox Code Playgroud)

有谁能告诉我这里做错了什么?如果这是数学,我无法解决..或者代码......或者什么?

相机翻译代码:

 public void applyTranslations() {
    glPushAttrib(GL_TRANSFORM_BIT);
    glMatrixMode(GL_MODELVIEW);
    glRotatef(pitch, 1, 0, 0);
    glRotatef(yaw, 0, 1, 0);
    lastYaw = yaw;
    glRotatef(roll, 0, 0, 1);
    glTranslatef(-x, -y, -z);
    glPopAttrib();
}
Run Code Online (Sandbox Code Playgroud)

更新:

它似乎是相机正在寻找的地方.例如,如果我查看-Z,则没有任何反应,但如果我查看+ Z,它们都会渲染.将if (dot > 0) code出现以某种方式为+ Z,而不是+ TheCameraRotation.

joz*_*yqk 5

你的相机旋转偏转Y,暗示Y是你向上的向量.但是,float z = (float) Math.sin(Math.toRadians(camera.pitch()));Z你的向上矢量.存在不一致.我想通过交换开始yz这里,然后打印出来的一切每一帧,所以你可以看到当你旋转相机会发生什么.还渲染一棵树并打印dot.例如,只有当您查看树的左侧90度时,您才可能很快注意到数字接近1.0,从而缩小了问题范围.正如@DWilches所指出的,交换cos/sin将改变旋转的相位,这将产生这样的效果.

您可以考虑将点积限制在相机的视野范围内.树木不仅仅是点,还存在问题.正如@glampert建议的那样,更好的方法是在相机平截头体上测试树边界框.

尽管如此,树几何看起来并不那么复杂.优化明智,我开始尝试更快地绘制它们.你在使用VBO吗?也许看看减少绘制调用的方法,比如实例化.甚至可能会为LOD或广告牌使用一些模型.更进一步,广告牌上有多棵树.遮挡剔除方法可用于忽略山脉背后的树木.

[ 编辑 ]
由于您的树木大致都在飞机上,您可以将问题限制在相机的偏航中:

float angleToTree = Math.atan2(tree.location.z - camera.z(), tree.location.x - camera.x());
float angleDiff = angleToTree - camera.yaw();
if (angleDiff > Math.PI)
    angleDiff -= 2.0f * Math.PI;
if (angleDiff < -Math.PI)
    angleDiff += 2.0f * Math.PI;
if (abs(angleDiff) < cameraFOV + 0.1f) //bias as trees are not points
    tree.render();
Run Code Online (Sandbox Code Playgroud)