diff --git a/.classpath b/.classpath
index 5cde1e7..c7a0cd7 100644
--- a/.classpath
+++ b/.classpath
@@ -9,7 +9,7 @@
-
+
diff --git a/src/sg/SpaceGame2.java b/src/sg/SpaceGame2.java
new file mode 100644
index 0000000..8e5b5ef
--- /dev/null
+++ b/src/sg/SpaceGame2.java
@@ -0,0 +1,181 @@
+package sg;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import sg.states.InGameState;
+import sg.states.MenuState;
+
+import com.jme.app.AbstractGame;
+import com.jme.app.BaseGame;
+import com.jme.input.KeyBindingManager;
+import com.jme.input.KeyInput;
+import com.jme.input.MouseInput;
+import com.jme.input.joystick.JoystickInput;
+import com.jme.renderer.ColorRGBA;
+import com.jme.renderer.Renderer;
+import com.jme.system.DisplaySystem;
+import com.jme.system.JmeException;
+import com.jme.util.GameTaskQueue;
+import com.jme.util.GameTaskQueueManager;
+import com.jme.util.TextureManager;
+import com.jme.util.Timer;
+import com.jmex.game.state.GameStateManager;
+
+public class SpaceGame2 extends BaseGame {
+ private static final Logger logger = Logger.getLogger(SpaceGame2.class.getName());
+
+ public static final String TITLE = "SpaceGame";
+
+ /** Time per frame */
+ protected float tpf;
+ /** High resolution timer for jME. */
+ protected Timer timer;
+
+ public static void main(String[] args) {
+ SpaceGame2 game = new SpaceGame2();
+ game.setConfigShowMode(ConfigShowMode.AlwaysShow);
+ game.start();
+ }
+
+ /**
+ * Creates display, sets up camera, and binds keys. Called in
+ * BaseGame.start() directly after the dialog box.
+ *
+ * @see AbstractGame#initSystem()
+ */
+ protected void initSystem() throws JmeException {
+ logger.info(getVersion());
+ try {
+ /**
+ * Get a DisplaySystem acording to the renderer selected in the
+ * startup box.
+ */
+ display = DisplaySystem.getDisplaySystem(settings.getRenderer() );
+
+ // Alpha bits to use for the renderer. Any changes must be made prior to call of start().
+ display.setMinAlphaBits( 0 );
+ // Depth bits to use for the renderer. Any changes must be made prior to call of start().
+ display.setMinDepthBits( 8 );
+ // Stencil bits to use for the renderer. Any changes must be made prior to call of start().
+ display.setMinStencilBits( 0 );
+ // Number of samples to use for the multisample buffer. Any changes must be made prior to call of start().
+ display.setMinSamples( 0 );
+
+ /** Create a window with the startup box's information. */
+ display.createWindow(settings.getWidth(), settings.getHeight(),
+ settings.getDepth(), settings.getFrequency(),
+ settings.isFullscreen() );
+ logger.info("Running on: " + display.getAdapter()
+ + "\nDriver version: " + display.getDriverVersion() + "\n"
+ + display.getDisplayVendor() + " - "
+ + display.getDisplayRenderer() + " - "
+ + display.getDisplayAPIVersion());
+
+
+ } catch ( JmeException e ) {
+ /**
+ * If the displaysystem can't be initialized correctly, exit
+ * instantly.
+ */
+ logger.log(Level.SEVERE, "Could not create displaySystem", e);
+ System.exit( 1 );
+ }
+
+ /** Set a black background. */
+ display.getRenderer().setBackgroundColor( ColorRGBA.black.clone() );
+
+ /** Get a high resolution timer for FPS updates. */
+ timer = Timer.getTimer();
+
+ /** Sets the title of our display. */
+ display.setTitle( TITLE );
+
+ }
+
+ @Override
+ protected void initGame() {
+ GameStateManager.getInstance().attachChild(new MenuState("menu"));
+ GameStateManager.getInstance().attachChild(new InGameState("ingame"));
+
+ timer.reset();
+ }
+
+ @Override
+ protected void update(float interpolation) {
+ /** Recalculate the framerate. */
+ timer.update();
+ /** Update tpf to time per frame according to the Timer. */
+ tpf = timer.getTimePerFrame();
+
+ // Execute updateQueue item
+ GameTaskQueueManager.getManager().getQueue(GameTaskQueue.UPDATE).execute();
+
+ GameStateManager.getInstance().update(tpf);
+
+
+ if ( KeyBindingManager.getKeyBindingManager().isValidCommand(
+ "mem_report", false ) ) {
+ long totMem = Runtime.getRuntime().totalMemory();
+ long freeMem = Runtime.getRuntime().freeMemory();
+ long maxMem = Runtime.getRuntime().maxMemory();
+
+ logger.info("|*|*| Memory Stats |*|*|");
+ logger.info("Total memory: "+(totMem>>10)+" kb");
+ logger.info("Free memory: "+(freeMem>>10)+" kb");
+ logger.info("Max memory: "+(maxMem>>10)+" kb");
+ }
+
+ if ( KeyBindingManager.getKeyBindingManager().isValidCommand( "exit",
+ false ) ) {
+ finish();
+ }
+ }
+
+ /**
+ * Clears stats, the buffers and renders bounds and normals if on.
+ *
+ * @param interpolation unused in this implementation
+ * @see AbstractGame#render(float interpolation)
+ */
+ protected void render( float interpolation ) {
+ Renderer r = display.getRenderer();
+ /** Clears the previously rendered information. */
+ r.clearBuffers();
+
+ // Execute renderQueue item
+ GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER).execute();
+
+ GameStateManager.getInstance().render(tpf);
+ }
+
+ @Override
+ protected void reinit() {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * Cleans up the keyboard.
+ *
+ * @see AbstractGame#cleanup()
+ */
+ protected void cleanup() {
+ logger.info( "Cleaning up resources." );
+
+ TextureManager.doTextureCleanup();
+ if (display != null && display.getRenderer() != null)
+ display.getRenderer().cleanup();
+ KeyInput.destroyIfInitalized();
+ MouseInput.destroyIfInitalized();
+ JoystickInput.destroyIfInitalized();
+ }
+
+ /**
+ * Calls the quit of BaseGame to clean up the display and then closes the JVM.
+ */
+ protected void quit() {
+ super.quit();
+ System.exit( 0 );
+ }
+}
\ No newline at end of file
diff --git a/src/sg/input/FirstPersonHandler.java b/src/sg/input/FirstPersonHandler.java
new file mode 100644
index 0000000..062fde0
--- /dev/null
+++ b/src/sg/input/FirstPersonHandler.java
@@ -0,0 +1,6 @@
+package sg.input;
+
+
+public class FirstPersonHandler extends GlobalInputHandler{
+
+}
diff --git a/src/sg/input/GlobalInputHandler.java b/src/sg/input/GlobalInputHandler.java
new file mode 100644
index 0000000..3129bc2
--- /dev/null
+++ b/src/sg/input/GlobalInputHandler.java
@@ -0,0 +1,14 @@
+package sg.input;
+
+import com.jme.input.InputHandler;
+
+public abstract class GlobalInputHandler extends InputHandler {
+
+ public GlobalInputHandler(){
+ /*
+ if ( KeyBindingManager.getKeyBindingManager().isValidCommand( "exit", false ) ) {
+ finish();
+ }
+ */
+ }
+}
diff --git a/src/sg/input/ThirdPersonHandler.java b/src/sg/input/ThirdPersonHandler.java
new file mode 100644
index 0000000..6957312
--- /dev/null
+++ b/src/sg/input/ThirdPersonHandler.java
@@ -0,0 +1,14 @@
+package sg.input;
+
+import com.jme.input.ChaseCamera;
+import com.jme.renderer.Camera;
+import com.jme.scene.Spatial;
+
+
+public class ThirdPersonHandler extends GlobalInputHandler{
+
+ public ThirdPersonHandler(Camera cam, Spatial ship){
+ ChaseCamera ccam = new ChaseCamera(cam, ship);
+ this.addToAttachedHandlers(ccam);
+ }
+}
diff --git a/src/sg/states/InGameState.java b/src/sg/states/InGameState.java
new file mode 100644
index 0000000..938c06f
--- /dev/null
+++ b/src/sg/states/InGameState.java
@@ -0,0 +1,84 @@
+package sg.states;
+
+import java.util.logging.Logger;
+
+import sg.env.Environment;
+import sg.util.SGUtil;
+
+import com.jme.input.InputHandler;
+import com.jme.input.ThirdPersonHandler;
+import com.jme.math.Vector3f;
+import com.jme.renderer.Renderer;
+import com.jme.scene.Node;
+import com.jme.system.DisplaySystem;
+import com.jmex.game.state.CameraGameState;
+import com.jmex.game.state.load.LoadingGameState;
+import com.jmex.physics.DynamicPhysicsNode;
+import com.jmex.physics.PhysicsDebugger;
+import com.jmex.physics.PhysicsSpace;
+import com.jmex.physics.StaticPhysicsNode;
+
+public class InGameState extends CameraGameState {
+ /** The Keyboard/ mous input handler */
+ protected InputHandler input;
+ /** The environment of the game */
+ protected Environment environment;
+ /** The physics space */
+ private PhysicsSpace physicsSpace;
+ /** The Speed of the physics */
+ private float physicsSpeed = 1;
+
+ public InGameState(String name) {
+ super(name);
+
+ LoadingGameState loader = new LoadingGameState(2);
+ loader.setActive(true);
+ // ***************** Load the Game **********************************
+
+ //physics
+ physicsSpace = PhysicsSpace.create();
+
+ physicsSpace.setDirectionalGravity(new Vector3f(0f, 0f, 0f));
+ StaticPhysicsNode staticNode = physicsSpace.createStaticNode();
+ DynamicPhysicsNode dynamicNode = physicsSpace.createDynamicNode();
+ rootNode.attachChild(dynamicNode);
+ rootNode.attachChild(staticNode);
+
+ // environment
+ environment = new Environment();
+ rootNode.attachChild(environment);
+ loader.increment();
+
+ // ship
+ Node ship = SGUtil.loadModel("sg/data/models/ships/G6.3ds");
+ ship.setLocalTranslation(new Vector3f(0,0,-40));
+ //ship.setLocalScale(0.01f);
+ rootNode.attachChild(ship);
+ loader.increment();
+
+ // inputs
+ input = new ThirdPersonHandler(ship, cam);
+ loader.increment();
+
+ // ***************** Done loading **********************************
+ loader.setActive(false);
+ this.setActive(true);
+ }
+
+ public void stateUpdate(float tpf) {
+ input.update(tpf);
+
+ environment.update();
+
+ if ( tpf > 0.2 || Float.isNaN( tpf ) ) {
+ Logger.getLogger( PhysicsSpace.LOGGER_NAME ).warning( "Maximum physics update interval is 0.2 seconds - capped." );
+ physicsSpace.update( 0.2f * physicsSpeed );
+ }
+ else physicsSpace.update( tpf * physicsSpeed );
+ }
+
+ public void stateRender(float tpf){
+ Renderer r = DisplaySystem.getDisplaySystem().getRenderer();
+ PhysicsDebugger.drawPhysics( physicsSpace, r );
+ }
+}
diff --git a/src/sg/states/MenuState.java b/src/sg/states/MenuState.java
new file mode 100644
index 0000000..e9a81b7
--- /dev/null
+++ b/src/sg/states/MenuState.java
@@ -0,0 +1,11 @@
+package sg.states;
+
+import com.jmex.game.state.BasicGameState;
+
+public class MenuState extends BasicGameState {
+
+ public MenuState(String name) {
+ super(name);
+ }
+
+}
diff --git a/src/sg/util/SGUtil.java b/src/sg/util/SGUtil.java
index c9bddf4..31565cc 100644
--- a/src/sg/util/SGUtil.java
+++ b/src/sg/util/SGUtil.java
@@ -5,7 +5,6 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
-import java.net.URL;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;