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

标签 java opengl math lwjgl

我有一些树,它们大大滞后于游戏,所以我想检查一下树是否在镜头前。 A swaggy picture

我从 Mathematics forum 那里得到了一些帮助, 也看过 This link帮助我将俯仰/偏航转换为所需的方向 vector 。

但出于某种原因,每当我将相机向左移动时,树木就会变得可见,而每当我将其向右移动时,它们就会变得不可见(因此,如果相机指向 Z 轴上的 +1,似乎正在渲染树木,但在 Z 轴上为 -1,并且似乎不渲染它们)。 GIF of trees being dumb (请参阅 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();
    }
}

有人能告诉我我做错了什么吗?我搞不懂是数学问题..还是代码问题..还是什么?

相机翻译代码:

 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();
}

更新:

它似乎是相机正在注视的地方。例如,如果我查看 -Z,什么也不会发生,但如果我查看 +Z,它们都会渲染。 if (dot > 0) code 似乎是 +Z 而不是 +TheCameraRotation。

最佳答案

您的相机围绕 Y 偏转,这意味着 Y 是您的向上 vector 。但是,float z = (float) Math.sin(Math.toRadians(camera.pitch())); 为您的上 vector 提供 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();

关于java - 如何检查相机前面是否有物体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26238226/

相关文章:

opengl - 我需要注意将顶点属性打包在一起吗?

javascript - Math.round(Math.random()) 组合似乎在我的 javascript 程序中生成了太多 0

swift - swift ios中的叉积函数

algorithm - 在 0-1 数组中查找所有 1 为 “on the left” 的 1 的个数?

java - Java POJO 中无模式模型的最佳实践是什么?

java - Hibernate在持久化到数据库之前通过id获取保存的对象

c++ - Alpha channel 被渲染为黑色。怎么让它透明呢?

java - 如何映射Pageable的排序字段?

java - 关于接口(interface)的不适用方法错误

math - 为什么 OpenGL 支持 mipmap 但不支持积分图像?