OSDN Git Service

avoid vector creation in intersectsSphere, some corrections in stress tests for profi...
[mikumikustudio/MikuMikuStudio.git] / src / jmetest / TutorialGuide / HelloLOD.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.io.ByteArrayInputStream;
36 import java.io.ByteArrayOutputStream;
37 import java.io.IOException;
38 import java.net.URL;
39
40 import com.jme.app.SimpleGame;
41 import com.jme.bounding.BoundingSphere;
42 import com.jme.curve.BezierCurve;
43 import com.jme.curve.CurveController;
44 import com.jme.input.KeyInput;
45 import com.jme.input.action.KeyExitAction;
46 import com.jme.math.Matrix3f;
47 import com.jme.math.Vector3f;
48 import com.jme.scene.*;
49 import com.jme.scene.lod.AreaClodMesh;
50 import com.jme.scene.state.RenderState;
51 import com.jme.util.LoggingSystem;
52 import com.jmex.model.XMLparser.JmeBinaryReader;
53 import com.jmex.model.XMLparser.Converters.FormatConverter;
54 import com.jmex.model.XMLparser.Converters.ObjToJme;
55
56 /**
57  * Started Date: Aug 16, 2004<br><br>
58  *
59  * This program teaches Complex Level of Detail mesh objects.  To use this program, move
60  * the camera backwards and watch the model disappear.
61  * 
62  * @author Jack Lindamood
63  */
64 public class HelloLOD extends SimpleGame {
65
66     CameraNode cn;
67
68     public static void main(String[] args) {
69         HelloLOD app = new HelloLOD();
70         app.setDialogBehaviour(SimpleGame.ALWAYS_SHOW_PROPS_DIALOG);
71         app.start();
72     }
73
74     protected void simpleInitGame() {
75         // Point to a URL of my model
76         URL model=HelloModelLoading.class.getClassLoader().getResource("jmetest/data/model/maggie.obj");
77
78         // Create something to convert .obj format to .jme
79         FormatConverter converter=new ObjToJme();
80         // Point the converter to where it will find the .mtl file from
81         converter.setProperty("mtllib",model);
82
83         // This byte array will hold my .jme file
84         ByteArrayOutputStream BO=new ByteArrayOutputStream();
85         // This will read the .jme format and convert it into a scene graph
86         JmeBinaryReader jbr=new JmeBinaryReader();
87
88         Node meshParent=null;
89         try {
90             // Use the format converter to convert .obj to .jme
91             converter.convert(model.openStream(), BO);
92
93             // Load the binary .jme format into a scene graph
94             Node maggie=jbr.loadBinaryFormat(new ByteArrayInputStream(BO.toByteArray()));
95             meshParent=(Node) maggie.getChild(0);
96
97         } catch (IOException e) {   // Just in case anything happens
98             System.out.println("Damn exceptions!" + e);
99             e.printStackTrace();
100             System.exit(0);
101         }
102
103         // Create a clod duplicate of meshParent.
104         Node clodNode=getClodNodeFromParent(meshParent);
105
106         // Attach the clod mesh at the origin.
107         clodNode.setLocalScale(.1f);
108         rootNode.attachChild(clodNode);
109
110         // Attach the original at -15,0,0
111         meshParent.setLocalScale(.1f);
112         meshParent.setLocalTranslation(new Vector3f(-15,0,0));
113
114         rootNode.attachChild(meshParent);
115
116         // Clear the keyboard commands that can move the camera.
117         input.clearKeyboardActions();
118         input.clearMouseActions();
119         // Insert a keyboard command that can exit the application.
120         input.addKeyboardAction("exit",KeyInput.KEY_ESCAPE,new KeyExitAction(this));
121
122         // The path the camera will take.
123         Vector3f[]cameraPoints=new Vector3f[]{
124             new Vector3f(0,5,20),
125             new Vector3f(0,20,90),
126             new Vector3f(0,30,200),
127             new Vector3f(0,100,300),
128             new Vector3f(0,150,400),
129         };
130         // Create a path for the camera.
131         BezierCurve bc=new BezierCurve("camera path",cameraPoints);
132
133         // Create a camera node to move along that path.
134         cn=new CameraNode("camera node",cam);
135
136         // Create a curve controller to move the CameraNode along the path
137         CurveController cc=new CurveController(bc,cn);
138
139         // Cycle the animation.
140         cc.setRepeatType(Controller.RT_CYCLE);
141
142         // Slow down the curve controller a bit
143         cc.setSpeed(.25f);
144
145         // Add the controller to the node.
146         cn.addController(cc);
147
148         // Attach the node to rootNode
149         rootNode.attachChild(cn);
150     }
151
152     private Node getClodNodeFromParent(Node meshParent) {
153         // Create a node to hold my cLOD mesh objects
154         Node clodNode=new Node("Clod node");
155         // For each mesh in maggie
156         for (int i=0;i<meshParent.getQuantity();i++){
157             final Spatial child = meshParent.getChild(i);
158             if ( child instanceof Node )
159             {
160                 clodNode.attachChild( getClodNodeFromParent( (Node) child ) );
161             }
162             else if ( child instanceof TriMesh )
163             {
164                 // Create an AreaClodMesh for that mesh.  Let it compute records automatically
165                 AreaClodMesh acm=new AreaClodMesh("part"+i,(TriMesh) child,null);
166                 acm.setModelBound(new BoundingSphere());
167                 acm.updateModelBound();
168
169                 // Allow 1/2 of a triangle in every pixel on the screen in the bounds.
170                 acm.setTrisPerPixel(.5f);
171
172                 // Force a move of 2 units before updating the mesh geometry
173                 acm.setDistanceTolerance(2);
174
175                 // Give the clodMesh node the material state that the original had.
176                 acm.setRenderState(child.getRenderStateList()[RenderState.RS_MATERIAL]);
177
178                 // Attach clod node.
179                 clodNode.attachChild(acm);
180             }
181             else
182             {
183                 LoggingSystem.getLogger().warning( "Unhandled Spatial type: " + child.getClass() );
184             }
185         }
186         return clodNode;
187     }
188
189     Vector3f up=new Vector3f(0,1,0);
190     Vector3f left=new Vector3f(1,0,0);
191
192     private static Vector3f tempVa=new Vector3f();
193     private static Vector3f tempVb=new Vector3f();
194     private static Vector3f tempVc=new Vector3f();
195     private static Vector3f tempVd=new Vector3f();
196     private static Matrix3f tempMa=new Matrix3f();
197
198     protected void simpleUpdate(){
199         // Get the center of root's bound.
200         Vector3f objectCenter=rootNode.getWorldBound().getCenter(tempVa);
201
202         // My direction is the place I want to look minus the location of the camera.
203         Vector3f lookAtObject=tempVb.set(objectCenter).subtractLocal(cam.getLocation()).normalizeLocal();
204
205         // Left vector
206         tempMa.setColumn(0,up.cross(lookAtObject,tempVc).normalizeLocal());
207         // Up vector
208         tempMa.setColumn(1,left.cross(lookAtObject,tempVd).normalizeLocal());
209         // Direction vector
210         tempMa.setColumn(2,lookAtObject);
211
212         cn.setLocalRotation(tempMa);
213     }
214 }