diff --git a/core/src/se/cookery/CookeryClient.java b/core/src/se/cookery/CookeryClient.java index faecf83..fa24022 100644 --- a/core/src/se/cookery/CookeryClient.java +++ b/core/src/se/cookery/CookeryClient.java @@ -2,23 +2,31 @@ package se.cookery; import com.jme3.app.FlyCamAppState; import com.jme3.app.SimpleApplication; +import com.jme3.collision.CollisionResults; import com.jme3.input.ChaseCamera; +import com.jme3.input.KeyInput; import com.jme3.input.MouseInput; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; import com.jme3.input.controls.MouseButtonTrigger; import com.jme3.math.ColorRGBA; +import com.jme3.math.Ray; +import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.post.FilterPostProcessor; import com.jme3.scene.Geometry; import se.cookery.core.world.Block; import se.cookery.core.world.gen.GrassLandWorldGenerator; import se.cookery.gfx.character.Player; +import se.cookery.gfx.input.WireFrameToggleAction; import se.cookery.gfx.terrain.TerrainMesh; import se.cookery.gfx.util.MaterialUtil; -import se.cookery.gfx.util.WireFrameProcessor; import com.jme3.post.filters.CartoonEdgeFilter; public class CookeryClient extends SimpleApplication { + private ChaseCamera chaseCam; + @Override public void simpleInitApp() { // ----------------------------------------- @@ -27,7 +35,7 @@ public class CookeryClient extends SimpleApplication { Block block = new GrassLandWorldGenerator().generateBlock(0, 0); - Geometry terrain = new Geometry("terrain", new TerrainMesh(1, 1, Block.BLOCK_SIZE, Block.BLOCK_SIZE)); + Geometry terrain = new Geometry("Terrain", new TerrainMesh(1, 1, Block.BLOCK_SIZE, Block.BLOCK_SIZE)); terrain.setMaterial(MaterialUtil.createMaterial(assetManager, ColorRGBA.Green)); rootNode.attachChild(terrain); @@ -42,24 +50,23 @@ public class CookeryClient extends SimpleApplication { // Setup Camera // ----------------------------------------- -// flyCam.setMoveSpeed(15); + flyCam.setMoveSpeed(15); // cam.setLocation(new Vector3f(0,10,-20)); // cam.lookAt(new Vector3f(0f,0f,0f), Vector3f.UNIT_Z); - flyCam.setEnabled(false); - ChaseCamera chaseCam = new ChaseCamera(cam, player.getGfxNode(), inputManager); + chaseCam = new ChaseCamera(cam, player.getGfxNode(), inputManager); chaseCam.setDefaultDistance(10); chaseCam.setRotationSpeed(2); chaseCam.setLookAtOffset(Vector3f.UNIT_Y); chaseCam.setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); + flyCam.setEnabled(false); + chaseCam.setEnabled(true); + // ----------------------------------------- // Setup Shaders // ----------------------------------------- - // Wireframe mode -// viewPort.addProcessor(new WireFrameProcessor(assetManager)); - // Cartoon shader FilterPostProcessor fpp = new FilterPostProcessor(assetManager); CartoonEdgeFilter toon = new CartoonEdgeFilter(); @@ -68,5 +75,59 @@ public class CookeryClient extends SimpleApplication { toon.setNormalThreshold(0.8f); fpp.addFilter(toon); viewPort.addProcessor(fpp); + + initializeInputs(); + } + + /** + * Custom Keybinding: Map named actions to inputs. + */ + private void initializeInputs() { + // Setup listeners + inputManager.addMapping("ToggleKeyframe", new KeyTrigger(KeyInput.KEY_W)); + inputManager.addMapping("Click", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); + + // Setup the action listeners + inputManager.addListener(new WireFrameToggleAction(assetManager, viewPort), "ToggleKeyframe"); + inputManager.addListener(analogListener, "Click"); + + } + + private AnalogListener analogListener = new AnalogListener() { + public void onAnalog(String name, float value, float tpf) { + // Convert screen click to 3d position + Vector2f screenVector = inputManager.getCursorPosition(); + Vector3f worldVector = cam.getWorldCoordinates(new Vector2f(screenVector.x, screenVector.y), 0f).clone(); + Vector3f direction = cam.getWorldCoordinates(new Vector2f(screenVector.x, screenVector.y), 1f).subtractLocal(worldVector).normalizeLocal(); + + // Aim the ray from the clicked spot forwards. + Ray ray = new Ray(worldVector, direction); + + // Collect intersections between ray and all nodes in results list. + CollisionResults results = new CollisionResults(); + rootNode.collideWith(ray, results); + + // (Print the results so we see what is going on:) + for (int i = 0; i < results.size(); i++) { + System.out.println("Selection #" + i + ": " + + "Geometry: " + results.getCollision(i).getGeometry().getName() + ", " + + "Contact: " + results.getCollision(i).getContactPoint() + ", " + + "Distance: " + results.getCollision(i).getDistance() + " WU"); + } + System.out.println(); + + // Use the results -- we rotate the selected geometry. + if (results.size() > 0) { + // The closest result is the target that the player picked: + Geometry target = results.getClosestCollision().getGeometry(); + // Here comes the action: + target.setLocalTranslation(target.getLocalTranslation().add(1, 0, 0)); + } + } + }; + + @Override + public void simpleUpdate(float tpf) { + chaseCam.update(tpf); } } \ No newline at end of file diff --git a/core/src/se/cookery/gfx/input/WireFrameToggleAction.java b/core/src/se/cookery/gfx/input/WireFrameToggleAction.java new file mode 100644 index 0000000..b9d60e5 --- /dev/null +++ b/core/src/se/cookery/gfx/input/WireFrameToggleAction.java @@ -0,0 +1,27 @@ +package se.cookery.gfx.input; + +import com.jme3.asset.AssetManager; +import com.jme3.input.controls.ActionListener; +import com.jme3.renderer.ViewPort; +import se.cookery.gfx.util.WireFrameProcessor; + +public class WireFrameToggleAction implements ActionListener { + private ViewPort viewPort; + private WireFrameProcessor processor; + + public WireFrameToggleAction(AssetManager assetManager, ViewPort viewPort) { + this.viewPort = viewPort; + this.processor = new WireFrameProcessor(assetManager); + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + if (viewPort.getProcessors().contains(processor)) { + viewPort.removeProcessor(processor); + } else { + viewPort.addProcessor(processor); + } + } + } +} diff --git a/core/src/se/cookery/gfx/util/AnimationUtil.java b/core/src/se/cookery/gfx/util/AnimationUtil.java new file mode 100644 index 0000000..0aa4b96 --- /dev/null +++ b/core/src/se/cookery/gfx/util/AnimationUtil.java @@ -0,0 +1,19 @@ +package se.cookery.gfx.util; + +import com.jme3.animation.AnimControl; +import com.jme3.animation.AnimationFactory; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; + +/** + * Utility functions for animations + */ +public class AnimationUtil { + + public static void translationAnimation(Geometry geom, Vector3f target, float time) { + AnimationFactory animation = new AnimationFactory(time, "TranslationAnimation"); + animation.addTimeTranslation(0, geom.getLocalTranslation()); + animation.addTimeTranslation(time, target); + geom.getControl(AnimControl.class).addAnim(animation.buildAnimation()); + } +}