I decided to take another look at the code I’d written in another post:
In a real implementation, one ray really isn’t enough to get the effect necessary. I’d planned on shooting more rays (about 4 total) to attempt to get things nearby that would obstruct the player’s view of the player character. Then I realized, hey, why don’t I just plop a bounding box with a corner at the player and a corner at the camera and see how that goes. ~ It actually works pretty neat. However, one huge drawback is that collideWith returns every single intersection.
I replaced the roomNode.collideWith() with:
BoundingBox bb = new BoundingBox(geom1.getLocalTranslation(), cam.getLocation());
Whenever the box contains Oto, the collision count jumps up to 1960, which kills the fps (obviously).
I’m still experiementing, and hell, I’m not even sure if I’m going about this right. But it would be super awesome if there was a way to use collideWith and return results with only a list of unique geometries it collided with. Or is there an even easier way to do this that I’m not seeing (hunted around the source already)?
Just order your scenegraph so that the node you pick only contains the wall geometry.
Thanks for the quick reply! Well, I’m glad I’m not doing it wrong at least. I’ll just be mindful of how complex I make the walls. In my actual game I’ve got the walls separated from the floor/characters/etc, so it will probably work better once I implement it. I need to decide whether or not I include doors and such in this but that’s more of a flavor of the game kind of problem ;p Though, I think it’s definitely an improvement; using the bounding box is much more simple than spraying rays everywhere to do virtually the same thing.
Also my bounding box won’t be changing every update so maybe that will help ;p I’ll likely end up making it the size of a fully zoomed in camera and stick with that. Even zoomed out that should occlude as much as the player would need.
Sorry to bother you again in this thread; I’m wondering if there’s a way to visualize the bounding box I’m using. It doesn’t seem as though it’s as nice as the physics objects where you can just attach a debug material to get the wireframe. I figured out a way to do it with a box geometry, however it has a pretty nasty drawback that I wasn’t sure if anyone was aware of (or maybe my usage is wrong). I noticed the box mesh has Box.updateGeometry(min, max); method. However, when called before or after rootNode.updateGeometry(); it errors out the program with:
Dec 9, 2010 10:24:22 AM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.UnsupportedOperationException: Data has already been sent. Cannot setupData again.
at java.lang.Thread.run(Unknown Source)
I can get around this by simply detaching the box, and making a new one every update, but it hardly seems efficient. Luckily, I don’t think I need the visual for anything but debugging, but I wasn’t sure if this was intentional, a bug, or if I was again, “doing it wrong” ™. I think I ran into this issue once before attempting to modify the buffers, probably the texCoord buffer, and I was running into a similar situation.
I like to watching this one develop. Keep up the good work!
More than a month old now yeeeesh. I saw this post back on my topics and thought I should update it with the ideas I eventually came up with so someone else might reference it. I’ve got a working version, but it’s very messy and not optimized at all. But it works so far!
Right now, I basically have a bounding box with one corner at the center of the player’s node, and the other corner at the camera position as I think I described above. Now, this works pretty well to keep things out of the player’s view. There’s only one problem, it occludes a bit too many walls sometimes. It works great when the room is just a square, but imagine an octagon room with the bounding box occlusion. What would happen is the front three walls would be occluded, AND the two side walls that aren’t in the way at all and are in fact facing the camera! Doh!
My solution for this at the moment is to fire a ray from the player at any geometry that is within the bounding box to get a “second opinion.” What I do with this ray is grab the first collision with one geometry at a time and check the normal at the point of contact. If the contact normal dot producted with a direction vector from the camera to the same geometry is negative (or at least from what I’ve gathered so far), then the surface that the player node can see, can also be seen by the camera. Whew, it’s crazy, but it seems to work with both tunnels within the bounding box and some scattered walls. It reduces the visibility around corners a bit because it takes it a second to make a corner wall vanish (the ray has to start hitting the side of the wall the camera can’t see so it occludes it), but I’ve made adjustments here and there to improve it a bit. I’m also sure there’s some more limitations, but initial testing is good so far. i’m a touch worried about irregular wall surfaces, but I’ll cross that bridge when I get to it.
Sadly the code is a mess as I said, but I also wanted to try some things using a bounding sphere instead of the box. I have a feeling I could get the same effect with an even smaller performance hit. Also, speaking of which, I haven’t seen much of one using the previous tactic, but I’m only testing with 10~ occlude-able walls at the moment.
I’m also considering bundling this into some sort of control class to be thrown at the camera or the rootnode of a scene or something.
A couple screencaps and note, I’m fps locked at 61 on purpose. Oh, and the ghosting bounding box is just a low alpha’d box to see the extents of the bounding volume. I don’t know any other way to visualize it. heh XD