• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2009-2010 jMonkeyEngine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *  notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *  notice, this list of conditions and the following disclaimer in the
14  *  documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17  *  may be used to endorse or promote products derived from this software
18  *  without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 package jme3test.helloworld;
34 
35 import com.jme3.app.SimpleApplication;
36 import com.jme3.asset.TextureKey;
37 import com.jme3.bullet.BulletAppState;
38 import com.jme3.bullet.control.RigidBodyControl;
39 import com.jme3.font.BitmapText;
40 import com.jme3.input.MouseInput;
41 import com.jme3.input.controls.ActionListener;
42 import com.jme3.input.controls.MouseButtonTrigger;
43 import com.jme3.material.Material;
44 import com.jme3.math.Vector2f;
45 import com.jme3.math.Vector3f;
46 import com.jme3.scene.Geometry;
47 import com.jme3.scene.shape.Box;
48 import com.jme3.scene.shape.Sphere;
49 import com.jme3.scene.shape.Sphere.TextureMode;
50 import com.jme3.texture.Texture;
51 import com.jme3.texture.Texture.WrapMode;
52 
53 /**
54  * Example 12 - how to give objects physical properties so they bounce and fall.
55  * @author base code by double1984, updated by zathras
56  */
57 public class HelloPhysics extends SimpleApplication {
58 
main(String args[])59   public static void main(String args[]) {
60     HelloPhysics app = new HelloPhysics();
61     app.start();
62   }
63 
64   /** Prepare the Physics Application State (jBullet) */
65   private BulletAppState bulletAppState;
66 
67   /** Prepare Materials */
68   Material wall_mat;
69   Material stone_mat;
70   Material floor_mat;
71 
72   /** Prepare geometries and physical nodes for bricks and cannon balls. */
73   private RigidBodyControl    brick_phy;
74   private static final Box    box;
75   private RigidBodyControl    ball_phy;
76   private static final Sphere sphere;
77   private RigidBodyControl    floor_phy;
78   private static final Box    floor;
79 
80   /** dimensions used for bricks and wall */
81   private static final float brickLength = 0.48f;
82   private static final float brickWidth  = 0.24f;
83   private static final float brickHeight = 0.12f;
84 
85   static {
86     /** Initialize the cannon ball geometry */
87     sphere = new Sphere(32, 32, 0.4f, true, false);
88     sphere.setTextureMode(TextureMode.Projected);
89     /** Initialize the brick geometry */
90     box = new Box(Vector3f.ZERO, brickLength, brickHeight, brickWidth);
box.scaleTextureCoordinates(new Vector2f(1f, .5f))91     box.scaleTextureCoordinates(new Vector2f(1f, .5f));
92     /** Initialize the floor geometry */
93     floor = new Box(Vector3f.ZERO, 10f, 0.1f, 5f);
floor.scaleTextureCoordinates(new Vector2f(3, 6))94     floor.scaleTextureCoordinates(new Vector2f(3, 6));
95   }
96 
97   @Override
simpleInitApp()98   public void simpleInitApp() {
99     /** Set up Physics Game */
100     bulletAppState = new BulletAppState();
101     stateManager.attach(bulletAppState);
102     //bulletAppState.getPhysicsSpace().enableDebug(assetManager);
103     /** Configure cam to look at scene */
104     cam.setLocation(new Vector3f(0, 4f, 6f));
105     cam.lookAt(new Vector3f(2, 2, 0), Vector3f.UNIT_Y);
106     /** Initialize the scene, materials, inputs, and physics space */
107     initInputs();
108     initMaterials();
109     initWall();
110     initFloor();
111     initCrossHairs();
112   }
113 
114   /** Add InputManager action: Left click triggers shooting. */
initInputs()115   private void initInputs() {
116     inputManager.addMapping("shoot",
117             new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
118     inputManager.addListener(actionListener, "shoot");
119   }
120 
121   /**
122    * Every time the shoot action is triggered, a new cannon ball is produced.
123    * The ball is set up to fly from the camera position in the camera direction.
124    */
125   private ActionListener actionListener = new ActionListener() {
126     public void onAction(String name, boolean keyPressed, float tpf) {
127       if (name.equals("shoot") && !keyPressed) {
128         makeCannonBall();
129       }
130     }
131   };
132 
133   /** Initialize the materials used in this scene. */
initMaterials()134   public void initMaterials() {
135     wall_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
136     TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg");
137     key.setGenerateMips(true);
138     Texture tex = assetManager.loadTexture(key);
139     wall_mat.setTexture("ColorMap", tex);
140 
141     stone_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
142     TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG");
143     key2.setGenerateMips(true);
144     Texture tex2 = assetManager.loadTexture(key2);
145     stone_mat.setTexture("ColorMap", tex2);
146 
147     floor_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
148     TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg");
149     key3.setGenerateMips(true);
150     Texture tex3 = assetManager.loadTexture(key3);
151     tex3.setWrap(WrapMode.Repeat);
152     floor_mat.setTexture("ColorMap", tex3);
153   }
154 
155   /** Make a solid floor and add it to the scene. */
initFloor()156   public void initFloor() {
157     Geometry floor_geo = new Geometry("Floor", floor);
158     floor_geo.setMaterial(floor_mat);
159     floor_geo.setLocalTranslation(0, -0.1f, 0);
160     this.rootNode.attachChild(floor_geo);
161     /* Make the floor physical with mass 0.0f! */
162     floor_phy = new RigidBodyControl(0.0f);
163     floor_geo.addControl(floor_phy);
164     bulletAppState.getPhysicsSpace().add(floor_phy);
165   }
166 
167   /** This loop builds a wall out of individual bricks. */
initWall()168   public void initWall() {
169     float startpt = brickLength / 4;
170     float height = 0;
171     for (int j = 0; j < 15; j++) {
172       for (int i = 0; i < 6; i++) {
173         Vector3f vt =
174          new Vector3f(i * brickLength * 2 + startpt, brickHeight + height, 0);
175         makeBrick(vt);
176       }
177       startpt = -startpt;
178       height += 2 * brickHeight;
179     }
180   }
181 
182   /** This method creates one individual physical brick. */
makeBrick(Vector3f loc)183   public void makeBrick(Vector3f loc) {
184     /** Create a brick geometry and attach to scene graph. */
185     Geometry brick_geo = new Geometry("brick", box);
186     brick_geo.setMaterial(wall_mat);
187     rootNode.attachChild(brick_geo);
188     /** Position the brick geometry  */
189     brick_geo.setLocalTranslation(loc);
190     /** Make brick physical with a mass > 0.0f. */
191     brick_phy = new RigidBodyControl(2f);
192     /** Add physical brick to physics space. */
193     brick_geo.addControl(brick_phy);
194     bulletAppState.getPhysicsSpace().add(brick_phy);
195   }
196 
197   /** This method creates one individual physical cannon ball.
198    * By defaul, the ball is accelerated and flies
199    * from the camera position in the camera direction.*/
makeCannonBall()200    public void makeCannonBall() {
201     /** Create a cannon ball geometry and attach to scene graph. */
202     Geometry ball_geo = new Geometry("cannon ball", sphere);
203     ball_geo.setMaterial(stone_mat);
204     rootNode.attachChild(ball_geo);
205     /** Position the cannon ball  */
206     ball_geo.setLocalTranslation(cam.getLocation());
207     /** Make the ball physcial with a mass > 0.0f */
208     ball_phy = new RigidBodyControl(1f);
209     /** Add physical ball to physics space. */
210     ball_geo.addControl(ball_phy);
211     bulletAppState.getPhysicsSpace().add(ball_phy);
212     /** Accelerate the physcial ball to shoot it. */
213     ball_phy.setLinearVelocity(cam.getDirection().mult(25));
214   }
215 
216   /** A plus sign used as crosshairs to help the player with aiming.*/
initCrossHairs()217   protected void initCrossHairs() {
218     guiNode.detachAllChildren();
219     guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
220     BitmapText ch = new BitmapText(guiFont, false);
221     ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
222     ch.setText("+");        // fake crosshairs :)
223     ch.setLocalTranslation( // center
224       settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2,
225       settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);
226     guiNode.attachChild(ch);
227   }
228 }
229