Ver Fonte

Merge branch 'MeFisto94-wip/issue1290'

Stephen Gold há 3 anos atrás
pai
commit
4dfeeb14f2

+ 6 - 1
jme3-core/build.gradle

@@ -10,11 +10,16 @@ sourceSets {
         java {
             srcDir 'src/test/java'
         }
+
+        System.setProperty "java.awt.headless", "true"
     }
 }
 
 dependencies {
     testImplementation project(':jme3-testdata')
+    testImplementation project(':jme3-testdata')
+    testImplementation project(':jme3-desktop')
+    testRuntime project(':jme3-plugins')
 }
 
 task updateVersionPropertiesFile {
@@ -40,4 +45,4 @@ task updateVersionPropertiesFile {
     }
 }
 
-processResources.dependsOn updateVersionPropertiesFile
+processResources.dependsOn updateVersionPropertiesFile

+ 68 - 0
jme3-core/src/test/java/com/jme3/asset/TestLocators.java

@@ -0,0 +1,68 @@
+package com.jme3.asset;
+
+import com.jme3.asset.plugins.ClasspathLocator;
+import com.jme3.asset.plugins.HttpZipLocator;
+import com.jme3.asset.plugins.UrlLocator;
+import com.jme3.asset.plugins.ZipLocator;
+import com.jme3.audio.plugins.WAVLoader;
+import com.jme3.system.JmeSystem;
+import com.jme3.texture.plugins.AWTLoader;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestLocators {
+
+    @Test
+    public void testAbsoluteLocators() {
+        AssetManager am = JmeSystem.newAssetManager(TestLocators.class.getResource("/com/jme3/asset/Desktop.cfg"));
+        am.registerLocator("/",  ClasspathLocator.class);
+        am.registerLoader(WAVLoader.class, "wav");
+        am.registerLoader(AWTLoader.class, "jpg");
+
+        Assert.assertNotNull(am.loadAudio("Sound/Effects/Gun.wav"));
+        Assert.assertNotNull(am.loadTexture("Textures/Terrain/Pond/Pond.jpg"));
+    }
+
+    /**
+     * Demonstrates loading a file from a custom {@link AssetLoader}
+     */
+    @Test
+    public void testCustomLoader() {
+        AssetManager am = new DesktopAssetManager(true);
+        am.registerLocator("/", ClasspathLocator.class);
+        am.registerLoader(TextLoader.class, "fnt");
+        String result = (String)am.loadAsset("Interface/Fonts/Console.fnt");
+        Assert.assertTrue(result.startsWith("info face=\"Lucida Console\" size=11 bold=0 italic=0 charset=\"\" unicode=1" +
+                " stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0"));
+    }
+
+    @Test
+    public void testManyLocators() {
+        AssetManager am = new DesktopAssetManager(true);
+        am.registerLocator(
+                "https://github.com/jMonkeyEngine/wiki/raw/master/docs/modules/tutorials/assets/images/beginner/",
+                UrlLocator.class);
+
+        am.registerLocator("../jme3-examples/town.zip", ZipLocator.class);
+        am.registerLocator(
+                "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/wildhouse.zip",
+                HttpZipLocator.class);
+        am.registerLocator("/", ClasspathLocator.class);
+
+        // Try loading from jme3-core resources using the ClasspathLocator.
+        Assert.assertNotNull("Failed to load from classpath",
+                am.locateAsset(new AssetKey<>("Interface/Fonts/Default.fnt")));
+
+        // Try loading from the "town.zip" file using the ZipLocator.
+        Assert.assertNotNull("Failed to load from town.zip file",
+                am.locateAsset(new ModelKey("casaamarela.jpg")));
+
+        // Try loading from the Google Code Archive website using the HttpZipLocator.
+        Assert.assertNotNull("Failed to load from wildhouse.zip on googleapis.com",
+                am.locateAsset(new ModelKey("glasstile2.png")));
+
+        // Try loading from the GitHub website using the UrlLocator.
+        Assert.assertNotNull("Failed to load from HTTP",
+                am.locateAsset(new TextureKey("beginner-physics.png")));
+    }
+}

+ 23 - 26
jme3-examples/src/main/java/jme3test/asset/TextLoader.java → jme3-core/src/test/java/com/jme3/asset/TextLoader.java

