Contributions

I know I've been slacking off on my developer responsibilities lately, but I'll try to make good on it over the next few months. :wink:



I have a few things I've written that I think might be useful in jME but wanted to get some feedback first. If no one sees any reason not to contribute these I'll stick them into CVS today.



See the messages below:

DummyTimer - This is a timer using nanoTime.  I use it primarily on headless servers so it doesn't have issues with LWJGL.  It was originally decided that we couldn't stick this into jME since it was using 1.5 compliant code, but now that CVS is 1.5 compliant I thought this might be beneficial:


/*
 * Created on Feb 22, 2006
 */
package com.captiveimagination.jme;

import com.jme.util.*;

/**
 * @author Matthew D. Hicks
 */
public class DummyTimer extends Timer {
    private static final long TIMER_RESOLUTION = 1000000000;
   
    private long startTime;
    private long previousTime;
    private float tpf;
    private float fps;
   
    public DummyTimer() {
        startTime = System.nanoTime();
    }
   
    public long getTime() {
        return System.nanoTime() - startTime;
    }

    public long getResolution() {
        return TIMER_RESOLUTION;
    }

    public float getFrameRate() {
        return fps;
    }

    public float getTimePerFrame() {
        return tpf;
    }

    public void update() {
        tpf = (getTime() - previousTime) * (1.0f / TIMER_RESOLUTION);
        fps = 1.0f / tpf;
        previousTime = getTime();
    }
   
    public void reset() {
       // TODO necessary to implement?
   }
}

DesktopBox - I really don't know if this would be valuable to anyone else, and I'm sure it could have been done more efficiently, but this is the core of the menu everyone seemed to love on Roll-A-Rama (ironic that everyone seemed to like it more than the game itself).  I'm happy to contribute it but as I said, I'm not sure if it would be useful to anyone but me.  It's specifically designed around JMEDesktop:


/*
 * Created on Jan 12, 2006
 */
package com.captiveimagination.jme;

import java.awt.*;

import com.jme.input.*;
import com.jme.math.*;
import com.jme.renderer.*;
import com.jme.scene.*;
import com.jme.scene.state.*;
import com.jmex.awt.swingui.*;

/**
 * @author Matthew D. Hicks
 */
public class DesktopBox extends Node {
    private static final long serialVersionUID = 1L;

    private static Vector3f temp = new Vector3f();
   
    public static final int NONE = 0;
    public static final int ONE = 1;
    public static final int TWO = 2;
    public static final int THREE = 3;
    public static final int FOUR = 4;
    public static final int FIVE = 5;
    public static final int SIX = 6;
   
    private InputHandler input;
    private Camera camera;
    private JMEDesktop deskOne, deskTwo, deskThree, deskFour, deskFive, deskSix;
    private InputHandler inputOne, inputTwo, inputThree, inputFour, inputFive, inputSix;
    private int position;
   
    private Vector3f cameraLocation;
   
    public DesktopBox(Camera camera) {
        super("DesktopBox");
        input = new InputHandler();
        this.camera = camera;
        init();
        position = ONE;
    }
   
