package lecture17; import com.jme3.app.SimpleApplication; import com.jme3.collision.CollisionResults; import com.jme3.light.DirectionalLight; import com.jme3.material.Material; import com.jme3.math.ColorRGBA; import com.jme3.math.FastMath; import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; import com.jme3.scene.Geometry; import com.jme3.scene.Node; import com.jme3.scene.shape.Box; import com.jme3.scene.shape.Sphere; public class Example01 extends SimpleApplication { Geometry floor1, floor2, floor3; Node boxes; Geometry ball; Vector3f floor2Normal = new Vector3f(-1f, 2f, 0).normalize(); Vector3f floor3Normal = new Vector3f(1f, 2f, 0).normalize(); float mass = 1f; float viscosity = 0.1f; float energyLoss = 0.95f; Vector3f gravity = new Vector3f(0, -9.8f, 0); Vector3f force = new Vector3f(0, 0, 0); Vector3f velocity = new Vector3f(3, 0, 0); Vector3f acceleration = new Vector3f(0, 0, 0); protected Geometry boxFromNormal(String name, Vector3f n) { Box b = new Box(10f, 1f, 10f); Geometry bg = new Geometry(name, b); Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); mat.setBoolean("UseMaterialColors", true); mat.setColor("Ambient", ColorRGBA.Gray); mat.setColor("Diffuse", ColorRGBA.Gray); bg.setMaterial(mat); Quaternion q = new Quaternion(); q.fromAxes(n.cross(Vector3f.UNIT_Z), n, Vector3f.UNIT_Z); bg.setLocalRotation(q); return bg; } public void simpleInitApp() { DirectionalLight sun = new DirectionalLight(); sun.setDirection(new Vector3f(1, -5, -7)); sun.setColor(ColorRGBA.White); rootNode.addLight(sun); boxes = new Node("boxes"); floor1 = boxFromNormal("floor1", Vector3f.UNIT_Y); boxes.attachChild(floor1); floor2 = boxFromNormal("floor2", floor2Normal); floor2.setLocalTranslation(18.5f, 4.5f, 0); boxes.attachChild(floor2); floor3 = boxFromNormal("floor3", floor3Normal); floor3.setLocalTranslation(-18.5f, 4.5f, 0); boxes.attachChild(floor3); rootNode.attachChild(boxes); Sphere s = new Sphere(60, 60, 1.5f); ball = new Geometry("Sphere", s); Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); mat.setBoolean("UseMaterialColors", true); mat.setColor("Ambient", ColorRGBA.Red); mat.setColor("Diffuse", ColorRGBA.Red); ball.setMaterial(mat); ball.move(5, 20, 0); rootNode.attachChild(ball); cam.setLocation(new Vector3f(0, 10, 100)); cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); } @Override public void simpleUpdate(float tpf) { acceleration = gravity.add(force.divide(mass)); velocity = velocity.add(acceleration.mult(tpf)); force = velocity.mult(-viscosity); ball.move(velocity.mult(tpf)); CollisionResults results = new CollisionResults(); boxes.collideWith(ball.getWorldBound(), results); if (results.size() > 0) { String closestGeom = results.getClosestCollision().getGeometry().getName(); if (closestGeom.equals("floor1")) { velocity.setY(FastMath.abs(energyLoss * velocity.getY())); } else if (closestGeom.equals("floor2")) { float projVal = velocity.dot(floor2Normal); Vector3f projection = floor2Normal.mult(projVal); Vector3f parall = velocity.subtract(projection); velocity = parall.add(floor2Normal.mult(energyLoss * FastMath.abs(projVal))); } else if (closestGeom.equals("floor3")) { float projVal = velocity.dot(floor3Normal); Vector3f projection = floor3Normal.mult(projVal); Vector3f parall = velocity.subtract(projection); velocity = parall.add(floor3Normal.mult(energyLoss * FastMath.abs(projVal))); } } } public static void main(String[] args) { Example01 app = new Example01(); app.start(); } }