@@ -1,26 +1,23 @@
-package jme3test.asset;
-
-import com.jme3.asset.AssetInfo;
-import com.jme3.asset.AssetLoader;
-import java.io.IOException;
-import java.util.Scanner;
-
-/**
- * An example implementation of {@link AssetLoader} to load text
- * files as strings.
- */
-public class TextLoader implements AssetLoader {
-    @Override
-    public Object load(AssetInfo assetInfo) throws IOException {
-        Scanner scan = new Scanner(assetInfo.openStream());
-        StringBuilder sb = new StringBuilder();
-        try {
-            while (scan.hasNextLine()) {
-                sb.append(scan.nextLine()).append('\n');
-            }
-        } finally {
-            scan.close();
-        }
-        return sb.toString();
-    }
-}
+package com.jme3.asset;
+
+import java.util.Scanner;
+
+/**
+ * An example implementation of {@link AssetLoader} to load text
+ * files as strings.
+ */
+public class TextLoader implements AssetLoader {
+    @Override
+    public Object load(AssetInfo assetInfo) {
+        Scanner scan = new Scanner(assetInfo.openStream());
+        StringBuilder sb = new StringBuilder();
+        try {
+            while (scan.hasNextLine()) {
+                sb.append(scan.nextLine()).append('\n');
+            }
+        } finally {
+            scan.close();
+        }
+        return sb.toString();
+    }
+}

+ 133 - 0
jme3-core/src/test/java/com/jme3/test/PreventCoreIssueRegressions.java

@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2019-2021 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.test;
+
+import com.jme3.anim.AnimComposer;
+import com.jme3.anim.Joint;
+import com.jme3.anim.SkinningControl;
+import com.jme3.app.LegacyApplication;
+import com.jme3.app.SimpleApplication;
+import com.jme3.app.state.AppState;
+import com.jme3.app.state.ScreenshotAppState;
+import com.jme3.asset.AssetManager;
+import com.jme3.asset.DesktopAssetManager;
+import com.jme3.input.InputManager;
+import com.jme3.input.dummy.DummyKeyInput;
+import com.jme3.input.dummy.DummyMouseInput;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.Camera;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.scene.Node;
+import com.jme3.system.JmeSystem;
+import com.jme3.system.NullRenderer;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.lang.reflect.Field;
+import java.util.List;
+
+/**
+ * The Test Suite to prevent regressions from previously fixed Core issues
+ * @author Stephen Gold &lt;[email protected]&gt;
+ */
+public class PreventCoreIssueRegressions {
+
+    /**
+     * Test case for JME issue #1421: ScreenshotAppState never cleans up.
+     */
+    @Test
+    public void testIssue1421() throws NoSuchFieldException, IllegalAccessException {
+        ScreenshotAppState screenshotAppState = new ScreenshotAppState("./", "screen_shot");
+
+        SimpleApplication app = new SimpleApplication(new AppState[]{}) {
+            // Dummy application because SimpleApp is abstract
+            @Override
+            public void simpleInitApp() { }
+        };
+
+        app.setAssetManager(new DesktopAssetManager(true));
+        Field f1 = LegacyApplication.class.getDeclaredField("inputManager");
+        f1.setAccessible(true);
+        f1.set(app, new InputManager(new DummyMouseInput(), new DummyKeyInput(), null, null));
+
+        Field f2 = LegacyApplication.class.getDeclaredField("renderManager");
+        f2.setAccessible(true);
+        f2.set(app, new RenderManager(new NullRenderer()));
+
+        app.getRenderManager().createPostView("null", new Camera(1, 1));
+
+        Assert.assertTrue(app.getStateManager().attach(screenshotAppState));
+        app.getStateManager().update(0f); // Causes SAS#initialize to be called
+
+        // Confirm that the SceneProcessor is attached.
+        List<ViewPort> vps = app.getRenderManager().getPostViews();
+        Assert.assertEquals(1, vps.size());
+        Assert.assertEquals(1, vps.get(0).getProcessors().size());
+        Assert.assertTrue(app.getInputManager().hasMapping("ScreenShot")); // Confirm that KEY_SYSRQ is mapped.
+        Assert.assertTrue(app.getStateManager().detach(screenshotAppState));
+
+        app.getStateManager().update(0f); // Causes SAS#cleanup to be called
+
+        // Check whether the SceneProcessor is still attached.
+        Assert.assertEquals(0, vps.get(0).getProcessors().size());
+        Assert.assertFalse(app.getInputManager().hasMapping("ScreenShot")); // Confirm that KEY_SYSRQ is unmapped.
+    }
+
+    /**
+     * Test case for JME issue #1138: Elephant's legUp animation sets Joint translation to NaN.
+     */
+    @Test
+    public void testIssue1138() {
+        AssetManager am = JmeSystem.newAssetManager(PreventCoreIssueRegressions.class.getResource("/com/jme3/asset/Desktop.cfg"));
+        Node cgModel = (Node)am.loadModel("Models/Elephant/Elephant.mesh.xml");
+        cgModel.rotate(0f, -1f, 0f);
+        cgModel.scale(0.04f);
+
+        AnimComposer composer = cgModel.getControl(AnimComposer.class);
+        composer.setCurrentAction("legUp");
+        SkinningControl sControl = cgModel.getControl(SkinningControl.class);
+
+        for (Joint joint : sControl.getArmature().getJointList()) {
+            Assert.assertTrue("Invalid translation for joint " + joint.getName(),
+                    Vector3f.isValidVector(joint.getLocalTranslation()));
+        }
+
+        cgModel.updateLogicalState(1.0f);
+        cgModel.updateGeometricState();
+
+        for (Joint joint : sControl.getArmature().getJointList()) {
+            Assert.assertTrue("Invalid translation for joint " + joint.getName(),
+                    Vector3f.isValidVector(joint.getLocalTranslation()));
+        }
+    }
+}

