Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

How to rotate the "camera"?

843799May 11 2010 — edited Jun 13 2010
Hi everybody,

I would like to rotate a loaded model (or the "camera"), which is shown in the middle of the screen.

How can I do that? The object should be rotating all the time very slowly (like one 360 degress rotating in 10sec).
public class CrossingFrame3D extends Applet {

    private BranchGroup scene;
    private SimpleUniverse u;
    private Background background;

    public CrossingFrame3D() throws Exception {
        setLayout(new BorderLayout());
        Canvas3D canvas = createCanvas();
        add("Center", canvas);
        u = new SimpleUniverse(canvas);

        scene = createContent();

        TransformGroup vtg = u.getViewingPlatform().getViewPlatformTransform();
        Transform3D moveback = new Transform3D();
        moveback.setTranslation(new Vector3f(0.0f, 0.0f, 10.0f));
        vtg.setTransform(moveback);

        BufferedImage image = ImageIO.read(new File("test.jpg"));
        BufferedImage resizedImage = new BufferedImage(640, 480, image.getType());
        Graphics2D g = resizedImage.createGraphics();
        g.drawImage(image, 0, 0, 640, 480, null);
        g.dispose();
        BoundingSphere boundingSphere = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
        TextureLoader backgroundTexture = new TextureLoader(resizedImage, this);
        background = new Background(backgroundTexture.getImage());
        background.setApplicationBounds(boundingSphere);
        background.setCapability(Background.ALLOW_IMAGE_WRITE);
        scene.addChild(background);

        scene.compile();
        u.getViewer().getView().setBackClipDistance(10000.0);
        u.addBranchGraph(scene);
    }

    private Canvas3D createCanvas() {
        GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
        GraphicsConfiguration gc1 = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getBestConfiguration(template);
        return new Canvas3D(gc1);
    }

    private BranchGroup createContent() throws Exception {
        Loader loader = new ObjectFile(ObjectFile.LOAD_ALL);

        // Use these 4 lines to load from a local file
        java.io.File file = new java.io.File("cow.obj");
        if (file.getParent() != null) {
            if (file.getParent().length() > 0) {
                loader.setBasePath(file.getParent() + java.io.File.separator);
            }
        }
        Scene newScene = loader.load(file.getName());

        BranchGroup group = newScene.getSceneGroup();
        createLights(group);
        return group;
    }

    private void createLights(BranchGroup graphRoot) {
        // Create a bounds for the light source influence
        BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);

        // Set up the global, ambient light
        Color3f alColor = new Color3f(0.3f, 1.0f, 0.3f);
        AmbientLight aLgt = new AmbientLight(alColor);
        aLgt.setInfluencingBounds(bounds);
        graphRoot.addChild(aLgt);

        // Set up the point (infinite) light source
        Point3f location = new Point3f(0.0f, 0.0f, 100.0f);
        PointLight lgt1 = new PointLight(new Color3f(1.0f, 1.0f, 1.0f),
                location,
                new Point3f(1.0f, 0.0f, 0.0f));
        lgt1.setInfluencingBounds(bounds);
        graphRoot.addChild(lgt1);

        // Set up the point (infinite) light source
        Point3f location2 = new Point3f(0.0f, 0.0f, -100.0f);
        PointLight lgt2 = new PointLight(new Color3f(1.0f, 1.0f, 1.0f),
                location2,
                new Point3f(-1.0f, 0.0f, 0.0f));
        lgt2.setInfluencingBounds(bounds);
        graphRoot.addChild(lgt2);
    }

    public void updateFrame(String img, Barcode barcode) throws IOException {

        if (barcode != null) {
            //change of model
            switch (barcode.getValue()) {
                case COW:
                    break;
                case CAR:
                    break;
                case ROBOT:
                    break;
                default:
                    throw new IllegalArgumentException("BarcodeType is not a known type!");
            }
        }

        BufferedImage image = ImageIO.read(new File(img));
        BufferedImage resizedImage = new BufferedImage(640, 480, image.getType());
        Graphics2D g = resizedImage.createGraphics();
        g.drawImage(image, 0, 0, 640, 480, null);
        g.dispose();
        TextureLoader backgroundTexture = new TextureLoader(resizedImage, this);
        background.setImage(backgroundTexture.getImage());
    }
}

Comments

843799
I added a new methode, which should rotate the BranchGroup:
    public void rotateX() {
        TransformGroup group = new TransformGroup();
        group.addChild(scene);

        Transform3D rotX = new Transform3D();
        rotX.rotX(2D);

        group.setTransform(rotX);
    }
There are two problems with it:

1. An exception is thrown:
Exception in thread "main" javax.media.j3d.MultipleParentException: Group.addChild: child already has a parent
        at javax.media.j3d.GroupRetained.checkValidChild(GroupRetained.java:478)
        at javax.media.j3d.GroupRetained.addChild(GroupRetained.java:487)
        at javax.media.j3d.Group.addChild(Group.java:290)
        at CrossingFrame3D.rotateX(CrossingFrame3D.java:151)
        at Main.main(Main.java:18)
2. The rotation should be automatically all the time (not only when a methode has been called).
843799

A quick solution of rotating your object can be with a RotationInterpolator. If you want your object to behave in a certain way, you have to define a Bahavior and arrange your wakeup condition accordingly. Considering that RotationInterpolator is a Behavior itself, you can extend this class and define your own wakeup conditon. Add this to your main root and it will be OK. I hope this helps.

843799
I spotted what I believe is the problem in your programming approach.

Your code puts everything into one BranchGroup. To me, this is bad. You should have the cow model be its own BranchGroup. Create a TransformGroup and add the Cow BG(BranchGroup) to the TG(TransformGroup). The TG will allow you to rotate the model by itself. Create a new BG. This will be the entire scene. To the scene BG, add the BoundingSphere, the lights, the background, and the cow TG. Then you may call u.addBranchGraph(scene BG);

To rotate the cow, put this code in a while loop(I calculated it to rotate 360 degrees in 10 seconds):
while(true) {
Transform3D t3d = new Transform3D();
Transform3D previousRotation = new Transform3D();
//Get the previous rotation amount
cowTG.getTransform(previousRotation);
//Rotate the cow 1 degree
t3d.rotY(Math.PI / 180);
//Add the new rotation to the previous one
previousRotation.mul(t3d);
//Apply the rotation
cowTG.setTransform(previousRotation);
//Sleep
try {
Thread.sleep(28);
} catch(Exception e) { }

This should fix it.
1 - 3
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Jul 11 2010
Added on May 11 2010
3 comments
396 views