This discussion is archived
1 Reply Latest reply: Aug 12, 2010 7:28 PM by 843799 RSS

Simple Java 3D program’s CPU Usage spikes to up to 90 percent!

843799 Newbie
Currently Being Moderated
Hi, everyone. I’m completely new to Java 3D and I’m toying around with basic program structure right now. My code is based off of that in the first chapter on 3D in Killer Game Programming in Java. I removed most of the scene elements, replacing them with a simple grid, Maya style. (Yes, I’m starting off small, but my ambitions are grand – I intend on creating a polygonal modeling and animation toolset. After all, the Maya PLE is dead – damn you, Autodesk! – and I just plain dislike Blender.) I implement a simple OrbitBehavior as a means for the user to navigate the scene. That part was basically copy and paste from Andrew Davison’s code. The mystery, then, is why the program’s framerate drops below 1 FPS and its CPU Usage spikes to up to 90 percent, according to the Task Manager, when I tumble the scene. I’d appreciate anyone taking the time to look at the code and trying to identify the problem area. (I’ve undoubtedly missed something totally newbish. -.-) Thank you!

(Also, I had the worst possible time wrestling with the posting process. Is anyone else having trouble editing their posts before submitting them?)
import java.awt.*;
import javax.swing.*;

public class MAFrame
{
    public static final Dimension SCREEN_SIZE = Toolkit.getDefaultToolkit().getScreenSize();

    public MAFrame ()
    {
        System.out.println("Initializing...");
        
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } 
        catch (Exception e) {
            e.printStackTrace();
        }
        
        JFrame frame = new JFrame ("Modeling and Animation");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        MAViewPanel panel = new MAViewPanel ();
        
        frame.getContentPane().add(panel);
        frame.pack();        
        frame.setLocation(((int)SCREEN_SIZE.getWidth() / 2) - (frame.getWidth() / 2),
                          ((int)SCREEN_SIZE.getHeight() / 2) - (frame.getHeight() / 2));      
        frame.setVisible(true);
    }
}
import com.sun.j3d.utils.behaviors.vp.*;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import java.awt.*;
import javax.media.j3d.*;
import javax.swing.*;
import javax.vecmath.*;

public class MAViewPanel extends JPanel
{
    public static final int GRID_SIZE = 12;
    public static final int GRID_SPACING = 4;

    public BoundingSphere bounds;
    public BranchGroup sceneBG;
    public SimpleUniverse su;
    
    public MAViewPanel ()
    {
        GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas3D = new Canvas3D (config);                
        canvas3D.setSize(600, 600);
        add(canvas3D);
        canvas3D.setFocusable(true);
        canvas3D.requestFocus();

        su = new SimpleUniverse (canvas3D);
        
        createSceneGraph();
        initUserPosition();
        orbitControls(canvas3D);
        
        su.addBranchGraph(sceneBG);
    }

    public void createSceneGraph ()
    {
        sceneBG = new BranchGroup ();
        bounds = new BoundingSphere (new Point3d(0, 0, 0), 1000);

        // ambient light
        Color3f white = new Color3f (1.0f, 1.0f, 1.0f);
        
        AmbientLight ambientLight = new AmbientLight (white);
        ambientLight.setInfluencingBounds(bounds);
        sceneBG.addChild(ambientLight);
        
        // background
        Background background = new Background ();
        background.setColor(0.17f, 0.65f, 0.92f);
        background.setApplicationBounds(bounds);        
        sceneBG.addChild(background);

        // grid
        createGrid();
        
        sceneBG.compile();
    }

    public void createGrid ()
    {
        Shape3D grid = new Shape3D();
        LineArray lineArr = new LineArray (GRID_SIZE * 8 + 4, GeometryArray.COORDINATES);
        
        int offset = GRID_SIZE * GRID_SPACING;
        // both sides of the grid plus the middle, done for both directions at once (each line defined by two points)
        for (int count = 0, index = 0; count < GRID_SIZE * 2 + 1; count++) {
            // vertical, left to right
            lineArr.setCoordinate(index++, new Point3d (-offset + (count * GRID_SPACING), 0, offset));  // starts near
            lineArr.setCoordinate(index++, new Point3d (-offset + (count * GRID_SPACING), 0, -offset)); // ends far
            
            // horizontal, near to far
            lineArr.setCoordinate(index++, new Point3d (-offset, 0, offset - (count * GRID_SPACING))); // starts left
            lineArr.setCoordinate(index++, new Point3d (offset, 0, offset - (count * GRID_SPACING)));  // ends right
        }
        
        grid.setGeometry(lineArr);
        sceneBG.addChild(grid);
    }
    
    public void initUserPosition ()
    {
        ViewingPlatform vp = su.getViewingPlatform();
        TransformGroup tg = vp.getViewPlatformTransform();
        
        Transform3D t3d = new Transform3D ();
        tg.getTransform(t3d);
        
        t3d.lookAt(new Point3d (0, 60, 80), new Point3d (0, 0, 0), new Vector3d(0, 1, 0));
        t3d.invert();
        
        tg.setTransform(t3d);
        
        su.getViewer().getView().setBackClipDistance(100);
    }
    
    private void orbitControls (Canvas3D c)
    {
        OrbitBehavior orbit = new OrbitBehavior (c, OrbitBehavior.REVERSE_ALL);
        orbit.setSchedulingBounds(bounds);
        
        ViewingPlatform vp = su.getViewingPlatform();
        vp.setViewPlatformBehavior(orbit);      
    }
}