+ 0 - 85
jme3-examples/src/main/java/jme3test/animation/TestIssue1138.java

@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2019-2021 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package jme3test.animation;
-
-import com.jme3.anim.AnimComposer;
-import com.jme3.anim.Joint;
-import com.jme3.anim.SkinningControl;
-import com.jme3.app.SimpleApplication;
-import com.jme3.light.AmbientLight;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Node;
-
-/**
- * Test case for JME issue #1138: Elephant's legUp animation sets Joint
- * translation to NaN.
- * <p>
- * If successful, the animation cycle will complete without throwing an
- * IllegalStateException.
- *
- * @author Stephen Gold
- */
-public class TestIssue1138 extends SimpleApplication {
-
-    private SkinningControl sControl;
-
-    public static void main(String... argv) {
-        new TestIssue1138().start();
-    }
-
-    @Override
-    public void simpleInitApp() {
-        Node cgModel = (Node) assetManager.loadModel(
-                "Models/Elephant/Elephant.mesh.xml");
-        rootNode.attachChild(cgModel);
-        cgModel.rotate(0f, -1f, 0f);
-        cgModel.scale(0.04f);
-
-        AnimComposer composer = cgModel.getControl(AnimComposer.class);
-        composer.setCurrentAction("legUp");
-        sControl = cgModel.getControl(SkinningControl.class);
-
-        AmbientLight light = new AmbientLight();
-        rootNode.addLight(light);
-    }
-
-    @Override
-    public void simpleUpdate(float tpf) {
-        for (Joint joint : sControl.getArmature().getJointList()) {
-            Vector3f translation = joint.getLocalTranslation();
-            if (!Vector3f.isValidVector(translation)) {
-                String msg = "Invalid translation for joint " + joint.getName();
-                throw new IllegalStateException(msg);
-            }
-        }
-    }
-}

+ 0 - 102
jme3-examples/src/main/java/jme3test/app/state/TestIssue1421.java

@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2020-2021 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package jme3test.app.state;
-
-import com.jme3.app.SimpleApplication;
-import com.jme3.app.state.ScreenshotAppState;
-import com.jme3.post.SceneProcessor;
-import com.jme3.renderer.ViewPort;
-import java.util.List;
-
-/**
- * Test case for JME issue #1421: ScreenshotAppState never cleans up.
- * <p>
- * If successful, the application will complete without throwing an Exception.
- *
- * @author Stephen Gold
- */
-public class TestIssue1421 extends SimpleApplication {
-
-    private int updateCount = 0;
-    private ScreenshotAppState screenshotAppState;
-
-    public static void main(String[] args) {
-        TestIssue1421 app = new TestIssue1421();
-        app.start();
-    }
-
-    @Override
-    public void simpleInitApp() {
-        // enable screenshots
-        screenshotAppState = new ScreenshotAppState("./", "screen_shot");
-        boolean success = stateManager.attach(screenshotAppState);
-        assert success;
-    }
-
-    @Override
-    public void simpleUpdate(float tpf) {
-        ++updateCount;
-        if (updateCount == 10) { // after attached
-            // Confirm that the SceneProcessor is attached.
-            List<ViewPort> vps = renderManager.getPostViews();
-            assert vps.size() == 1 : vps.size();
-            ViewPort lastViewPort = vps.get(0);
-            List<SceneProcessor> processorList = lastViewPort.getProcessors();
-            int numProcessors = processorList.size();
-            assert numProcessors == 1 : numProcessors;
-
-            // Confirm that KEY_SYSRQ is mapped.
-            assert inputManager.hasMapping("ScreenShot");
-
-            // disable screenshots
-            boolean success = stateManager.detach(screenshotAppState);
-            assert success;
-
-        } else if (updateCount == 20) { // after detached
-            // Check whether the SceneProcessor is still attached.
-            List<ViewPort> vps = renderManager.getPostViews();
-            ViewPort lastViewPort = vps.get(0);
-            List<SceneProcessor> processorList = lastViewPort.getProcessors();
-            int numProcessors = processorList.size();
-            if (numProcessors != 0) {
-                throw new IllegalStateException(
-                        "SceneProcessor is still attached.");
-            }
-
-            // Check whether KEY_SYSRQ is still mapped.
-            if (inputManager.hasMapping("ScreenShot")) {
-                throw new IllegalStateException("KEY_SYSRQ is still mapped.");
-            }
-            stop();
-        }
-    }
-}

