-
-
Save skapral/73358cfcd4ddf48a132a5119020fece6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Main extends SimpleApplication { | |
public static void main(String[] args){ | |
Main app = new Main(); | |
app.start(); | |
} | |
@Override | |
public void simpleInitApp() { | |
flyCam.setEnabled(false); | |
assetManager.addClassLoader(Main.class.getClassLoader()); | |
stateManager.attach(new CameraControl(Vector3f.UNIT_Y, Vector3f.UNIT_X, Vector3f.UNIT_Z, 20)); | |
stateManager.attach(new Scene(rootNode)); | |
Arrow arrow = new Arrow(Vector3f.UNIT_X.mult(50)); | |
putShape(arrow, ColorRGBA.Red); | |
arrow = new Arrow(Vector3f.UNIT_Y.mult(50)); | |
putShape(arrow, ColorRGBA.Blue); | |
arrow = new Arrow(Vector3f.UNIT_Z.mult(50)); | |
putShape(arrow, ColorRGBA.Green); | |
} | |
private Geometry putShape(Mesh shape, ColorRGBA color) { | |
Geometry g = new Geometry("coordinate axis", shape); | |
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); | |
mat.getAdditionalRenderState().setWireframe(true); | |
mat.getAdditionalRenderState().setLineWidth(4); | |
mat.setColor("Color", color); | |
g.setMaterial(mat); | |
rootNode.attachChild(g); | |
return g; | |
} | |
} | |
public class CameraControl extends AbstractAppState implements AnalogListener, ActionListener { | |
public static final String NORTH = "CC_N"; | |
public static final String SOUTH = "CC_S"; | |
public static final String WEST = "CC_W"; | |
public static final String EAST = "CC_E"; | |
public static final String UP = "CC_U"; | |
public static final String DOWN = "CC_D"; | |
private final Vector3f north; | |
private final Vector3f east; | |
private final Vector3f up; | |
private final float moveSpeed; | |
private float frustumSize; | |
private InputManager inputManager; | |
private Camera camera; | |
public CameraControl(Vector3f north, Vector3f east, Vector3f up, float moveSpeed) { | |
this.north = north; | |
this.east = east; | |
this.up = up; | |
this.moveSpeed = moveSpeed; | |
} | |
@Override | |
public void stateAttached(AppStateManager stateManager) { | |
super.stateAttached(stateManager); | |
inputManager = stateManager.getApplication().getInputManager(); | |
camera = stateManager.getApplication().getCamera(); | |
frustumSize = 5; | |
setupCamera(); | |
setupInputManager(); | |
} | |
@Override | |
public void stateDetached(AppStateManager stateManager) { | |
super.stateDetached(stateManager); | |
inputManager.removeListener(this); | |
} | |
private void setupCamera() { | |
float aspect = (float) camera.getWidth() / camera.getHeight(); | |
camera.setFrustum(-1000, 1000, -aspect * frustumSize, aspect * frustumSize, frustumSize, -frustumSize); | |
camera.setParallelProjection(true); | |
//camera.setLocation(new Vector3f(0f, 200f, 0f)); | |
//camera.lookAt(new Vector3f(0f, 0f, 0f), new Vector3f(0f, 0f, 1f)); | |
camera.setLocation(new Vector3f(0f, 0f, 200f)); | |
camera.lookAt(new Vector3f(0f, 0f, 0f), new Vector3f(0f, 0f, 1f)); | |
} | |
private void setupInputManager() { | |
inputManager.addMapping(NORTH, new KeyTrigger(KeyInput.KEY_W)); | |
inputManager.addMapping(SOUTH, new KeyTrigger(KeyInput.KEY_S)); | |
inputManager.addMapping(WEST, new KeyTrigger(KeyInput.KEY_A)); | |
inputManager.addMapping(EAST, new KeyTrigger(KeyInput.KEY_D)); | |
inputManager.addMapping(UP, new MouseAxisTrigger(MouseInput.AXIS_WHEEL, false)); | |
inputManager.addMapping(DOWN, new MouseAxisTrigger(MouseInput.AXIS_WHEEL, true)); | |
inputManager.setCursorVisible(true); | |
inputManager.addListener(this, new String[]{ | |
NORTH, SOUTH, WEST, EAST, UP, DOWN | |
}); | |
} | |
private void moveNorth(float v) { | |
Vector3f pos = camera.getLocation().clone(); | |
camera.setLocation(pos.addLocal(north.mult(v * moveSpeed * frustumSize))); | |
} | |
private void moveEast(float v) { | |
Vector3f pos = camera.getLocation().clone(); | |
camera.setLocation(pos.addLocal(east.mult(v * moveSpeed * frustumSize))); | |
} | |
private void moveUp(float v) { | |
frustumSize += moveSpeed * v; | |
frustumSize = frustumSize < 1 ? 1 : frustumSize; | |
frustumSize = frustumSize > 100 ? 100 : frustumSize; | |
setupCamera(); | |
} | |
@Override | |
public void onAnalog(String name, float value, float tpf) { | |
System.out.println(name + " " + value + " " + tpf); | |
switch (name) { | |
case NORTH: { | |
moveNorth(value); | |
break; | |
} | |
case SOUTH: { | |
moveNorth(-value); | |
break; | |
} | |
case WEST: { | |
moveEast(-value); | |
break; | |
} | |
case EAST: { | |
moveEast(value); | |
break; | |
} | |
case UP: { | |
moveUp(value); | |
break; | |
} | |
case DOWN: { | |
moveUp(-value); | |
break; | |
} | |
default: { | |
} | |
} | |
} | |
@Override | |
public void onAction(String name, boolean value, float tpf) { | |
System.out.println(name + " " + value + " " + tpf); | |
} | |
} | |
public class Scene extends AbstractAppState implements AnalogListener { | |
public static final String SELECT = "SC_SEL"; | |
public static final String CMD = "SC_CMD"; | |
private Camera camera; | |
private InputManager inputManager; | |
private AssetManager assetManager; | |
private Node sceneNode; | |
private final Node rootNode; | |
public Scene(Node rootNode) { | |
this.rootNode = rootNode; | |
} | |
@Override | |
public void stateAttached(AppStateManager stateManager) { | |
super.stateAttached(stateManager); | |
inputManager = stateManager.getApplication().getInputManager(); | |
assetManager = stateManager.getApplication().getAssetManager(); | |
camera = stateManager.getApplication().getCamera(); | |
sceneNode = new Node("Scene"); | |
createTerrain(); | |
rootNode.attachChild(sceneNode); | |
inputManager.addMapping(SELECT, new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); | |
inputManager.addMapping(CMD, new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); | |
inputManager.addListener(this, new String[] { SELECT, CMD }); | |
} | |
@Override | |
public void stateDetached(AppStateManager stateManager) { | |
super.stateDetached(stateManager); | |
rootNode.detachChild(sceneNode); | |
inputManager.removeListener(this); | |
} | |
@Override | |
public void onAnalog(String name, float value, float tpf) { | |
if (name.equals(SELECT)) { | |
CollisionResults results = new CollisionResults(); | |
Vector2f click2d = inputManager.getCursorPosition(); | |
Vector3f click3d = camera.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 1f).clone(); | |
System.out.println(click3d); | |
Vector3f dir = camera.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).subtractLocal(click3d).normalizeLocal(); | |
System.out.println(dir); | |
Ray ray = new Ray(click3d, dir); | |
sceneNode.collideWith(ray, results); | |
System.out.println(results.size()); | |
for (int i = 0; i < results.size(); i++) { | |
// (For each “hit”, we know distance, impact point, geometry.) | |
float dist = results.getCollision(i).getDistance(); | |
Vector3f pt = results.getCollision(i).getContactPoint(); | |
String target = results.getCollision(i).getGeometry().getName(); | |
System.out.println("Selection #" + i + ": " + target + " at " + pt + ", " + dist + " WU away."); | |
} | |
} | |
} | |
private void createTerrain() { | |
Material mat_terrain = new Material(assetManager,"Common/MatDefs/Terrain/Terrain.j3md"); | |
mat_terrain.setTexture("Alpha", new Texture2D(generateImage(16, 16))); | |
Texture grass = assetManager.loadTexture("JME/Textures/grass.jpg"); | |
grass.setWrap(Texture.WrapMode.Repeat); | |
mat_terrain.setTexture("Tex1", grass); | |
mat_terrain.setFloat("Tex1Scale", 16f); | |
Texture dirt = assetManager.loadTexture("JME/Textures/dirt.jpg"); | |
dirt.setWrap(Texture.WrapMode.Repeat); | |
mat_terrain.setTexture("Tex2", dirt); | |
mat_terrain.setFloat("Tex2Scale", 16f); | |
Texture rock = assetManager.loadTexture("JME/Textures/road.jpg"); | |
rock.setWrap(Texture.WrapMode.Repeat); | |
mat_terrain.setTexture("Tex3", rock); | |
mat_terrain.setFloat("Tex3Scale", 16f); | |
HeightMap heightmap = new RawHeightMap(new float[1025]); | |
TerrainQuad terrain = new TerrainQuad("my terrain", 5, 129, heightmap.getHeightMap()); | |
terrain.rotate(FastMath.HALF_PI, 0, 0); | |
terrain.setMaterial(mat_terrain); | |
sceneNode = terrain; | |
} | |
private Image generateImage(int width, int height) { | |
ByteBuffer bb = ByteBuffer.allocateDirect(width*height*4); | |
bb.position(0); | |
bb.put(ColorRGBA.Green.asBytesRGBA()); | |
for(int i=4; i < width*height*4; i+=4) | |
{ | |
ColorRGBA color = i % 8 != 0 ? ColorRGBA.Blue : ColorRGBA.Red; | |
bb.position(i); | |
bb.put(color.asBytesRGBA()); | |
} | |
bb.rewind(); | |
return new Image(Image.Format.RGBA8, width, height, bb, ColorSpace.sRGB); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment