package lecture16; import com.jme3.app.SimpleApplication; import com.jme3.light.DirectionalLight; import com.jme3.material.Material; import com.jme3.math.ColorRGBA; import com.jme3.math.Vector3f; import com.jme3.scene.Geometry; import com.jme3.scene.shape.Sphere; public class Example05 extends SimpleApplication { // world constants final float g = 9.8f; final Vector3f gravity = new Vector3f(0, -g, 0); final float b = 0.9f; // distance to travel final float distance = 100f; // how fast along the x axis. Play with this value! final float vx = 20f; final float m = 1f; // mass final float eps = 1f; // error float step = 50f; // iteration steps //Geometries Geometry bullet; Geometry target; Vector3f velocity = new Vector3f(0, 0, 0); Vector3f force = new Vector3f(0, 0, 0); Vector3f oldVelocity = new Vector3f(0, 0, 0); Vector3f acceleration = new Vector3f(0, 0, 0); boolean overshot = false; private Geometry makeBall(ColorRGBA color) { Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); mat.setBoolean("UseMaterialColors", true); mat.setColor("Ambient", color); mat.setColor("Diffuse", color); Sphere s = new Sphere(60, 60, 1.5f); Geometry geom = new Geometry("Sphere", s); geom.setMaterial(mat); return geom; } public void simpleInitApp() { DirectionalLight sun = new DirectionalLight(); sun.setDirection(new Vector3f(-10, 2, -2).normalize()); sun.setColor(ColorRGBA.White); rootNode.addLight(sun); bullet = makeBall(ColorRGBA.Blue); rootNode.attachChild(bullet); target = makeBall(ColorRGBA.Red); rootNode.attachChild(target); target.move(distance, 0, 0); float vy = (g * distance) / (2 * vx); velocity = new Vector3f(vx, vy, 0); oldVelocity = velocity; cam.setLocation(new Vector3f(distance + 50, 0, 15)); cam.lookAt(new Vector3f(3 * distance / 4f, 0, 0), Vector3f.UNIT_Y); } @Override public void simpleUpdate(float tpf) { boolean relaunch = false; if (bullet.getLocalTranslation().getY() >= 0) { // Linear drag for added fun force = velocity.mult(-b); acceleration = gravity.add(force.divide(m)); velocity = velocity.add(acceleration.mult(tpf)); bullet.move(velocity.mult(tpf)); } else { if (bullet.getLocalTranslation().length() + eps < distance) { if (overshot) { step = step / 2f; } velocity = oldVelocity.add(step, 0, 0); relaunch = true; } else if (bullet.getLocalTranslation().length() - eps > distance) { if (!overshot) { step = step / 2f; } velocity = oldVelocity.subtract(step, 0, 0); relaunch = true; } if (relaunch) { oldVelocity = velocity; bullet.setLocalTranslation(0, 0, 0); } } } public static void main(String[] args) { Example05 app = new Example05(); app.start(); } }