+ 0 - 71
jme3-examples/src/main/java/jme3test/asset/TestAbsoluteLocators.java

@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2009-2012 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package jme3test.asset;
-
-import com.jme3.asset.AssetManager;
-import com.jme3.asset.plugins.ClasspathLocator;
-import com.jme3.audio.AudioData;
-import com.jme3.audio.plugins.WAVLoader;
-import com.jme3.system.JmeSystem;
-import com.jme3.texture.Texture;
-import com.jme3.texture.plugins.AWTLoader;
-
-public class TestAbsoluteLocators {
-    public static void main(String[] args){
-        AssetManager am = JmeSystem.newAssetManager();
-
-        am.registerLoader(AWTLoader.class, "jpg");
-        am.registerLoader(WAVLoader.class, "wav");
-
-        // register absolute locator
-        am.registerLocator("/",  ClasspathLocator.class);
-
-        // find a sound
-        AudioData audio = am.loadAudio("Sound/Effects/Gun.wav");
-
-        // find a texture
-        Texture tex = am.loadTexture("Textures/Terrain/Pond/Pond.jpg");
-
-        if (audio == null)
-            throw new RuntimeException("Cannot find audio!");
-        else
-            System.out.println("Audio loaded from Sounds/Effects/Gun.wav");
-
-        if (tex == null)
-            throw new RuntimeException("Cannot find texture!");
-        else
-            System.out.println("Texture loaded from Textures/Terrain/Pond/Pond.jpg");
-
-        System.out.println("Success!");
-    }
-}

+ 0 - 50
jme3-examples/src/main/java/jme3test/asset/TestCustomLoader.java

@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2009-2012 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package jme3test.asset;
-
-import com.jme3.asset.AssetLoader;
-import com.jme3.asset.AssetManager;
-import com.jme3.asset.plugins.ClasspathLocator;
-import com.jme3.system.JmeSystem;
-
-/**
- * Demonstrates loading a file from a custom {@link AssetLoader}
- */
-public class TestCustomLoader {
-    public static void main(String[] args){
-        AssetManager assetManager = JmeSystem.newAssetManager();
-        assetManager.registerLocator("/", ClasspathLocator.class);
-        assetManager.registerLoader(TextLoader.class, "fnt");
-        System.out.println(assetManager.loadAsset("Interface/Fonts/Console.fnt"));
-    }
-}

+ 0 - 91
jme3-examples/src/main/java/jme3test/asset/TestManyLocators.java

@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2009-2021 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package jme3test.asset;
-
-import com.jme3.asset.*;
-import com.jme3.asset.plugins.ClasspathLocator;
-import com.jme3.asset.plugins.HttpZipLocator;
-import com.jme3.asset.plugins.UrlLocator;
-import com.jme3.asset.plugins.ZipLocator;
-import com.jme3.system.JmeSystem;
-
-public class TestManyLocators {
-    public static void main(String[] args){
-        AssetManager am = JmeSystem.newAssetManager();
-
-        am.registerLocator(
-                "https://github.com/jMonkeyEngine/wiki/raw/master/docs/modules/tutorials/assets/images/beginner/",
-                UrlLocator.class);
-
-        am.registerLocator("town.zip", ZipLocator.class);
-        am.registerLocator(
-                "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/wildhouse.zip",
-                HttpZipLocator.class);
-
-        am.registerLocator("/", ClasspathLocator.class);
-        
-        
-
-        // Try loading from jme3-core resources using the ClasspathLocator.
-        AssetInfo a = am.locateAsset(new AssetKey<Object>("Interface/Fonts/Default.fnt"));
-
-        // Try loading from the "town.zip" file using the ZipLocator.
-        AssetInfo b = am.locateAsset(new ModelKey("casaamarela.jpg"));
-
-        // Try loading from the Google Code Archive website using the HttpZipLocator.
-        AssetInfo c = am.locateAsset(new ModelKey("glasstile2.png"));
-
-        // Try loading from the GitHub website using the UrlLocator.
-        AssetInfo d = am.locateAsset(new TextureKey("beginner-physics.png"));
-
-        if (a == null)
-            System.out.println("Failed to load from classpath");
-        else
-            System.out.println("Found classpath font: " + a.toString());
-
-        if (b == null)
-            System.out.println("Failed to load from town.zip file");
-        else
-            System.out.println("Found zip image: " + b.toString());
-
-        if (c == null)
-            System.out.println("Failed to load from wildhouse.zip on googleapis.com");
-        else
-            System.out.println("Found online zip image: " + c.toString());
-
-        if (d == null)
-            System.out.println("Failed to load from HTTP");
-        else
-            System.out.println("Found HTTP showcase image: " + d.toString());
-    }
-}

