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 package jme3test.bullet; 33 34 import com.jme3.app.SimpleApplication; 35 import com.jme3.asset.TextureKey; 36 import com.jme3.bullet.BulletAppState; 37 import com.jme3.bullet.PhysicsSpace; 38 import com.jme3.bullet.collision.shapes.BoxCollisionShape; 39 import com.jme3.bullet.collision.shapes.SphereCollisionShape; 40 import com.jme3.bullet.control.RigidBodyControl; 41 import com.jme3.font.BitmapText; 42 import com.jme3.input.KeyInput; 43 import com.jme3.input.MouseInput; 44 import com.jme3.input.controls.ActionListener; 45 import com.jme3.input.controls.KeyTrigger; 46 import com.jme3.input.controls.MouseButtonTrigger; 47 import com.jme3.material.Material; 48 import com.jme3.math.Vector2f; 49 import com.jme3.math.Vector3f; 50 import com.jme3.renderer.queue.RenderQueue.ShadowMode; 51 import com.jme3.scene.Geometry; 52 import com.jme3.scene.shape.Box; 53 import com.jme3.scene.shape.Sphere; 54 import com.jme3.scene.shape.Sphere.TextureMode; 55 import com.jme3.shadow.BasicShadowRenderer; 56 import com.jme3.texture.Texture; 57 import com.jme3.texture.Texture.WrapMode; 58 59 /** 60 * 61 * @author double1984 62 */ 63 public class TestBrickWall extends SimpleApplication { 64 65 static float bLength = 0.48f; 66 static float bWidth = 0.24f; 67 static float bHeight = 0.12f; 68 Material mat; 69 Material mat2; 70 Material mat3; 71 BasicShadowRenderer bsr; 72 private static Sphere bullet; 73 private static Box brick; 74 private static SphereCollisionShape bulletCollisionShape; 75 76 private BulletAppState bulletAppState; 77 main(String args[])78 public static void main(String args[]) { 79 TestBrickWall f = new TestBrickWall(); 80 f.start(); 81 } 82 83 @Override simpleInitApp()84 public void simpleInitApp() { 85 86 bulletAppState = new BulletAppState(); 87 bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); 88 stateManager.attach(bulletAppState); 89 90 bullet = new Sphere(32, 32, 0.4f, true, false); 91 bullet.setTextureMode(TextureMode.Projected); 92 bulletCollisionShape = new SphereCollisionShape(0.4f); 93 brick = new Box(Vector3f.ZERO, bLength, bHeight, bWidth); 94 brick.scaleTextureCoordinates(new Vector2f(1f, .5f)); 95 96 initMaterial(); 97 initWall(); 98 initFloor(); 99 initCrossHairs(); 100 this.cam.setLocation(new Vector3f(0, 6f, 6f)); 101 cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0)); 102 cam.setFrustumFar(15); 103 inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); 104 inputManager.addListener(actionListener, "shoot"); 105 inputManager.addMapping("gc", new KeyTrigger(KeyInput.KEY_X)); 106 inputManager.addListener(actionListener, "gc"); 107 108 rootNode.setShadowMode(ShadowMode.Off); 109 bsr = new BasicShadowRenderer(assetManager, 256); 110 bsr.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); 111 viewPort.addProcessor(bsr); 112 } 113 getPhysicsSpace()114 private PhysicsSpace getPhysicsSpace() { 115 return bulletAppState.getPhysicsSpace(); 116 } 117 private ActionListener actionListener = new ActionListener() { 118 119 public void onAction(String name, boolean keyPressed, float tpf) { 120 if (name.equals("shoot") && !keyPressed) { 121 Geometry bulletg = new Geometry("bullet", bullet); 122 bulletg.setMaterial(mat2); 123 bulletg.setShadowMode(ShadowMode.CastAndReceive); 124 bulletg.setLocalTranslation(cam.getLocation()); 125 126 SphereCollisionShape bulletCollisionShape = new SphereCollisionShape(0.4f); 127 RigidBodyControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1); 128 // RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, 1); 129 bulletNode.setLinearVelocity(cam.getDirection().mult(25)); 130 bulletg.addControl(bulletNode); 131 rootNode.attachChild(bulletg); 132 getPhysicsSpace().add(bulletNode); 133 } 134 if (name.equals("gc") && !keyPressed) { 135 System.gc(); 136 } 137 } 138 }; 139 initWall()140 public void initWall() { 141 float startpt = bLength / 4; 142 float height = 0; 143 for (int j = 0; j < 15; j++) { 144 for (int i = 0; i < 4; i++) { 145 Vector3f vt = new Vector3f(i * bLength * 2 + startpt, bHeight + height, 0); 146 addBrick(vt); 147 } 148 startpt = -startpt; 149 height += 2 * bHeight; 150 } 151 } 152 initFloor()153 public void initFloor() { 154 Box floorBox = new Box(Vector3f.ZERO, 10f, 0.1f, 5f); 155 floorBox.scaleTextureCoordinates(new Vector2f(3, 6)); 156 157 Geometry floor = new Geometry("floor", floorBox); 158 floor.setMaterial(mat3); 159 floor.setShadowMode(ShadowMode.Receive); 160 floor.setLocalTranslation(0, -0.1f, 0); 161 floor.addControl(new RigidBodyControl(new BoxCollisionShape(new Vector3f(10f, 0.1f, 5f)), 0)); 162 this.rootNode.attachChild(floor); 163 this.getPhysicsSpace().add(floor); 164 } 165 initMaterial()166 public void initMaterial() { 167 mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); 168 TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg"); 169 key.setGenerateMips(true); 170 Texture tex = assetManager.loadTexture(key); 171 mat.setTexture("ColorMap", tex); 172 173 mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); 174 TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG"); 175 key2.setGenerateMips(true); 176 Texture tex2 = assetManager.loadTexture(key2); 177 mat2.setTexture("ColorMap", tex2); 178 179 mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); 180 TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg"); 181 key3.setGenerateMips(true); 182 Texture tex3 = assetManager.loadTexture(key3); 183 tex3.setWrap(WrapMode.Repeat); 184 mat3.setTexture("ColorMap", tex3); 185 } 186 addBrick(Vector3f ori)187 public void addBrick(Vector3f ori) { 188 189 Geometry reBoxg = new Geometry("brick", brick); 190 reBoxg.setMaterial(mat); 191 reBoxg.setLocalTranslation(ori); 192 //for geometry with sphere mesh the physics system automatically uses a sphere collision shape 193 reBoxg.addControl(new RigidBodyControl(1.5f)); 194 reBoxg.setShadowMode(ShadowMode.CastAndReceive); 195 reBoxg.getControl(RigidBodyControl.class).setFriction(0.6f); 196 this.rootNode.attachChild(reBoxg); 197 this.getPhysicsSpace().add(reBoxg); 198 } 199 initCrossHairs()200 protected void initCrossHairs() { 201 guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); 202 BitmapText ch = new BitmapText(guiFont, false); 203 ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); 204 ch.setText("+"); // crosshairs 205 ch.setLocalTranslation( // center 206 settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2, 207 settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); 208 guiNode.attachChild(ch); 209 } 210 } 211