    public void init() {
        inputOne = new InputHandler();
        input.addToAttachedHandlers(inputOne);
        deskOne = new JMEDesktop("DesktopOne", 250, 250, inputOne);
        configure(deskOne);
        deskOne.getLocalTranslation().set(0.0f, 0.0f, 50.0f);
        deskOne.lock();
       
        inputTwo = new InputHandler();
        inputTwo.setEnabled(false);
        input.addToAttachedHandlers(inputTwo);
        deskTwo = new JMEDesktop("DesktopTwo", 250, 250, inputTwo);
        configure(deskTwo);
        deskTwo.getLocalTranslation().set(50.0f, 0.0f, 0.0f);
        deskTwo.getLocalRotation().fromAngleAxis(0.5f * FastMath.PI, new Vector3f(0.0f, 1.0f, 0.0f));
        deskTwo.lock();
       
        inputThree = new InputHandler();
        inputThree.setEnabled(false);
        input.addToAttachedHandlers(inputThree);
        deskThree = new JMEDesktop("DesktopThree", 250, 250, inputThree);
        configure(deskThree);
        deskThree.getLocalTranslation().set(0.0f, 0.0f, -50.0f);
        deskThree.getLocalRotation().fromAngleAxis(1.0f * FastMath.PI, new Vector3f(0.0f, 1.0f, 0.0f));
        deskThree.lock();
       
        inputFour = new InputHandler();
        inputFour.setEnabled(false);
        input.addToAttachedHandlers(inputFour);
        deskFour = new JMEDesktop("DesktopFour", 250, 250, inputFour);
        configure(deskFour);
        deskFour.getLocalTranslation().set(-50.0f, 0.0f, 0.0f);
        deskFour.getLocalRotation().fromAngleAxis(1.5f * FastMath.PI, new Vector3f(0.0f, 1.0f, 0.0f));
        deskFour.lock();
       
        inputFive = new InputHandler();
        inputFive.setEnabled(false);
        input.addToAttachedHandlers(inputFive);
        deskFive = new JMEDesktop("DesktopFive", 250, 250, inputFive);
        configure(deskFive);
        deskFive.getLocalTranslation().set(0.0f, 50.0f, 0.0f);
        Quaternion q = new Quaternion();
        q.fromAngleAxis(1.0f * FastMath.PI, new Vector3f(0.0f, 1.0f, 0.0f));
        deskFive.getLocalRotation().fromAngleAxis(0.5f * FastMath.PI, new Vector3f(1.0f, 0.0f, 0.0f));
        deskFive.getLocalRotation().multLocal(q);
        deskFive.lock();
       
        inputSix = new InputHandler();
        inputSix.setEnabled(false);
        input.addToAttachedHandlers(inputSix);
        deskSix = new JMEDesktop("DesktopSix", 250, 250, inputSix);
        configure(deskSix);
        deskSix.getLocalTranslation().set(0.0f, -50.0f, 0.0f);
        deskSix.getLocalRotation().fromAngleAxis(0.5f * FastMath.PI, new Vector3f(1.0f, 0.0f, 0.0f));
        deskSix.lock();
       
        setCullMode(Spatial.CULL_NEVER);
        setLightCombineMode(LightState.OFF);
        updateRenderState();
        updateGeometricState(0.0f, true);
    }
   
    public int getPosition() {
        return position;
    }
   
    private void configure(JMEDesktop desktop) {
        desktop.setLocalScale(new Vector3f(0.4f, 0.4f, 0.4f));
        desktop.getJDesktop().setBackground(new Color(0.0f, 0.0f, 1.0f, 0.2f));
        attachChild(desktop);
    }

    public void update(float interpolation) {
        if (cameraLocation != null) {
            camera.setLocation(cameraLocation);
            if ((camera.getLocation().x == 0.0f) && (camera.getLocation().z == 0.0f)) {
                camera.lookAt(new Vector3f(0.0f, 0.0f, 0.0f), new Vector3f(0.0f, 0.0f, 1.0f));
            } else {
                camera.lookAt(new Vector3f(0.0f, 0.0f, 0.0f), new Vector3f(0.0f, 1.0f, 0.0f));
            }
        }
        input.update(interpolation);
    }
   
    public void setCameraLocation(Vector3f cameraLocation) {
        this.cameraLocation = cameraLocation;
    }
   
    public JMEDesktop getDeskFive() {
        return deskFive;
    }

    public JMEDesktop getDeskFour() {
        return deskFour;
    }

    public JMEDesktop getDeskOne() {
        return deskOne;
    }
   
    public JMEDesktop getDeskSix() {
        return deskSix;
    }
   
    public JMEDesktop getDeskThree() {
        return deskThree;
    }

    public JMEDesktop getDeskTwo() {
        return deskTwo;
    }
   
    public void moveTo(int endPosition) {
        setEnabled(position, false);
        rotate(250.0f, getPosition(position), getPosition(endPosition));
        setEnabled(endPosition, true);
        position = endPosition;
    }
   