+ 0 - 92
jme3-examples/src/main/java/jme3test/bullet/TestIssue1004.java

@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2019 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package jme3test.bullet;
-
-import com.jme3.app.SimpleApplication;
-import com.jme3.bullet.BulletAppState;
-import com.jme3.bullet.control.KinematicRagdollControl;
-import com.jme3.scene.Geometry;
-import com.jme3.scene.Mesh;
-import com.jme3.scene.Node;
-import com.jme3.scene.VertexBuffer;
-import java.nio.ByteBuffer;
-
-/**
- * Test case for JME issue #1004: RagdollUtils can't handle 16-bit bone indices.
- * <p>
- * If successful, no exception will be thrown.
- */
-public class TestIssue1004 extends SimpleApplication {
-    // *************************************************************************
-    // new methods exposed
-
-    public static void main(String[] args) {
-        TestIssue1004 app = new TestIssue1004();
-        app.start();
-    }
-    // *************************************************************************
-    // SimpleApplication methods
-
-    @Override
-    public void simpleInitApp() {
-        BulletAppState bulletAppState = new BulletAppState();
-        stateManager.attach(bulletAppState);
-        String sinbadPath = "Models/Sinbad/SinbadOldAnim.j3o";
-        Node sinbad = (Node) assetManager.loadModel(sinbadPath);
-
-        Geometry geometry = (Geometry) sinbad.getChild(0);
-        Mesh mesh = geometry.getMesh();
-        VertexBuffer.Type bufferType = VertexBuffer.Type.BoneIndex;
-        VertexBuffer vertexBuffer = mesh.getBuffer(bufferType);
-
-        // Remove the existing bone-index buffer.
-        mesh.getBufferList().remove(vertexBuffer);
-        mesh.getBuffers().remove(bufferType.ordinal());
-
-        // Copy the 8-bit bone indices to 16-bit indices.
-        ByteBuffer oldBuffer = (ByteBuffer) vertexBuffer.getDataReadOnly();
-        int numComponents = oldBuffer.limit();
-        oldBuffer.rewind();
-        short[] shortArray = new short[numComponents];
-        for (int index = 0; oldBuffer.hasRemaining(); ++index) {
-            shortArray[index] = oldBuffer.get();
-        }
-
-        // Add the 16-bit bone indices to the mesh.
-        mesh.setBuffer(bufferType, 4, shortArray);
-
-        KinematicRagdollControl ragdoll = new KinematicRagdollControl(0.5f);
-        sinbad.addControl(ragdoll);
-
-        stop();
-    }
-}

+ 0 - 87
jme3-examples/src/main/java/jme3test/bullet/TestIssue889.java

@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2018 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package jme3test.bullet;
-
-/**
- * Test case for JME issue #889: disabled physics control gets added to a
- * physics space.
- * <p>
- * If successful, no debug meshes will be visible.
- */
-import com.jme3.app.SimpleApplication;
-import com.jme3.bullet.BulletAppState;
-import com.jme3.bullet.PhysicsSpace;
-import com.jme3.bullet.collision.shapes.BoxCollisionShape;
-import com.jme3.bullet.collision.shapes.CollisionShape;
-import com.jme3.bullet.collision.shapes.SphereCollisionShape;
-import com.jme3.bullet.control.BetterCharacterControl;
-import com.jme3.bullet.control.GhostControl;
-import com.jme3.bullet.control.RigidBodyControl;
-import com.jme3.math.Vector3f;
-
-public class TestIssue889 extends SimpleApplication {
-
-    public static void main(String[] args) {
-        TestIssue889 app = new TestIssue889();
-        app.start();
-    }
-
-    @Override
-    public void simpleInitApp() {
-        flyCam.setEnabled(false);
-
-        BulletAppState bulletAppState = new BulletAppState();
-        bulletAppState.setDebugEnabled(true);
-        bulletAppState.setSpeed(0f);
-        stateManager.attach(bulletAppState);
-        PhysicsSpace space = bulletAppState.getPhysicsSpace();
-
-        float radius = 1f;
-        CollisionShape sphere = new SphereCollisionShape(radius);
-        CollisionShape box = new BoxCollisionShape(Vector3f.UNIT_XYZ);
-
-        RigidBodyControl rbc = new RigidBodyControl(box);
-        rbc.setEnabled(false);
-        rbc.setPhysicsSpace(space);
-        rootNode.addControl(rbc);
-
-        BetterCharacterControl bcc = new BetterCharacterControl(radius, 4f, 1f);
-        bcc.setEnabled(false);
-        bcc.setPhysicsSpace(space);
-        rootNode.addControl(bcc);
-
-        GhostControl gc = new GhostControl(sphere);
-        gc.setEnabled(false);
-        gc.setPhysicsSpace(space);
-        rootNode.addControl(gc);
-    }
-}

