|
1 | 1 | /*
|
2 |
| - * Copyright (c) 2009-2012 jMonkeyEngine |
| 2 | + * Copyright (c) 2009-2025 jMonkeyEngine |
3 | 3 | * All rights reserved.
|
4 | 4 | *
|
5 | 5 | * Redistribution and use in source and binary forms, with or without
|
|
29 | 29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
30 | 30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31 | 31 | */
|
32 |
| - |
33 | 32 | package jme3test.export;
|
34 | 33 |
|
35 | 34 | import com.jme3.anim.AnimComposer;
|
| 35 | +import com.jme3.anim.SkinningControl; |
36 | 36 | import com.jme3.app.SimpleApplication;
|
37 | 37 | import com.jme3.export.binary.BinaryExporter;
|
38 |
| -import com.jme3.export.binary.BinaryImporter; |
| 38 | +import com.jme3.font.BitmapText; |
| 39 | +import com.jme3.light.AmbientLight; |
39 | 40 | import com.jme3.light.DirectionalLight;
|
| 41 | +import com.jme3.material.MatParamOverride; |
40 | 42 | import com.jme3.math.ColorRGBA;
|
41 | 43 | import com.jme3.math.Vector3f;
|
42 |
| -import com.jme3.scene.Node; |
43 | 44 | import com.jme3.scene.Spatial;
|
44 | 45 |
|
45 |
| -import java.io.*; |
46 |
| - |
| 46 | +/** |
| 47 | + * This class is a jMonkeyEngine 3 (jME3) test application designed to verify |
| 48 | + * the import, export, and runtime behavior of 3D models, particularly those |
| 49 | + * in or compatible with the Ogre3D format (.mesh.xml). |
| 50 | + * It loads an Ogre model, saves and reloads it using jME3's binary exporter, |
| 51 | + * plays an animation, and displays debugging information about its skinning |
| 52 | + * and material parameters. |
| 53 | + * |
| 54 | + * @author capdevon |
| 55 | + */ |
47 | 56 | public class TestOgreConvert extends SimpleApplication {
|
48 | 57 |
|
49 |
| - public static void main(String[] args){ |
| 58 | + public static void main(String[] args) { |
50 | 59 | TestOgreConvert app = new TestOgreConvert();
|
| 60 | + app.setPauseOnLostFocus(false); |
51 | 61 | app.start();
|
52 | 62 | }
|
53 | 63 |
|
| 64 | + private final StringBuilder sb = new StringBuilder(); |
| 65 | + private int frameCount = 0; |
| 66 | + private BitmapText bmp; |
| 67 | + private Spatial spCopy; |
| 68 | + private SkinningControl skinningControl; |
| 69 | + private AnimComposer animComposer; |
| 70 | + |
54 | 71 | @Override
|
55 | 72 | public void simpleInitApp() {
|
56 |
| - Spatial ogreModel = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); |
| 73 | + configureCamera(); |
| 74 | + setupLights(); |
| 75 | + |
| 76 | + bmp = createLabelText(10, 20, "<placeholder>"); |
| 77 | + |
| 78 | + // Load the Ogre model (Oto.mesh.xml) from the assets |
| 79 | + Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); |
| 80 | + |
| 81 | + // Save the loaded model to jME3's binary format and then reload it. |
| 82 | + // This tests the binary serialization/deserialization process. |
| 83 | + spCopy = BinaryExporter.saveAndLoad(assetManager, model); |
| 84 | + spCopy.setName("Oto-Copy"); |
| 85 | + rootNode.attachChild(spCopy); |
| 86 | + |
| 87 | + animComposer = spCopy.getControl(AnimComposer.class); |
| 88 | + animComposer.setCurrentAction("Walk"); |
| 89 | + |
| 90 | + // Get the SkinningControl from the model to inspect skinning properties |
| 91 | + skinningControl = spCopy.getControl(SkinningControl.class); |
| 92 | + } |
| 93 | + |
| 94 | + private void setupLights() { |
| 95 | + AmbientLight al = new AmbientLight(); |
| 96 | + rootNode.addLight(al); |
57 | 97 |
|
58 | 98 | DirectionalLight dl = new DirectionalLight();
|
59 |
| - dl.setColor(ColorRGBA.White); |
60 |
| - dl.setDirection(new Vector3f(0,-1,-1).normalizeLocal()); |
| 99 | + dl.setDirection(new Vector3f(0, -1, -1).normalizeLocal()); |
61 | 100 | rootNode.addLight(dl);
|
| 101 | + } |
62 | 102 |
|
63 |
| - try { |
64 |
| - ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
65 |
| - BinaryExporter exp = new BinaryExporter(); |
66 |
| - exp.save(ogreModel, baos); |
| 103 | + private void configureCamera() { |
| 104 | + flyCam.setDragToRotate(true); |
| 105 | + flyCam.setMoveSpeed(15f); |
67 | 106 |
|
68 |
| - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); |
69 |
| - BinaryImporter imp = new BinaryImporter(); |
70 |
| - imp.setAssetManager(assetManager); |
71 |
| - Node ogreModelReloaded = (Node) imp.load(bais, null, null); |
| 107 | + cam.setLocation(new Vector3f(0, 0, 20)); |
| 108 | + } |
72 | 109 |
|
73 |
| - AnimComposer composer = ogreModelReloaded.getControl(AnimComposer.class); |
74 |
| - composer.setCurrentAction("Walk"); |
| 110 | + @Override |
| 111 | + public void simpleUpdate(float tpf) { |
| 112 | + frameCount++; |
| 113 | + if (frameCount == 10) { |
| 114 | + frameCount = 0; |
75 | 115 |
|
76 |
| - rootNode.attachChild(ogreModelReloaded); |
77 |
| - } catch (IOException ex){ |
78 |
| - ex.printStackTrace(); |
| 116 | + sb.append("HW Skinning Preferred: ").append(skinningControl.isHardwareSkinningPreferred()).append("\n"); |
| 117 | + sb.append("HW Skinning Enabled: ").append(skinningControl.isHardwareSkinningUsed()).append("\n"); |
| 118 | + sb.append("Mesh Targets: ").append(skinningControl.getTargets().length).append("\n"); |
| 119 | + sb.append("Anim Clips: ").append(animComposer.getAnimClips().size()).append("\n"); |
| 120 | + |
| 121 | + for (MatParamOverride mpo : spCopy.getLocalMatParamOverrides()) { |
| 122 | + sb.append(mpo.getVarType()).append(" "); |
| 123 | + sb.append(mpo.getName()).append(": "); |
| 124 | + sb.append(mpo.getValue()).append("\n"); |
| 125 | + } |
| 126 | + |
| 127 | + bmp.setText(sb.toString()); |
| 128 | + sb.setLength(0); |
79 | 129 | }
|
80 | 130 | }
|
| 131 | + |
| 132 | + private BitmapText createLabelText(int x, int y, String text) { |
| 133 | + BitmapText bmp = new BitmapText(guiFont); |
| 134 | + bmp.setText(text); |
| 135 | + bmp.setLocalTranslation(x, settings.getHeight() - y, 0); |
| 136 | + bmp.setColor(ColorRGBA.Red); |
| 137 | + guiNode.attachChild(bmp); |
| 138 | + return bmp; |
| 139 | + } |
81 | 140 | }
|
0 commit comments