13

I have got some trees, which are greatly lagging the game, so I would like to check if the trees are in front of the camera or not. A swaggy picture

I have had some help from the Mathematics forum, and also had a look at This link to help me convert pitch/yaw to the directional vector needed.

But for some reason, whenever I move the camera to the left, the trees become visible, wheras whenever I move it to the right, they become unvisible (So if camera is pointing at +1 on the Z axis, it seems to be rendering the trees, but -1 on the Z axis and it seems to not render them). GIF of trees being dumb (See http://i.gyazo.com/cdd05dc3f5dbdc07577c6e41fab3a549 for a less-jumpy .mp4)

I am using the following code to check if an object is in front of the camera or not:

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

Is anyone able to tell me what I have done wrong here? I can't work out if it's the math.. Or the code.. Or what?

Camera translation code:

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

UPDATE:

It appears to be where the camera is looking. For example, if I look to -Z, nothing happens, but if I look to +Z, they all render. The if (dot > 0) code appears to somehow being +Z rather than +TheCameraRotation.

Community
  • 1
  • 1
Joehot200
  • 1,070
  • 15
  • 44
  • 9
    Frustum Culling is a more appropriate method for removal of hidden geometry. [Check this tutorial](http://www.lighthouse3d.com/tutorials/view-frustum-culling/). – glampert Oct 07 '14 at 14:45
  • Can you please put the line `this checks the distance to the ship*/ if (you.location.x - tree.location.x < dis && you.location.x - tree.location.x > -dis && you.location.z - tree.location.z < dis && you.location.z - tree.location.z > -dis)` onto visible screen ? – Caffeinated Oct 07 '14 at 14:46
  • @Coffee I think I did what you wanted. If not, then could you clarify? – Joehot200 Oct 07 '14 at 14:52
  • 1
    You have two criteria to reject the tree: The distance test, and the dot product test. You can easily find out which one causes the trees to disappear by disabling one or the other. This would narrow down the problem. – Reto Koradi Oct 07 '14 at 14:56
  • @RetoKoradi I did that for testing purposes - It is not the issue. – Joehot200 Oct 07 '14 at 16:41
  • Will add a bounty if I don't get an answer in 2 days. – Joehot200 Oct 07 '14 at 17:11
  • It would go much faster if you move as many calculations outside the loop as possible instead of doing them every time. Next you could do estimation instead fo the more expensive cos/sin in many cases. – Peter Lawrey Oct 07 '14 at 21:08
  • @PeterLawrey I actually don't see how. Mind explaining? – Joehot200 Oct 07 '14 at 21:43
  • @Joehot200 Is the `X` the same for every tree, if so, do you need to recreate it every time? Is any of the calculations using `X` going to be the same each time, if so do they need to be recalculated to get the same result. – Peter Lawrey Oct 07 '14 at 21:45
  • @Joehot200 Is the camera different for each tree or are all the calculation which use that the same each time? – Peter Lawrey Oct 07 '14 at 21:47
  • 1
    The most likely problem is that the camera direction you are calculating here is not consistent with the camera transformation you apply when rendering. Somewhere in code not shown here, you must be calculating a camera (view) transformation based on the camera parameters. I suspect that it applies the camera parameters differently from the way they are used in the posted code. – Reto Koradi Oct 07 '14 at 22:09
  • @RetoKoradi Added translation code to my post. – Joehot200 Oct 08 '14 at 10:32
  • Honestly, you would probably get better help at http://gamedev.stackexchange.com. – RBarryYoung Nov 20 '14 at 17:21
  • That said, I can see one problem with your code: you are treating the trees as though the are single points in space, when at the very least they should be treated as line segments. However, I also do not think that that is what is causing your problem. – RBarryYoung Nov 20 '14 at 17:27

3 Answers3

5

Your camera rotations yaw around Y, implying Y is your up vector. However, float z = (float) Math.sin(Math.toRadians(camera.pitch())); gives Z for your up vector. There is an inconsistency. I'd start by swapping y and z here, then print everything out every frame so you can see what happens as you rotate the camera. Also render just one tree and print dot. E.g. you might quickly notice the numbers approach 1.0 only when you look at 90 degrees left of the tree which narrows down the problem. As @DWilches notes, swapping cos/sin will change the phase of the rotation, which would produce such an effect.

You might consider limiting the dot product to the camera's field of view. There are still problems in that trees are not just points. A better way would be to test tree bounding boxes against the camera frustum, as @glampert suggests.

Still, the tree geometry doesn't look that complex. Optimization wise, I'd start trying to draw them faster. Are you using VBOs? Perhaps look at methods to reduce draw calls such as instancing. Perhaps even use a few models for LOD or billboards. Going even further, billboards with multiple trees on them. Occlusion culling methods could be used to ignore trees behind mountains.

[EDIT]
Since your trees are all roughly on a plane, you could limit the problem to the camera's yaw:

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();
jozxyqk
  • 16,424
  • 12
  • 91
  • 180
  • I already have LOD stuff implemented now. That question was asked two months ago: But the trees (and grass I am about to implement!) are still laggy, which is why I would like to not render the ones I can't see. By the way, how would I use a billboard like that? – Joehot200 Nov 21 '14 at 10:27
  • @Joehot200 I'd render the tree to a texture (via FBO) and draw a quad with that texture on as one of the farthest LOD models. Then maybe have a few textures rendered with different rotations so they don't all look the same. – jozxyqk Nov 21 '14 at 10:32
  • The dot product is being anywhere between -10,000 and +10,000 (and beyond, I think). Is that normal? – Joehot200 Nov 21 '14 at 10:59
  • @Joehot200 oh right, that'd be the distance to the tree. Hopefully the min/max align with when you're looking directly at/away from the tree. If not then the problem's most likely to do with your yaw/pitch/roll calculations not matching the OpenGL rotations. – jozxyqk Nov 21 '14 at 11:13
  • The dot product appears to be affected depending on which way the camera is facing, but not the location of the camera. – Joehot200 Nov 21 '14 at 11:17
  • @Joehot200 Then perhaps your vector `X`, the camera position, isn't correct. Moving should change the camera's angle relative to the tree. – jozxyqk Nov 21 '14 at 11:40
  • @Joehot200 Oh, right, you're using java. `M_PI` is a C/C++ macro definition of π. Will update. – jozxyqk Nov 21 '14 at 13:12
  • I'm pretty sure something is messed up here: It is returning values of -5000 and stuff - I think the camera yaw or something is being odd. Still, that yaw-only code was really helpful. It's up to me to debug my darned code now. – Joehot200 Nov 21 '14 at 13:33
4

Could you write it like this

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

As you can see there is far less calculation being performed for each tree.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Upvoted since it is a good suggestions (I was just trying to be lazy and get it to work at the time), however it has not solved the issue. – Joehot200 Oct 08 '14 at 10:16
  • A little bitt off topic, but since main problem is lagging of the game: you can also greatly increase rendering speeds with storing several tree objects. Like close objects with great detail, on medium range some medium detailed trees, and far away trees as billboards. Naturally you want this to be paired with frustrum culling as mentioned above. – Izzy Nov 20 '14 at 19:23
2

For what I see here the correct formulas are:

x = Math.sin(pitch) * Math.cos(yaw);
y = Math.sin(pitch) * Math.sin(yaw);
z = Math.cos(pitch);

Could you try them ?

Daniel
  • 21,933
  • 14
  • 72
  • 101