+ 0 - 76
jme3-examples/src/main/java/jme3test/bullet/TestIssue931.java

@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2018 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package jme3test.bullet;
-
-import com.jme3.app.SimpleApplication;
-import com.jme3.bullet.BulletAppState;
-import com.jme3.bullet.control.KinematicRagdollControl;
-import com.jme3.scene.Node;
-import com.jme3.scene.Spatial;
-
-/**
- * Test case for JME issue #931: RagdollUtils can miss model meshes or use the
- * non-animated ones.
- * <p>
- * If successful, no AssertionError will be thrown.
- */
-public class TestIssue931 extends SimpleApplication {
-    // *************************************************************************
-    // new methods exposed
-
-    public static void main(String[] args) {
-        TestIssue931 app = new TestIssue931();
-        app.start();
-    }
-    // *************************************************************************
-    // SimpleApplication methods
-
-    @Override
-    public void simpleInitApp() {
-        BulletAppState bulletAppState = new BulletAppState();
-        stateManager.attach(bulletAppState);
-        String sinbadPath = "Models/Sinbad/SinbadOldAnim.j3o";
-        Node sinbad = (Node) assetManager.loadModel(sinbadPath);
-
-        Node extender = new Node();
-        for (Spatial child : sinbad.getChildren()) {
-            extender.attachChild(child);
-        }
-        sinbad.attachChild(extender);
-
-        //Note: PhysicsRagdollControl is still a WIP, constructor will change
-        KinematicRagdollControl ragdoll = new KinematicRagdollControl(0.5f);
-        sinbad.addControl(ragdoll);
-
-        stop();
-    }
-}

+ 0 - 139
jme3-examples/src/main/java/jme3test/bullet/TestIssue970.java

@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2018 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package jme3test.bullet;
-
-import com.jme3.app.SimpleApplication;
-import com.jme3.asset.AssetNotFoundException;
-import com.jme3.asset.ModelKey;
-import com.jme3.asset.plugins.FileLocator;
-import com.jme3.bullet.collision.shapes.CollisionShape;
-import com.jme3.bullet.collision.shapes.SphereCollisionShape;
-import com.jme3.bullet.control.RigidBodyControl;
-import com.jme3.bullet.objects.PhysicsRigidBody;
-import com.jme3.export.JmeExporter;
-import com.jme3.export.binary.BinaryExporter;
-import com.jme3.math.Matrix3f;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Node;
-import com.jme3.scene.Spatial;
-import com.jme3.scene.control.Control;
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Test case for JME issue #970: RigidBodyControl doesn't read/write velocities.
- *
- * If successful, no AssertionError will be thrown.
- *
- * @author Stephen Gold [email protected]
- */
-public class TestIssue970 extends SimpleApplication {
-
-    private int fileIndex = 0;
-
-    public static void main(String[] args) {
-        TestIssue970 app = new TestIssue970();
-        app.start();
-    }
-
-    @Override
-    public void simpleInitApp() {
-        assetManager.registerLocator(".", FileLocator.class);
-
-        CollisionShape shape = new SphereCollisionShape(1f);
-        RigidBodyControl rbc = new RigidBodyControl(shape, 1f);
-        setParameters(rbc);
-        verifyParameters(rbc);
-        RigidBodyControl rbcCopy = (RigidBodyControl) saveThenLoad(rbc);
-        verifyParameters(rbcCopy);
-
-        stop();
-    }
-
-    /**
-     * Clone a body that implements Control by saving and then loading it.
-     *
-     * @param sgc the body/control to copy (not null, unaffected)
-     * @return a new body/control
-     */
-    private PhysicsRigidBody saveThenLoad(PhysicsRigidBody body) {
-        Control sgc = (Control) body;
-        Node savedNode = new Node();
-        /*
-         * Add the Control to the Node without altering its physics transform.
-         */
-        Vector3f pl = body.getPhysicsLocation(null);
-        Matrix3f pr = body.getPhysicsRotationMatrix(null);
-        savedNode.addControl(sgc);
-        body.setPhysicsLocation(pl);
-        body.setPhysicsRotation(pr);
-
-        String fileName = String.format("tmp%d.j3o", ++fileIndex);
-        File file = new File(fileName);
-
-        JmeExporter exporter = BinaryExporter.getInstance();
-        try {
-            exporter.save(savedNode, file);
-        } catch (IOException exception) {
-            assert false;
-        }
-
-        ModelKey key = new ModelKey(fileName);
-        Spatial loadedNode = new Node();
-        try {
-            loadedNode = assetManager.loadAsset(key);
-        } catch (AssetNotFoundException e) {
-            assert false;
-        }
-        file.delete();
-        Control loadedSgc = loadedNode.getControl(0);
-
-        return (PhysicsRigidBody) loadedSgc;
-    }
-
-    private void setParameters(PhysicsRigidBody body) {
-        body.setAngularVelocity(new Vector3f(0.04f, 0.05f, 0.06f));
-        body.setLinearVelocity(new Vector3f(0.26f, 0.27f, 0.28f));
-    }
-
-    private void verifyParameters(PhysicsRigidBody body) {
-        Vector3f w = body.getAngularVelocity();
-        assert w.x == 0.04f : w;
-        assert w.y == 0.05f : w;
-        assert w.z == 0.06f : w;
-
-        Vector3f v = body.getLinearVelocity();
-        assert v.x == 0.26f : v;
-        assert v.y == 0.27f : v;
-        assert v.z == 0.28f : v;
-    }
-}

