1/*
2 * To change this template, choose Tools | Templates
3 * and open the template in the editor.
4 */
5package jme3test.bullet;
6
7import com.jme3.app.Application;
8import com.jme3.asset.AssetManager;
9import com.jme3.asset.TextureKey;
10import com.jme3.bullet.PhysicsSpace;
11import com.jme3.bullet.collision.shapes.CollisionShape;
12import com.jme3.bullet.collision.shapes.MeshCollisionShape;
13import com.jme3.bullet.control.RigidBodyControl;
14import com.jme3.input.MouseInput;
15import com.jme3.input.controls.ActionListener;
16import com.jme3.input.controls.MouseButtonTrigger;
17import com.jme3.light.AmbientLight;
18import com.jme3.material.Material;
19import com.jme3.math.ColorRGBA;
20import com.jme3.renderer.queue.RenderQueue.ShadowMode;
21import com.jme3.scene.Geometry;
22import com.jme3.scene.Node;
23import com.jme3.scene.shape.Box;
24import com.jme3.scene.shape.Sphere;
25import com.jme3.scene.shape.Sphere.TextureMode;
26import com.jme3.texture.Texture;
27
28/**
29 *
30 * @author normenhansen
31 */
32public class PhysicsTestHelper {
33
34    /**
35     * creates a simple physics test world with a floor, an obstacle and some test boxes
36     * @param rootNode
37     * @param assetManager
38     * @param space
39     */
40    public static void createPhysicsTestWorld(Node rootNode, AssetManager assetManager, PhysicsSpace space) {
41        AmbientLight light = new AmbientLight();
42        light.setColor(ColorRGBA.LightGray);
43        rootNode.addLight(light);
44
45        Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
46        material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
47
48        Box floorBox = new Box(140, 0.25f, 140);
49        Geometry floorGeometry = new Geometry("Floor", floorBox);
50        floorGeometry.setMaterial(material);
51        floorGeometry.setLocalTranslation(0, -5, 0);
52//        Plane plane = new Plane();
53//        plane.setOriginNormal(new Vector3f(0, 0.25f, 0), Vector3f.UNIT_Y);
54//        floorGeometry.addControl(new RigidBodyControl(new PlaneCollisionShape(plane), 0));
55        floorGeometry.addControl(new RigidBodyControl(0));
56        rootNode.attachChild(floorGeometry);
57        space.add(floorGeometry);
58
59        //movable boxes
60        for (int i = 0; i < 12; i++) {
61            Box box = new Box(0.25f, 0.25f, 0.25f);
62            Geometry boxGeometry = new Geometry("Box", box);
63            boxGeometry.setMaterial(material);
64            boxGeometry.setLocalTranslation(i, 5, -3);
65            //RigidBodyControl automatically uses box collision shapes when attached to single geometry with box mesh
66            boxGeometry.addControl(new RigidBodyControl(2));
67            rootNode.attachChild(boxGeometry);
68            space.add(boxGeometry);
69        }
70
71        //immovable sphere with mesh collision shape
72        Sphere sphere = new Sphere(8, 8, 1);
73        Geometry sphereGeometry = new Geometry("Sphere", sphere);
74        sphereGeometry.setMaterial(material);
75        sphereGeometry.setLocalTranslation(4, -4, 2);
76        sphereGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(sphere), 0));
77        rootNode.attachChild(sphereGeometry);
78        space.add(sphereGeometry);
79
80    }
81
82    public static void createPhysicsTestWorldSoccer(Node rootNode, AssetManager assetManager, PhysicsSpace space) {
83        AmbientLight light = new AmbientLight();
84        light.setColor(ColorRGBA.LightGray);
85        rootNode.addLight(light);
86
87        Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
88        material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
89
90        Box floorBox = new Box(140, 0.25f, 140);
91        Geometry floorGeometry = new Geometry("Floor", floorBox);
92        floorGeometry.setMaterial(material);
93        floorGeometry.setLocalTranslation(0, -0.25f, 0);
94//        Plane plane = new Plane();
95//        plane.setOriginNormal(new Vector3f(0, 0.25f, 0), Vector3f.UNIT_Y);
96//        floorGeometry.addControl(new RigidBodyControl(new PlaneCollisionShape(plane), 0));
97        floorGeometry.addControl(new RigidBodyControl(0));
98        rootNode.attachChild(floorGeometry);
99        space.add(floorGeometry);
100
101        //movable spheres
102        for (int i = 0; i < 5; i++) {
103            Sphere sphere = new Sphere(16, 16, .5f);
104            Geometry ballGeometry = new Geometry("Soccer ball", sphere);
105            ballGeometry.setMaterial(material);
106            ballGeometry.setLocalTranslation(i, 2, -3);
107            //RigidBodyControl automatically uses Sphere collision shapes when attached to single geometry with sphere mesh
108            ballGeometry.addControl(new RigidBodyControl(.001f));
109            ballGeometry.getControl(RigidBodyControl.class).setRestitution(1);
110            rootNode.attachChild(ballGeometry);
111            space.add(ballGeometry);
112        }
113
114        //immovable Box with mesh collision shape
115        Box box = new Box(1, 1, 1);
116        Geometry boxGeometry = new Geometry("Box", box);
117        boxGeometry.setMaterial(material);
118        boxGeometry.setLocalTranslation(4, 1, 2);
119        boxGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(box), 0));
120        rootNode.attachChild(boxGeometry);
121        space.add(boxGeometry);
122
123    }
124
125    /**
126     * creates a box geometry with a RigidBodyControl
127     * @param assetManager
128     * @return
129     */
130    public static Geometry createPhysicsTestBox(AssetManager assetManager) {
131        Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
132        material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
133        Box box = new Box(0.25f, 0.25f, 0.25f);
134        Geometry boxGeometry = new Geometry("Box", box);
135        boxGeometry.setMaterial(material);
136        //RigidBodyControl automatically uses box collision shapes when attached to single geometry with box mesh
137        boxGeometry.addControl(new RigidBodyControl(2));
138        return boxGeometry;
139    }
140
141    /**
142     * creates a sphere geometry with a RigidBodyControl
143     * @param assetManager
144     * @return
145     */
146    public static Geometry createPhysicsTestSphere(AssetManager assetManager) {
147        Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
148        material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
149        Sphere sphere = new Sphere(8, 8, 0.25f);
150        Geometry boxGeometry = new Geometry("Sphere", sphere);
151        boxGeometry.setMaterial(material);
152        //RigidBodyControl automatically uses sphere collision shapes when attached to single geometry with sphere mesh
153        boxGeometry.addControl(new RigidBodyControl(2));
154        return boxGeometry;
155    }
156
157    /**
158     * creates an empty node with a RigidBodyControl
159     * @param manager
160     * @param shape
161     * @param mass
162     * @return
163     */
164    public static Node createPhysicsTestNode(AssetManager manager, CollisionShape shape, float mass) {
165        Node node = new Node("PhysicsNode");
166        RigidBodyControl control = new RigidBodyControl(shape, mass);
167        node.addControl(control);
168        return node;
169    }
170
171    /**
172     * creates the necessary inputlistener and action to shoot balls from teh camera
173     * @param app
174     * @param rootNode
175     * @param space
176     */
177    public static void createBallShooter(final Application app, final Node rootNode, final PhysicsSpace space) {
178        ActionListener actionListener = new ActionListener() {
179
180            public void onAction(String name, boolean keyPressed, float tpf) {
181                Sphere bullet = new Sphere(32, 32, 0.4f, true, false);
182                bullet.setTextureMode(TextureMode.Projected);
183                Material mat2 = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
184                TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG");
185                key2.setGenerateMips(true);
186                Texture tex2 = app.getAssetManager().loadTexture(key2);
187                mat2.setTexture("ColorMap", tex2);
188                if (name.equals("shoot") && !keyPressed) {
189                    Geometry bulletg = new Geometry("bullet", bullet);
190                    bulletg.setMaterial(mat2);
191                    bulletg.setShadowMode(ShadowMode.CastAndReceive);
192                    bulletg.setLocalTranslation(app.getCamera().getLocation());
193                    RigidBodyControl bulletControl = new RigidBodyControl(1);
194                    bulletg.addControl(bulletControl);
195                    bulletControl.setLinearVelocity(app.getCamera().getDirection().mult(25));
196                    bulletg.addControl(bulletControl);
197                    rootNode.attachChild(bulletg);
198                    space.add(bulletControl);
199                }
200            }
201        };
202        app.getInputManager().addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
203        app.getInputManager().addListener(actionListener, "shoot");
204    }
205}
206