Hi All I intend to draw a bunch grass in java3d. I divided the x-z plane to several blocks and in each block I choose some points randomly as the start point of the grasses and draw a projectile path with random initial velocity and angle. My problem is when I increase the number of grass in each block (for example to 15 grass per block), the program exits by java.lang.OutOfMemoryError. Does anybody have any idea to improve the performance? Actually, I even don't know why this error occurs! Does it really need much memory?!
BTW, I create a BranchGroup for each grass and add it to the main BranchGroup. Yours, Siamak This is the code: ////////////////////////////////////////////////////////////////////// package j3dtest.ui; import java.awt.BorderLayout; import java.awt.Dimension; import java.util.Random; import javax.vecmath.Point3d; import com.sun.j3d.utils.universe.SimpleUniverse; import com.sun.j3d.utils.behaviors.mouse.MouseZoom; import javax.vecmath.Color3f; import java.awt.Color; import javax.swing.JSpinner; import javax.swing.SpinnerNumberModel; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; import javax.swing.JFrame; import javax.media.j3d.BranchGroup; import javax.media.j3d.Canvas3D; import javax.media.j3d.Transform3D; import javax.swing.JToolBar; import javax.swing.JLabel; import javax.swing.JColorChooser; import javax.swing.JPanel; import javax.swing.JButton; import javax.media.j3d.LineStripArray; import javax.media.j3d.GeometryArray; import javax.media.j3d.TransformGroup; import javax.media.j3d.Shape3D; import javax.media.j3d.BoundingSphere; import javax.swing.BorderFactory; public class MainFrame extends JFrame implements ActionListener, MouseListener { private BorderLayout borderLayout1 = new BorderLayout(); private BranchGroup scene = null; private Canvas3D canvas3d = null; private final int n = 10; private SimpleUniverse universe = null; private Transform3D transform3d = new Transform3D(); private Random rand = new Random(); private double pX = 0; private double pY = 0; private double pZ = 0; double oX = 0; double oZ = 0; double step = 0; double grassHeight = 0; double px = 0; double py = 0; private final double limit = 0.05; private JToolBar toolbar = new JToolBar(); private JLabel lblGrassNum = new JLabel("Grass Count: "); private JLabel lblGrassHeight = new JLabel("Grass Height: "); private JLabel lblFColor = new JLabel("Far Color: "); private JLabel lblCColor = new JLabel("Close Color: "); private JSpinner spnGrassNum = new JSpinner(); private JSpinner spnGrassHeight = new JSpinner(); private JColorChooser ccColor = new JColorChooser(); private JPanel pnlFColor = new JPanel(); private JPanel pnlCColor = new JPanel(); private JButton btnApply = new JButton("Apply"); private JButton btnReset = new JButton("Reset"); private JButton btnExit = new JButton("Exit"); public MainFrame(String title) { super(title); try { jbInit(); } catch (Exception ex) { ex.printStackTrace(); } } public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if ("exit".equals(cmd)) { System.exit(0); } else if ("apply".equals(cmd)) { redrawGrass(); } else if ("reset".equals(cmd)) { spnGrassHeight.setValue(new Float(0.05)); spnGrassNum.setValue(new Integer(8)); pnlFColor.setBackground(new Color(60, 106, 38)); pnlCColor.setBackground(new Color(69, 171, 19)); redrawGrass(); } } public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1) { if (e.getSource() instanceof JPanel) { JPanel panel = (JPanel) e.getSource(); String title = (panel == pnlFColor ? "Select Far Color" : "Select Close Color"); Color dc = (panel == pnlFColor ? pnlFColor.getBackground() : pnlCColor.getBackground()); Color c = ccColor.showDialog(this, title, dc); if (c != null) { if (panel == pnlFColor) { pnlFColor.setBackground(c); } else { pnlCColor.setBackground(c); } /** @todo Update Canvas3D */ } } } } public void mouseReleased(MouseEvent e) { } private void drawGrass() { btnApply.setEnabled(false); btnReset.setEnabled(false); transform3d.rotX(Math.PI / 10); Point3d p = new Point3d(0, 0, 0); double baseX = -0.7; double baseZ = -0.7; int iLimit = (int) ((Math.abs(baseZ) * 2) / limit); int jLimit = (int) ((Math.abs(baseX) * 2) / limit); Color fc = pnlFColor.getBackground(); float rStart = fc.getRed() / 256.0f; float gStart = fc.getGreen() / 256.0f; float bStart = fc.getBlue() / 256.0f; Color cc = pnlCColor.getBackground(); float rEnd = cc.getRed() / 256.0f; float gEnd = cc.getGreen() / 256.0f; float bEnd = cc.getBlue() / 256.0f; Color3f c = new Color3f(rStart, gStart, bStart); float rStep = (rEnd - rStart) / iLimit; float gStep = (gEnd - gStart) / iLimit; float bStep = (bEnd - bStart) / iLimit; double grassNumber = Double.parseDouble(spnGrassNum.getValue().toString()); double bX = 0; double bZ = 0; double r = 0; double angle = 0; double v0 = 0; Point3d base = new Point3d(0, 0, 0); for (int i = 0; i < iLimit; i++) { c.set(rStart + i * rStep, gStart + i * gStep, bStart + i * bStep); for (int j = 0; j < jLimit; j++) { bX = baseX + (j + 1.0 / 2) * limit; bZ = baseZ + (i + 1.0 / 2) * limit; base.x = bX; base.y = 0; base.z = bZ; for (int k = 0; k < grassNumber; k++) { r = rand.nextDouble(); angle = Math.PI / (r + 2.1); v0 = 2.1 - r; addGrass(rand.nextBoolean(), base, limit, angle, v0, c, (rand.nextDouble() * 2 - 1) * 1); } } } btnApply.setEnabled(true); btnReset.setEnabled(true); } private void redrawGrass() { scene.detach(); setupScene(); universe.addBranchGraph(scene); drawGrass(); } private void addGrass(boolean dir, Point3d origin, double limit, double angle, double v0, Color3f color, double zFactor) { LineStripArray lsa = new LineStripArray(n, GeometryArray.COORDINATES | GeometryArray.COLOR_3, new int[] {n}); oX = origin.x + (rand.nextDouble() - 0.5) * limit; oZ = origin.z + (rand.nextDouble() - 0.5) * limit; step = limit / (2 * n); pX = 0; pY = 0; pZ = 0; grassHeight = Double.parseDouble(spnGrassHeight.getValue().toString()); px = 0; py = 0; for (int i = 0; i < n; i++) { lsa.setCoordinate(i, new Point3d(dir ? oX + pX : oX - pX, pY, oZ + pZ)); lsa.setColor(i, color); px = pX + step; py = getProjectileY(angle, v0, pX); if ((grassHeight > 0) && (py <= grassHeight)) { pY = py; pX = px; pZ = pX * zFactor; } else if ((grassHeight <= 0) && (py <= limit)) { pY = py; pX = px; pZ = pX * zFactor; } } BranchGroup bg = new BranchGroup(); TransformGroup tg1 = new TransformGroup(transform3d); tg1.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); tg1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); Shape3D sh3d = new Shape3D(lsa); tg1.addChild(sh3d); bg.addChild(tg1); MouseZoom zoom = new MouseZoom(tg1); zoom.setSchedulingBounds(new BoundingSphere()); bg.addChild(zoom); bg.compile(); scene.addChild(bg); } private double getProjectileY(double angle, double v0, double x) { return x * Math.tan(angle) - (9.8 * x * x) / (2 * Math.pow(v0 * Math.cos(angle), 2)); } private void jbInit() throws Exception { getContentPane().setLayout(borderLayout1); canvas3d = new Canvas3D(null); canvas3d.setDoubleBufferEnable(true); getContentPane().add(canvas3d, BorderLayout.CENTER); // Init Components Dimension sep = new Dimension(15, 22); Dimension txtDim = new Dimension(45, 22); Dimension btnDim = new Dimension(80, 22); getContentPane().add(toolbar, BorderLayout.NORTH); spnGrassNum.setPreferredSize(txtDim); spnGrassNum.setMaximumSize(txtDim); spnGrassNum.setModel(new SpinnerNumberModel(8, 1, 50, 1)); toolbar.add(lblGrassNum); toolbar.add(spnGrassNum); toolbar.addSeparator(); spnGrassHeight.setPreferredSize(txtDim); spnGrassHeight.setMaximumSize(txtDim); spnGrassHeight.setModel(new SpinnerNumberModel(0.05, 0.01, 1.00, 0.01)); toolbar.add(lblGrassHeight); toolbar.add(spnGrassHeight); toolbar.addSeparator(); Dimension pnlDim = new Dimension(15, 15); pnlFColor.setMinimumSize(pnlDim); pnlFColor.setMaximumSize(pnlDim); pnlFColor.setPreferredSize(pnlDim); pnlFColor.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY)); pnlFColor.addMouseListener(this); pnlFColor.setBackground(new Color(60, 106, 38)); toolbar.add(lblFColor); toolbar.add(pnlFColor); toolbar.addSeparator(); pnlCColor.setMinimumSize(pnlDim); pnlCColor.setMaximumSize(pnlDim); pnlCColor.setPreferredSize(pnlDim); pnlCColor.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY)); pnlCColor.addMouseListener(this); pnlCColor.setBackground(new Color(69, 171, 19)); toolbar.add(lblCColor); toolbar.add(pnlCColor); btnApply.setPreferredSize(btnDim); btnApply.setMaximumSize(btnDim); btnReset.setPreferredSize(btnDim); btnReset.setMaximumSize(btnDim); btnExit.setPreferredSize(btnDim); btnExit.setMaximumSize(btnDim); toolbar.addSeparator(); btnApply.setActionCommand("apply"); btnApply.addActionListener(this); btnReset.setActionCommand("reset"); btnReset.addActionListener(this); btnExit.setActionCommand("exit"); btnExit.addActionListener(this); toolbar.add(btnApply); toolbar.add(btnReset); toolbar.add(btnExit); setupScene(); universe = new SimpleUniverse(canvas3d); universe.getViewingPlatform().setNominalViewingTransform(); universe.addBranchGraph(scene); drawGrass(); } private void setupScene() { scene = new BranchGroup(); scene.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); scene.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); scene.setCapability(BranchGroup.ALLOW_CHILDREN_READ); scene.setCapability(BranchGroup.ALLOW_DETACH); scene.setCapability(BranchGroup.ALLOW_LOCAL_TO_VWORLD_READ); scene.compile(); } public static void main(String[] args) { // try { // UIManager.setLookAndFeel(UIManager. // getSystemLookAndFeelClassName()); // } catch (UnsupportedLookAndFeelException ex) { // } catch (IllegalAccessException ex) { // } catch (InstantiationException ex) { // } catch (ClassNotFoundException ex) { // } MainFrame frame = new MainFrame("Grass"); frame.setSize(new Dimension(700, 600)); frame.setResizable(false); frame.setLocation(100, 100); frame.show(); } } //////////////////////////////////////////////////////////////// =========================================================================== To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA3D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".