+ 9 - 0
jme3-jbullet/build.gradle

@@ -5,6 +5,13 @@ sourceSets {
             srcDir '../jme3-bullet/src/common/java'
         }
     }
+    test {
+        java {
+            srcDir 'src/test/java'
+        }
+
+        System.setProperty "java.awt.headless", "true"
+    }
 }
 
 dependencies {
@@ -12,4 +19,6 @@ dependencies {
     api 'javax.vecmath:vecmath:1.5.2'
     api project(':jme3-core')
     api project(':jme3-terrain')
+    testRuntime project(':jme3-desktop')
+    testRuntime project(':jme3-testdata')
 }

+ 203 - 0
jme3-jbullet/src/test/java/com/jme3/jbullet/test/PreventBulletIssueRegressions.java

@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2019-2021 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.jbullet.test;
+
+import com.jme3.asset.AssetInfo;
+import com.jme3.asset.DesktopAssetManager;
+import com.jme3.bullet.BulletAppState;
+import com.jme3.bullet.PhysicsSpace;
+import com.jme3.bullet.PhysicsTickListener;
+import com.jme3.bullet.collision.shapes.BoxCollisionShape;
+import com.jme3.bullet.collision.shapes.CollisionShape;
+import com.jme3.bullet.collision.shapes.SphereCollisionShape;
+import com.jme3.bullet.control.BetterCharacterControl;
+import com.jme3.bullet.control.GhostControl;
+import com.jme3.bullet.control.KinematicRagdollControl;
+import com.jme3.bullet.control.RigidBodyControl;
+import com.jme3.bullet.objects.PhysicsRigidBody;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.binary.BinaryExporter;
+import com.jme3.export.binary.BinaryImporter;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Mesh;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.VertexBuffer;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.nio.ByteBuffer;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+/**
+ * The Test Suite to prevent regressions from previously fixed Bullet issues
+ * @author Stephen Gold &lt;[email protected]&gt;
+ */
+public class PreventBulletIssueRegressions {
+    /**
+     * Test case for JME issue #889: disabled physics control gets added to a
+     * physics space.
+     */
+    @Test
+    public void testIssue889() throws IllegalAccessException, NoSuchFieldException {
+        // throws are added so that we don't have to catch them just to assert them again.
+        // If they throw, the Unit Test should fail
+        Field f1 = PhysicsSpace.class.getDeclaredField("tickListeners");
+        f1.setAccessible(true);
+        Field f2 = BetterCharacterControl.class.getDeclaredField("rigidBody");
+        f2.setAccessible(true);
+
+        BulletAppState bulletAppState = new BulletAppState();
+        bulletAppState.setSpeed(0f);
+        bulletAppState.startPhysics(); // so that we don't need an AppStateManager etc
+        PhysicsSpace space = bulletAppState.getPhysicsSpace();
+        ConcurrentLinkedQueue<PhysicsTickListener> tickListeners = (ConcurrentLinkedQueue<PhysicsTickListener>)f1.get(space);
+
+        float radius = 1f;
+        CollisionShape sphere = new SphereCollisionShape(radius);
+        CollisionShape box = new BoxCollisionShape(Vector3f.UNIT_XYZ);
+
+        Node rootNode = new Node("RootNode");
+
+        RigidBodyControl rbc = new RigidBodyControl(box);
+        rbc.setEnabled(false);
+        rbc.setPhysicsSpace(space);
+        rootNode.addControl(rbc);
+
+        BetterCharacterControl bcc = new BetterCharacterControl(radius, 4f, 1f);
+        bcc.setEnabled(false);
+        bcc.setPhysicsSpace(space);
+        rootNode.addControl(bcc);
+        PhysicsRigidBody bcc_rb = (PhysicsRigidBody)f2.get(bcc);
+
+        GhostControl gc = new GhostControl(sphere);
+        gc.setEnabled(false);
+        gc.setPhysicsSpace(space);
+        rootNode.addControl(gc);
+
+        Assert.assertFalse(space.getRigidBodyList().contains(rbc));
+        Assert.assertFalse(tickListeners.contains(bcc));
+        Assert.assertFalse(space.getRigidBodyList().contains(bcc_rb));
+        Assert.assertFalse(space.getGhostObjectList().contains(gc));
+    }
+
+    /**
+     * Test case for JME issue #931: RagdollUtils can miss model meshes or use the
+     * non-animated ones.
+     */
+    @Test
+    public void testIssue931() {
+        Node sinbad = (Node)new DesktopAssetManager(true).loadModel("Models/Sinbad/SinbadOldAnim.j3o");
+        Node extender = new Node();
+        for (Spatial child : sinbad.getChildren()) {
+            extender.attachChild(child);
+        }
+        sinbad.attachChild(extender);
+
+        //Note: PhysicsRagdollControl is still a WIP, constructor will change
+        KinematicRagdollControl ragdoll = new KinematicRagdollControl(0.5f);
+        sinbad.addControl(ragdoll);
+    }
+
+    /**
+     * Test case for JME issue #970: RigidBodyControl doesn't read/write velocities.
+     * Clone a body that implements Control by saving and then loading it.
+     * */
+    @Test
+    public void testIssue970() throws IOException {
+        // throws are added so that we don't have to catch them just to assert them again.
+        // If they throw, the Unit Test should fail
+        CollisionShape shape = new SphereCollisionShape(1f);
+        RigidBodyControl rbc = new RigidBodyControl(shape, 1f);
+        rbc.setAngularVelocity(new Vector3f(0.04f, 0.05f, 0.06f));
+        rbc.setLinearVelocity(new Vector3f(0.26f, 0.27f, 0.28f));
+
+        Assert.assertEquals(new Vector3f(0.04f, 0.05f, 0.06f), rbc.getAngularVelocity());
+        Assert.assertEquals(new Vector3f(0.26f, 0.27f, 0.28f), rbc.getLinearVelocity());
+
+        // Write/Serialize the RBC
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        JmeExporter exporter = BinaryExporter.getInstance();
+        exporter.save(rbc, baos);
+
+        // Load/Deserialize the RBC
+        JmeImporter importer = BinaryImporter.getInstance();
+        RigidBodyControl rbcCopy = (RigidBodyControl)importer.load(new AssetInfo(null, null) {
+            @Override
+            public InputStream openStream() {
+                return new ByteArrayInputStream(baos.toByteArray());
+            }
+        });
+
+        Assert.assertNotNull(rbcCopy);
+        Assert.assertEquals(new Vector3f(0.04f, 0.05f, 0.06f), rbcCopy.getAngularVelocity());
+        Assert.assertEquals(new Vector3f(0.26f, 0.27f, 0.28f), rbcCopy.getLinearVelocity());
+    }
+
+    /**
+     *  Test case for JME issue #1004: RagdollUtils can't handle 16-bit bone indices.
+     */
+    @Test
+    public void testIssue1004() {
+        Node sinbad = (Node)new DesktopAssetManager(true).loadModel("Models/Sinbad/SinbadOldAnim.j3o");
+
+        Geometry geometry = (Geometry) sinbad.getChild(0);
+        Mesh mesh = geometry.getMesh();
+        VertexBuffer.Type bufferType = VertexBuffer.Type.BoneIndex;
+        VertexBuffer vertexBuffer = mesh.getBuffer(bufferType);
+
+        // Remove the existing bone-index buffer.
+        mesh.getBufferList().remove(vertexBuffer);
+        mesh.getBuffers().remove(bufferType.ordinal());
+
+        // Copy the 8-bit bone indices to 16-bit indices.
+        ByteBuffer oldBuffer = (ByteBuffer) vertexBuffer.getDataReadOnly();
+        int numComponents = oldBuffer.limit();
+        oldBuffer.rewind();
+        short[] shortArray = new short[numComponents];
+        for (int index = 0; oldBuffer.hasRemaining(); ++index) {
+            shortArray[index] = oldBuffer.get();
+        }
+
+        // Add the 16-bit bone indices to the mesh.
+        mesh.setBuffer(bufferType, 4, shortArray);
+
+        sinbad.addControl(new KinematicRagdollControl(0.5f)); // should not throw
+    }
+}