    public void setEnabled(int position, boolean enabled) {
        InputHandler input = null;
        if (position == ONE) {
            input = inputOne;
        } else if (position == TWO) {
            input = inputTwo;
        } else if (position == THREE) {
            input = inputThree;
        } else if (position == FOUR) {
            input = inputFour;
        } else if (position == FIVE) {
            input = inputFive;
        } else if (position == SIX) {
            input = inputSix;
        }
        input.setEnabled(enabled);
    }
   
    public void setEnabled(boolean enabled) {
        if (enabled) {
            inputOne.setEnabled(false);
            inputTwo.setEnabled(false);
            inputThree.setEnabled(false);
            inputFour.setEnabled(false);
            inputFive.setEnabled(false);
            inputSix.setEnabled(false);
            setEnabled(position, enabled);
        } else {
            inputOne.setEnabled(enabled);
            inputTwo.setEnabled(enabled);
            inputThree.setEnabled(enabled);
            inputFour.setEnabled(enabled);
            inputFive.setEnabled(enabled);
            inputSix.setEnabled(enabled);
        }
    }
   
    public static Vector3f getPosition(int position) {
        if (position == ONE) {
            return new Vector3f(0.0f, 0.0f, 250.0f);
        } else if (position == TWO) {
            return new Vector3f(250.0f, 0.0f, 0.0f);
        } else if (position == THREE) {
            return new Vector3f(0.0f, 0.0f, -250.0f);
        } else if (position == FOUR) {
            return new Vector3f(-250.0f, 0.0f, 0.0f);
        } else if (position == FIVE) {
            return new Vector3f(0.0f, 250.0f, 0.0f);
        } else if (position == SIX) {
            return new Vector3f(0.0f, -250.0f, 0.0f);
        }
        return null;
    }
 
    private void rotate(float distance, Vector3f start, Vector3f end) {
        float inc = 0.01f;
        start.subtract(end, temp);
       
        if (temp.x == 0) {
            if (FastMath.abs(end.y) < FastMath.abs(start.y)) {
                inc = -inc;
            }
        } else if (temp.y == 0) {
            if (FastMath.abs(end.x) < FastMath.abs(start.x)) {
                inc = -inc;
            }
        } else if (temp.z == 0) {
            if (FastMath.abs(end.x) < FastMath.abs(start.x)) {
                inc = -inc;
            }
        }
        float r = distance;
        float a;
        float x = 0.0f;
        float y = 0.0f;
        float z = 0.0f;
       
        float angle = 0.01f;
        if (inc < 0) {
            angle = 0.49f;
        }
        for (int i = 1; i < 50; i++) {
            angle += inc;
            a = 2 * r * FastMath.sin(0.5f * angle * (FastMath.PI * 2));
           
            if (temp.x == 0) {
                y = ((a * a) / (2 * a));
                if ((start.y < 0) || (end.y < 0)) {
                    y = -y;
                }
                z = FastMath.sqrt((r * r) - (y * y));
                if ((start.z < 0) || (end.z < 0)) {
                    z = -z;
                }
            } else if (temp.y == 0) {
                x = ((a * a) / (2 * a));
                if ((start.x < 0) || (end.x < 0)) {
                    x = -x;
                }
                z = FastMath.sqrt((r * r) - (x * x));
                if ((start.z < 0) || (end.z < 0)) {
                    z = -z;
                }
            } else if (temp.z == 0) {
                x = ((a * a) / (2 * a));
                if ((start.x < 0) || (end.x < 0)) {
                    x = -x;
                }
                y = FastMath.sqrt((r * r) - (x * x));
                if ((start.y < 0) || (end.y < 0)) {
                    y = -y;
                }
            }
            cameraLocation = new Vector3f(x, y, z);
           
            try {
                Thread.sleep(10);
            } catch(InterruptedException exc) {
                exc.printStackTrace();
            }
        }
    }

    public void dispose() {
        getDeskOne().dispose();
        getDeskTwo().dispose();
        getDeskThree().dispose();
        getDeskFour().dispose();
        getDeskFive().dispose();
        getDeskSix().dispose();
    }
}

Finally, I have a lot of revisions to GameStates that I'll be working on today.  I'll post another topic about that when I've made some decisions about how I'd like to do it and then get some feedback.