Easy Canvas -> dryed RenParticleEditor

Drying out RenParticleEditor. Easy canvas method. :lol:


// JAVA imports
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.io.File;
import java.net.URL;
import java.util.concurrent.Callable;

// JAVAX imports
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.UIManager;

// JME imports
import com.jme.image.Texture;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Geometry;
import com.jme.scene.Node;
import com.jme.scene.SceneElement;
import com.jme.scene.Spatial;
import com.jme.scene.Text;
import com.jme.scene.state.RenderState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.util.GameTaskQueue;
import com.jme.util.GameTaskQueueManager;
import com.jmex.awt.JMECanvas;
import com.jmex.awt.SimpleCanvasImpl;
import com.jmex.effects.particles.ParticleGeometry;

public class RenParticleEditor extends JFrame {

    public static Node particleNode;
    public static ParticleGeometry particleGeom;
    private static final long serialVersionUID = 1L;
    int width = 640, height = 480;
    MyImplementor impl;
    private CameraHandler camhand;
    private Canvas glCanvas;
    private Node root;
    private Geometry grid;

    private File openFile;

    /**
     * Main Entry point...
     *
     * @param args
     *            String[]
     */
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
        }
        new RenParticleEditor();
    }

    public RenParticleEditor() {
        try {
            init();
            // center the frame
            setLocationRelativeTo(null);

            // show frame
            setVisible(true);

            while (glCanvas == null);

            // MAKE SURE YOU REPAINT SOMEHOW OR YOU WON'T SEE THE UPDATES...
            new Thread() {

                {
                    setDaemon(true);
                }

                public void run() {
                    try {
                        while (true) {
//                            if (isVisible()) {
                                glCanvas.repaint();
//                            }
                            Thread.sleep(2);
                        }
                    } catch (InterruptedException e) {
                    }
                }
            }.start();

        } catch (Exception ex) {
        }
    }

    private void init() throws Exception {
        updateTitle();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setFont(new Font("Arial", 0, 12));

        JPanel canvasPanel = new JPanel();
        canvasPanel.setLayout(new BorderLayout());
        canvasPanel.add(getGlCanvas(), BorderLayout.CENTER);

        JSplitPane mainSplit = new JSplitPane();
        mainSplit.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
        mainSplit.setRightComponent(canvasPanel);

        Dimension minimumSize = new Dimension(100, 50);
        canvasPanel.setMinimumSize(minimumSize);

        getContentPane().add(mainSplit, BorderLayout.CENTER);

        this.setSize(800, 600);
    }

    private void updateTitle() {
        setTitle("Particle System Editor" + (openFile == null ? "" : (" - " + openFile)));
    }

    private void createNewSystem() {
        particleNode.detachAllChildren();
        openFile = null;
        updateTitle();
    }
   
    private ColorRGBA makeColorRGBA(Color color) {
        return new ColorRGBA(color.getRed() / 255f, color.getGreen() / 255f,
                color.getBlue() / 255f, color.getAlpha() / 255f);
    }

    protected Canvas getGlCanvas() {
        if (glCanvas == null) {

            //


GL STUFF

            // make the canvas:
            glCanvas = DisplaySystem.getDisplaySystem().createCanvas(width, height);
            glCanvas.setMinimumSize(new Dimension(100, 100));

            // add a listener... if window is resized, we can do something about
            // it.
            glCanvas.addComponentListener(new ComponentAdapter() {

                public void componentResized(ComponentEvent ce) {
                    doResize();
                }
            });

            camhand = new CameraHandler();

            glCanvas.addMouseWheelListener(camhand);
            glCanvas.addMouseListener(camhand);
            glCanvas.addMouseMotionListener(camhand);

            // Important! Here is where we add the guts to the canvas:
            impl = new MyImplementor(width, height);
           
            ((JMECanvas) glCanvas).setImplementor(impl);

            //
END OF GL STUFF

            Callable<?> exe = new Callable() {

                public Object call() {
                    forceUpdateToSize();
                    return null;
                }
            };
            GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER).enqueue(exe);
        }
        return glCanvas;
    }

    public void forceUpdateToSize() {
        // force a resize to ensure proper canvas size.
        glCanvas.setSize(glCanvas.getWidth(), glCanvas.getHeight() + 1);
        glCanvas.setSize(glCanvas.getWidth(), glCanvas.getHeight() - 1);
    }

    class CameraHandler extends MouseAdapter implements MouseMotionListener,
            MouseWheelListener {

        Point last = new Point(0, 0);
        Vector3f focus = new Vector3f();
        private Vector3f vector = new Vector3f();
        private Quaternion rot = new Quaternion();

        public void mouseDragged(final MouseEvent arg0) {
            Callable<?> exe = new Callable() {

                public Object call() {
                    int difX = last.x - arg0.getX();
                    int difY = last.y - arg0.getY();
                    int mult = arg0.isShiftDown() ? 10 : 1;
                    last.x = arg0.getX();
                    last.y = arg0.getY();

                    int mods = arg0.getModifiers();
                    if ((mods & InputEvent.BUTTON1_MASK) != 0) {
                        rotateCamera(Vector3f.UNIT_Y, difX * 0.0025f);
                        rotateCamera(impl.getRenderer().getCamera().getLeft(),
                                -difY * 0.0025f);
                    }
                    if ((mods & InputEvent.BUTTON2_MASK) != 0 && difY != 0) {
                        zoomCamera(difY * mult);
                    }
                    if ((mods & InputEvent.BUTTON3_MASK) != 0) {
                        panCamera(-difX, -difY);
                    }
                    return null;
                }
            };
            GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER).enqueue(exe);
        }

        public void mouseMoved(MouseEvent arg0) {
        }

        public void mousePressed(MouseEvent arg0) {
            last.x = arg0.getX();
            last.y = arg0.getY();
        }

        public void mouseWheelMoved(final MouseWheelEvent arg0) {
            Callable<?> exe = new Callable() {

                public Object call() {
                    zoomCamera(arg0.getWheelRotation() * (arg0.isShiftDown() ? -100 : -20));
                    return null;
                }
            };
            GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER).enqueue(exe);
        }

        public void recenterCamera() {
            Callable<?> exe = new Callable() {

                public Object call() {
                    Camera cam = impl.getRenderer().getCamera();
                    Vector3f.ZERO.subtract(focus, vector);
                    cam.getLocation().addLocal(vector);
                    focus.addLocal(vector);
                    cam.onFrameChange();
                    return null;
                }
            };
            GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER).enqueue(exe);
        }

        private void rotateCamera(Vector3f axis, float amount) {
            Camera cam = impl.getRenderer().getCamera();
            if (axis.equals(cam.getLeft())) {
                float elevation = -FastMath.asin(cam.getDirection().y);
                amount = Math.min(Math.max(elevation + amount,
                        -FastMath.HALF_PI), FastMath.HALF_PI) - elevation;
            }
            rot.fromAngleAxis(amount, axis);
            cam.getLocation().subtract(focus, vector);
            rot.mult(vector, vector);
            focus.add(vector, cam.getLocation());
            rot.mult(cam.getLeft(), cam.getLeft());
            rot.mult(cam.getUp(), cam.getUp());
            rot.mult(cam.getDirection(), cam.getDirection());
            cam.normalize();
            cam.onFrameChange();
        }

        private void panCamera(float left, float up) {
            Camera cam = impl.getRenderer().getCamera();
            cam.getLeft().mult(left, vector);
            vector.scaleAdd(up, cam.getUp(), vector);
            cam.getLocation().addLocal(vector);
            focus.addLocal(vector);
            cam.onFrameChange();
        }

        private void zoomCamera(float amount) {
            Camera cam = impl.getRenderer().getCamera();
            float dist = cam.getLocation().distance(focus);
            amount = dist - Math.max(0f, dist - amount);
            cam.getLocation().scaleAdd(amount, cam.getDirection(),
                    cam.getLocation());
            cam.onFrameChange();
        }
    }

    protected void doResize() {
        if (impl != null) {
            impl.resizeCanvas(glCanvas.getWidth(), glCanvas.getHeight());
            if (impl.getCamera() != null) {
                Callable<?> exe = new Callable() {

                    public Object call() {
                        impl.getCamera().setFrustumPerspective(
                                45.0f,
                                (float) glCanvas.getWidth() / (float) glCanvas.getHeight(), 1,
                                10000);
                        return null;
                    }
                };
                GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER).enqueue(exe);
            }
        }
    }

    // IMPLEMENTING THE SCENE:
    class MyImplementor extends SimpleCanvasImpl {

        private static final int GRID_LINES = 51;
        private static final float GRID_SPACING = 100f;
        /**
         * The root node of our text.
         */
        protected Node fpsNode;
        /**
         * Displays all the lovely information at the bottom.
         */
        protected Text fps;
        /**
         * This is used to recieve getStatistics calls.
         */
        protected StringBuffer tempBuffer = new StringBuffer();
        /**
         * This is used to display print text.
         */
        protected StringBuffer updateBuffer = new StringBuffer(30);

        public MyImplementor(int width, int height) {
            super(width, height);
        }

        public void simpleSetup() {
            Color bg = new Color(0,0,0);
            renderer.setBackgroundColor(makeColorRGBA(bg));
            cam.setFrustumPerspective(45.0f, (float) glCanvas.getWidth() / (float) glCanvas.getHeight(), 1, 10000);

            Vector3f loc = new Vector3f(0, 850, -850);
            Vector3f left = new Vector3f(1, 0, 0);
            Vector3f up = new Vector3f(0, 0.7071f, 0.7071f);
            Vector3f dir = new Vector3f(0, -0.7071f, 0.7071f);
            cam.setFrame(loc, left, up, dir);

            root = rootNode;

            // Then our font Text object.
            /** This is what will actually have the text at the bottom. */
            fps = Text.createDefaultTextLabel("FPS label");
            fps.setCullMode(SceneElement.CULL_NEVER);
            fps.setTextureCombineMode(TextureState.REPLACE);

            // Finally, a stand alone node (not attached to root on purpose)
            fpsNode = new Node("FPS node");
            fpsNode.setRenderState(fps.getRenderState(RenderState.RS_ALPHA));
            fpsNode.setRenderState(fps.getRenderState(RenderState.RS_TEXTURE));
            fpsNode.attachChild(fps);
            fpsNode.setCullMode(SceneElement.CULL_NEVER);

            renderer.enableStatistics(true);

            root.attachChild(grid = createGrid());
            grid.updateRenderState();

            particleNode = new Node("particles");
            root.attachChild(particleNode);

            ZBufferState zbuf = renderer.createZBufferState();
            zbuf.setWritable(false);
            zbuf.setEnabled(true);
            zbuf.setFunction(ZBufferState.CF_LEQUAL);

            particleNode.setRenderState(zbuf);
            particleNode.updateRenderState();

            fpsNode.updateGeometricState(0, true);
            fpsNode.updateRenderState();

            createNewSystem();

        }
        ;

        public void simpleUpdate() {
            updateBuffer.setLength(0);
            updateBuffer.append("FPS: ").append((int) timer.getFrameRate()).append(" - ");
            updateBuffer.append(renderer.getStatistics(tempBuffer));
            /** Send the fps to our fps bar at the bottom. */
            fps.print(updateBuffer);
        }

        @Override
        public void simpleRender() {
            fpsNode.draw(renderer);
            renderer.clearStatistics();
        }

        private Geometry createGrid() {
            Vector3f[] vertices = new Vector3f[GRID_LINES * 2 * 2];
            float edge = GRID_LINES / 2 * GRID_SPACING;
            for (int ii = 0, idx = 0; ii < GRID_LINES; ii++) {
                float coord = (ii - GRID_LINES / 2) * GRID_SPACING;
                vertices[idx++] = new Vector3f(-edge, 0f, coord);
                vertices[idx++] = new Vector3f(+edge, 0f, coord);
                vertices[idx++] = new Vector3f(coord, 0f, -edge);
                vertices[idx++] = new Vector3f(coord, 0f, +edge);
            }
            Geometry grid = new com.jme.scene.Line("grid", vertices, null,
                    null, null);
            grid.getBatch(0).getDefaultColor().set(ColorRGBA.darkGray.clone());
            return grid;
        }
    }
}



Just grab what u need and put in your class.

Now u can use it.

whats the difference or advantage to the original RenParticleEditor ?

No one. No advantage, here u only have a example whiteout all particle methods. Only what u need to have a canvas in your project.  :stuck_out_tongue: