OSDN Git Service

avoid vector creation in intersectsSphere, some corrections in stress tests for profi...
[mikumikustudio/MikuMikuStudio.git] / src / jmetest / TutorialGuide / HelloIntersection.java
1 /*
2  * Copyright (c) 2003-2005 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 jmetest.TutorialGuide;
34
35 import java.net.URL;
36 import java.util.Random;
37
38 import com.jme.app.SimpleGame;
39 import com.jme.bounding.BoundingSphere;
40 import com.jme.image.Texture;
41 import com.jme.input.KeyInput;
42 import com.jme.input.action.InputActionEvent;
43 import com.jme.input.action.KeyInputAction;
44 import com.jme.math.Vector3f;
45 import com.jme.renderer.ColorRGBA;
46 import com.jme.scene.Controller;
47 import com.jme.scene.Skybox;
48 import com.jme.scene.Text;
49 import com.jme.scene.TriMesh;
50 import com.jme.scene.shape.Sphere;
51 import com.jme.scene.state.MaterialState;
52 import com.jme.scene.state.TextureState;
53 import com.jme.util.TextureManager;
54 import com.jmex.sound.openAL.SoundSystem;
55
56
57 /**
58  * Started Date: Jul 24, 2004 <br>
59  * <br>
60  * 
61  * Demonstrates intersection testing, sound, and making your own controller.
62  * 
63  * @author Jack Lindamood
64  */
65 public class HelloIntersection extends SimpleGame {
66         /** Material for my bullet */
67         MaterialState bulletMaterial;
68
69         /** Target you're trying to hit */
70         Sphere target;
71
72         /** Location of laser sound */
73         URL laserURL;
74
75         /** Location of hit sound */
76         URL hitURL;
77
78         /** Used to move target location on a hit */
79         Random r = new Random();
80
81         /** A sky box for our scene. */
82         Skybox sb;
83
84         /**
85          * The programmable sound that will be in charge of maintaining our sound
86          * effects.
87          */
88         int laserSound;
89
90         int targetSound;
91
92         /** The node where attached sounds will be propagated from */
93         int snode;
94
95         /**
96          * The ID of our laser shooting sound effect. The value is not important. It
97          * should just be unique in our game to this sound.
98          */
99         private int laserEventID = 1;
100
101         private int hitEventID = 2;
102
103         public static void main(String[] args) {
104                 HelloIntersection app = new HelloIntersection();
105                 app.setDialogBehaviour(SimpleGame.ALWAYS_SHOW_PROPS_DIALOG);
106                 app.start();
107         }
108
109         protected void simpleInitGame() {
110                 setupSound();
111
112                 /** Create a + for the middle of the screen */
113                 Text cross = new Text("Crosshairs", "+");
114
115                 // 8 is half the width of a font char
116                 /** Move the + to the middle */
117                 cross.setLocalTranslation(new Vector3f(display.getWidth() / 2f - 8f,
118                                 display.getHeight() / 2f - 8f, 0));
119                 fpsNode.attachChild(cross);
120                 target = new Sphere("my sphere", 15, 15, 1);
121                 target.setModelBound(new BoundingSphere());
122                 target.updateModelBound();
123                 rootNode.attachChild(target);
124
125                 /** Create a skybox to suround our world */
126                 sb = new Skybox("skybox", 200, 200, 200);
127                 URL monkeyLoc = HelloIntersection.class.getClassLoader().getResource(
128                                 "jmetest/data/texture/clouds.png");
129                 TextureState ts = display.getRenderer().createTextureState();
130                 ts.setTexture(TextureManager.loadTexture(monkeyLoc, Texture.MM_LINEAR,
131                                 Texture.FM_LINEAR));
132                 sb.setRenderState(ts);
133
134                 // Attach the skybox to our root node, and force the rootnode to show
135                 // so that the skybox will always show
136                 rootNode.attachChild(sb);
137                 rootNode.setForceView(true);
138
139                 /**
140                  * Set the action called "firebullet", bound to KEY_F, to performAction
141                  * FireBullet
142                  */
143                 input.addKeyboardAction("firebullet", KeyInput.KEY_F, new FireBullet());
144
145                 /** Make bullet material */
146                 bulletMaterial = display.getRenderer().createMaterialState();
147                 bulletMaterial.setEmissive(ColorRGBA.green);
148
149                 /** Make target material */
150                 MaterialState redMaterial = display.getRenderer().createMaterialState();
151                 redMaterial.setDiffuse(ColorRGBA.red);
152                 target.setRenderState(redMaterial);
153         }
154
155         private void setupSound() {
156         /** Set the 'ears' for the sound API */
157                 SoundSystem.init(display.getRenderer().getCamera(), SoundSystem.OUTPUT_DEFAULT);
158                 
159                 snode = SoundSystem.createSoundNode();
160                 /** Create program sound */
161                 targetSound = SoundSystem.create3DSample( getClass().getResource( "/jmetest/data/sound/explosion.wav" ) );
162                 laserSound = SoundSystem.create3DSample( getClass().getResource( "/jmetest/data/sound/laser.ogg" ) );
163         SoundSystem.setSampleMaxAudibleDistance(targetSound, 1000);
164         SoundSystem.setSampleMaxAudibleDistance(laserSound, 1000);
165         // Then we bind the programid we received to our laser event id.
166                 SoundSystem.bindEventToSample(laserSound, laserEventID);
167         SoundSystem.bindEventToSample(targetSound, hitEventID);
168         SoundSystem.addSampleToNode(laserSound, snode);
169         SoundSystem.addSampleToNode(targetSound, snode);
170         }
171
172         class FireBullet extends KeyInputAction {
173                 int numBullets;
174
175                 FireBullet() {
176                         setAllowsRepeats(false);
177                 }
178
179                 public void performAction(InputActionEvent evt) {
180                         System.out.println("BANG");
181                         /** Create bullet */
182                         Sphere bullet = new Sphere("bullet" + numBullets++, 8, 8, .25f);
183                         bullet.setModelBound(new BoundingSphere());
184                         bullet.updateModelBound();
185                         /** Move bullet to the camera location */
186                         bullet.setLocalTranslation(new Vector3f(cam.getLocation()));
187                         bullet.setRenderState(bulletMaterial);
188                         /**
189                          * Update the new world locaion for the bullet before I add a
190                          * controller
191                          */
192                         bullet.updateGeometricState(0, true);
193                         /**
194                          * Add a movement controller to the bullet going in the camera's
195                          * direction
196                          */
197                         bullet.addController(new BulletMover(bullet, new Vector3f(cam
198                                         .getDirection())));
199                         rootNode.attachChild(bullet);
200                         bullet.updateRenderState();
201                         /** Signal our sound to play laser during rendering */
202             Vector3f v=cam.getLocation();
203                         SoundSystem.setSamplePosition(laserSound, v.x, v.y, v.z);
204             SoundSystem.onEvent(snode, laserEventID);
205                 }
206         }
207
208         class BulletMover extends Controller {
209             private static final long serialVersionUID = 1L;
210                 /** Bullet that's moving */
211                 TriMesh bullet;
212
213                 /** Direciton of bullet */
214                 Vector3f direction;
215
216                 /** speed of bullet */
217                 float speed = 10;
218
219                 /** Seconds it will last before going away */
220                 float lifeTime = 5;
221
222                 BulletMover(TriMesh bullet, Vector3f direction) {
223                         this.bullet = bullet;
224                         this.direction = direction;
225                         this.direction.normalizeLocal();
226                 }
227
228                 public void update(float time) {
229                         lifeTime -= time;
230                         /** If life is gone, remove it */
231                         if (lifeTime < 0) {
232                                 rootNode.detachChild(bullet);
233                                 bullet.removeController(this);
234                                 return;
235                         }
236                         /** Move bullet */
237                         Vector3f bulletPos = bullet.getLocalTranslation();
238                         bulletPos.addLocal(direction.mult(time * speed));
239                         bullet.setLocalTranslation(bulletPos);
240                         /** Does the bullet intersect with target? */
241                         if (bullet.getWorldBound().intersects(target.getWorldBound())) {
242                                 System.out.println("OWCH!!!");
243                 Vector3f v=target.getWorldTranslation();
244                 SoundSystem.setSamplePosition(targetSound, v.x, v.y, v.z);
245                                 
246                                 target.setLocalTranslation(new Vector3f(r.nextFloat() * 10, r
247                                                 .nextFloat() * 10, r.nextFloat() * 10));
248                                 lifeTime = 0;
249                                 SoundSystem.onEvent(snode, hitEventID);
250                                 
251                         }
252                 }
253         }
254
255         /**
256          * Called every frame for rendering
257          */
258         protected void simpleRender() {
259                 // Give control to the sound in case sound changes are needed.
260                 SoundSystem.draw();
261         }
262
263         /**
264          * Called every frame for updating
265          */
266         protected void simpleUpdate() {
267                 // Let the programmable sound update itself.
268         SoundSystem.update(tpf);
269         }
270 }