Rotating the viewing platform in Java3d

SummerCodin picture SummerCodin · Aug 19, 2010 · Viewed 8.5k times · Source

The following code puts a cube at (0, 0, 0) and another at (0, .5, .5) and each cube is (.5, .5, .5) in dimension. I'm trying to rotate the view that the screen gets to one like this good but instead I get this view alt text. Also, I realize I got the colors backwards.

Anyway, this is my code so far:

import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;

public class Positioning {
    private Color3f lightBlue;
    private Color3f aquaGreen;
    private Color3f white;
    private Color3f teal;
    private BranchGroup group;
    private SimpleUniverse universe;

    public Positioning() {
        lightBlue = new Color3f(0.0f, 0.749019608f, 1.0f);
        aquaGreen = new Color3f(0.439215686f, 0.858823529f, 0.576470588f);
        white = new Color3f(1.0f, 1.0f, 1.0f);
        teal = new Color3f(0.196078431f, 0.6f, 0.8f);

        universe = new SimpleUniverse();
        group = new BranchGroup();

        addCube(0.5f, 0.5f, 0.5f, new Vector3f(0.0f, 0.0f, 0.0f), lightBlue);
        addCube(0.5f, 0.5f, 0.5f, new Vector3f(0.5f, 0.0f, 0.5f), aquaGreen);

        //add light
        DirectionalLight light1 = new DirectionalLight(white, new Vector3f(0.0f, 7.0f, -12.0f));
        light1.setInfluencingBounds(new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0));
        group.addChild(light1);

        //look at the right spot
        Transform3D lookAt = new Transform3D();
        lookAt.lookAt(new Point3d(0.0, 0.0, 3.0), new Point3d(0.0, 0.0, 0.0), new Vector3d(1.0, 1.0, 0.0));
        lookAt.invert();
        universe.getViewingPlatform().getViewPlatformTransform().setTransform(lookAt);
        universe.addBranchGraph(group);
    }

    public void addCube(float x, float y, float z, Vector3f position, Color3f color) {
        TransformGroup tg = new TransformGroup();
        Transform3D trans = new Transform3D();

        Appearance app = new Appearance();
        Material mat = new Material();
        mat.setDiffuseColor(color);
        mat.setSpecularColor(color);
        app.setMaterial(mat);
        Box b = new Box(x, y, z, app);

        //move into position and add to the branch group
        trans.setTranslation(position);
        tg.setTransform(trans);
        tg.addChild(b);

        group.addChild(tg);
    }

    public static void main(String[] args) {
        new Positioning();
    }
}

So right now the canvas is black and I think it might be my positioning on the lookAt function. I'm also not exactly for sure what the up vector is for. Any ideas on how to fix this?

Answer

Troubadour picture Troubadour · Aug 19, 2010

I'm not familiar with Java but usually you can set up a view matrix using some sort of "lookAt" function. A quick look at the docs came up with this.

BTW, setNominalViewingTransform only translates along the z-axis so the screenshot you showed is what I would expect to see. You are correct to try to set the view transform yourself.

Edit

As far as the up direction for the lookAt function is concerned this is just a way of controlling the roll of the camera. In other words by specifying the eye point and the centre point (the point the camera is looking at) you have only defined a direction. The camera could still rotate 360 degrees on that axis. If you want to look at things the right way up then just specify a vector in the direction of "up" in your system - if that is y then it would be (0,1,0). If you wanted to look at things upside down then it would be (0,-1,0).

Note that you don't have to make sure that the "up" vector is perpendicular to the direction defined by eye and centre. As long as it's not parallel to that direction then the method should automatically just use the component of your supplied "up" vector that is perpendicular to the direction.

Edit2:

Based on your edits it looks as if you have put in a position for the "up" vector rather than a direction. It should just be the vector (0,1,0). Having said that it still won't fix your problem as an incorrect "up" vector just means that the camera might end up rolled around on its own axis so that it's upside-down, on its side, etc., but it won't affect the direction.

Therefore there must be something wrong with the eye and centre positions or the matrix is still not inverted. Your edit for the invert() looks wrong as you haven't called it on your lookAt Transform3D but I assume that's just a typo. when you updated the question?

I would try a simpler viewing angle to start with. Just try to look along the z-axis with something like

    Transform3D lookAt = new Transform3D();
    lookAt.lookAt( new  Point3d( 0.0, 0.0, 1.0 )
                 , new  Point3d( 0.0, 0.0, 0.0 )
                 , new Vector3d( 0.0, 1.0, 0.0) );
    lookAt.invert();

What happens with that?

If you still get black then try changing the eye point's position along the z-axis, perhaps try 2.0, 3.0 and then a few negative values too.

The other possibility is that your camera is looking in the right direction but the objects are being culled due to frustum clipping. You might want to check the documentation to see what the default clip planes are set to. This might show up in the example above when you change the eye position along the z-axis. If you can see your objects for some values of z but not others then it's probably a clipping problem.

Let me know how you get on.