Strange behavior of Camera.lookAt(Vector3f)

Check out HelloLOD. I’m trying to attach a CurveController to a CameraNode at the end so that the camera can just fly through the program. Unfortunantly, I’m having problems using lookAt(). When I use lookAt() in simpleUpdate, the camera looks correctly but it ends up culling bounding sphere’s that are visable. Very strange. Any hints?

At work, so I can’t take a look at the code, and lookAt is a recent addition that I never looked at to begin with… BUT, if I had to take a guess and start debugging it, I would make sure that the onFrustumChange() or onFrameChange() are called properly to set up the Frustum Planes that define the view volume.

Normally, lookat = location + direction. Calling lookat overrides that, but our frustum calculations for culling are based on you looking along the vector defined by location and direction+location. So you get issues using outside of a controlled environment.



We could certainly extend that method’s usefulness by altering the direction and up/left vectors on each frustum change. That would cause some extra calculation, but might make it more useful outside of its use in imposter node.

Ok, lookAt is not meant for public consumption, and thus is probably misnamed. It’s used by Imposter to keep geometry a certain distance from the camera so that it fills the Quad of the Imposter. It is not intended for the main camera to be controlled with this. Renaming should most likely be required, and documented.



You culling issues are due to the fact that the “lookAt” vector you set is not setting the direction of the camera, but being added to the location of the camera, so geometry is no longer where you thought it was going to be in relation to the camera.



CORRECTION: Location = direction+lookat.

We need to look at lookAt XD XD



I somewhat figured that out from the source, but the function was very cleverly misnamed. A "look at" function would be very usefull though.

Well it basically does the starts of what you might want such a function to do if used publically, just needs to set a few more things up for you I think.

https://jme.dev.java.net/source/browse/jme/src/jmetest/TutorialGuide/HelloLOD.java?rev=1.5&content-type=text/vnd.viewcvs-markup



I’m not using lookAt anymore. Just using


camera.setDirection



but again it seems to be culling objects that are visible. I'm calling camera.update() after every camera change, which calls

    onFrustumChange();
    onViewPortChange();
    onFrameChange();

I constantly see visible objects culled by JME. I think that the culling system needs fixing. I noticed problems when looking at objects higher in the y axes and large objects (radius of around 10000-1000000, witch is just a guess).

This model isn’t large or scaled or far or anything. The bounding volumes are viewable, it just culls away.

Ok, I guess this is something that just isn’t documented anywhere, or confusing in the API. A camera must have it’s vectors set in a standard right handed coordinate system. This means the left, up and direction vectors should be 90 degrees from one another. You should not be just setting direction to look at something and leave the left and up vectors the original values. This totally screws up the frustum planes. A camera should have it’s vectors set and NEVER touched again. You then rotate and translate the camera as needed.

   
CameraNode cn;   
Matrix3f m=cn.getLocalRotation().toRotationMatrix();
        m.setColumn(2,lookAtObject);
        cn.setLocalRotation(m);



that is still giving the same problem. Knowing that "lookAtObject" is the direction I want to look, how do I make the camera look at that direction?

There is nothing in the Camera that will let you just set the point to look at. You’d have to set the direction to your point, and take the cross products to get the left and up, then normalize.



That would probably be a good helper method.

c.setFrame(c.getLocation(),
new Vector3f(-1,0,0).crossLocal(lookAtObject).normalizeLocal(),
new Vector3f(0,1,0).crossLocal(lookAtObject).normalizeLocal(),
lookAtObject);


lookAtObject is the direction I want to look, not the point I want to look at. When I use this, my model looks tilted in the view.

I want to move the camera along a CurveController and have it look at a model every frame. What is the correct way to do this in jME?

It is when it’s calculated

hmmm looks correct at first glance.



I’ll have to play with it some when I get home tonight.

I figured it out.

        c.setFrame(c.getLocation(),
                new Vector3f(0,1,0).crossLocal(lookAtObject).normalizeLocal(),
                new Vector3f(1,0,0).crossLocal(lookAtObject).normalizeLocal(),
                lookAtObject);



The above works like I expect. I was crossing my left for my left when I should of been crossing my up for my left.

Some helper - functions in this area would be highly welcome.



Look the camera at some location

Look the camera at some other Object (Node, Geometry )

Set Direction of a Node / Geometry to face a given Direction

Set Direction of a Node / Geometry to look at a given Point



comes to my mind on a first tought.



(Please don’t flame me if anything of this is already in and i just haven’t found it.)

Here you go:



http://www.jmonkeyengine.com/jmeforum/index.php?topic=1895.0



Enjoy,

DP

Just a note.  Camera's lookAt(Vector3f position) method has been changed to lookAt(Vector3f position, Vector3f worldUp).  It now properly sets the camera's up, left and direction vectors, so you can safely use this function to point your camera.

Perhaps this is a dumb question but why are there only two Vector3fs instead of three?



darkfrog