CapsuleColissionShape not visible

Hi,

I tried running the jmeTests project, and many programs ran, but the one that was most important for me: The TestRagDoll program, rendered only the physics world’s “floor”, the cubes and the sphere. The ragdoll was nowhere to be seen. The other two ragdoll programs worked, but the TestRagDoll was the kind of program I needed JMonkey for.

So I copied that code and tried narrowing down the problem, but CapsuleColissionShape objects are still not visible on the screen. Am I doing something wrong or is there a problem with my computer hardware that makes it not render correctly?

The code:
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.joints.ConeJoint;
import com.jme3.bullet.joints.PhysicsJoint;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;

/**
 *
 * @author normenhansen
 */
public class Main extends SimpleApplication implements ActionListener {

    private BulletAppState bulletAppState = new BulletAppState();
    private Node ragDoll = new Node();
    private Node shoulders;
    private Vector3f upforce = new Vector3f(0, 200, 0);
    private boolean applyForce = false;

    public static void main(String[] args) {
        Main app = new Main();
        app.setShowSettings(false);
        AppSettings settings = new AppSettings(true);
        settings.put("Width", 1280);
        settings.put("Height", 720);
        settings.put("Title", "My prog");
        settings.put("VSync", true);
        //Anti-Aliasing
        settings.put("Samples", 4);
        app.setSettings(settings);
        app.start();
    }

    @Override
    public void simpleInitApp() {
        bulletAppState = new BulletAppState();
        stateManager.attach(bulletAppState);
        bulletAppState.setDebugEnabled(true);
        inputManager.addMapping("Pull ragdoll up", new MouseButtonTrigger(0));
        inputManager.addListener(this, "Pull ragdoll up");
        PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace());
        //createRagDoll();
        
        Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
        
        
        Box box = new Box(0.1f, 0.1f, 1);
        Geometry boxGeometry = new Geometry("Box", box);
        boxGeometry.setMaterial(material);
        boxGeometry.setLocalTranslation(2, -5, 0);
        //RigidBodyControl automatically uses box collision shapes when attached to single geometry with box mesh
        boxGeometry.addControl(new RigidBodyControl(2));
        rootNode.attachChild(boxGeometry);
        bulletAppState.getPhysicsSpace().add(boxGeometry);     
        
        Box box2 = new Box(0.1f, 0.1f, 1);
        Geometry boxGeometry2 = new Geometry("Box", box2);
        boxGeometry2.setMaterial(material);
        boxGeometry2.setLocalTranslation(2, -5, -2);
        //RigidBodyControl automatically uses box collision shapes when attached to single geometry with box mesh
        boxGeometry2.addControl(new RigidBodyControl(2));
        rootNode.attachChild(boxGeometry2);
        bulletAppState.getPhysicsSpace().add(boxGeometry2);  

        createLimb(0.1f, 0.1f, new Vector3f(3,-5,-2), false, material);        
    }
    
    private Node createLimb(float width, float height, Vector3f location, boolean rotate, Material mat) {
        int axis = rotate ? PhysicsSpace.AXIS_X : PhysicsSpace.AXIS_Y;
        CapsuleCollisionShape shape = new CapsuleCollisionShape(width, height, axis);
        Node node = new Node("Limb");
        node.setMaterial(mat);
        RigidBodyControl rigidBodyControl = new RigidBodyControl(shape, 1);
        node.setLocalTranslation(location);
        node.addControl(rigidBodyControl);
        return node;
    }

    private void createRagDoll() {
//        shoulders = createLimb(2, 5, new Vector3f(0, 5, -3), true);
//        Node uArmL = createLimb(0.2f, 0.5f, new Vector3f(-5.75f, -4.8f, 2), false);
//        Node uArmR = createLimb(0.2f, 0.5f, new Vector3f(5.75f, -4.8f, 2), false);
//        Node lArmL = createLimb(0.2f, 0.5f, new Vector3f(-5.75f, -4.2f, 2), false);
//        Node lArmR = createLimb(0.2f, 0.5f, new Vector3f(5.75f, -4.2f, 2), false);
//        Node body = createLimb(4f, 1, new Vector3f(4, -4, 2), false);
//        Node hips = createLimb(0.2f, 0.5f, new Vector3f(5.00f, -4.5f, 2), true);
//        Node uLegL = createLimb(0.2f, 0.5f, new Vector3f(-5.25f, -4.2f, 2), false);
//        Node uLegR = createLimb(0.2f, 0.5f, new Vector3f(5.25f, -4.2f, 2), false);
//        Node lLegL = createLimb(0.2f, 0.5f, new Vector3f(-5.25f, -4.2f, 2), false);
//        Node lLegR = createLimb(0.2f, 0.5f, new Vector3f(5.25f, -4.2f, 2), false);

//        join(body, shoulders, new Vector3f(1, 2, -3));
//        join(body, hips, new Vector3f(0f, -0.5f, 0));
//
//        join(uArmL, shoulders, new Vector3f(-0.75f, 1.4f, 0));
//        join(uArmR, shoulders, new Vector3f(0.75f, 1.4f, 0));
//        join(uArmL, lArmL, new Vector3f(-0.75f, .4f, 0));
//        join(uArmR, lArmR, new Vector3f(0.75f, .4f, 0));
//
//        join(uLegL, hips, new Vector3f(-.25f, -0.5f, 0));
//        join(uLegR, hips, new Vector3f(.25f, -0.5f, 0));
//        join(uLegL, lLegL, new Vector3f(-.25f, -1.7f, 0));
//        join(uLegR, lLegR, new Vector3f(.25f, -1.7f, 0));

//        ragDoll.attachChild(shoulders);
//        ragDoll.attachChild(body);
//        ragDoll.attachChild(hips);
//        ragDoll.attachChild(uArmL);
//        ragDoll.attachChild(uArmR);
//        ragDoll.attachChild(lArmL);
//        ragDoll.attachChild(lArmR);
//        ragDoll.attachChild(uLegL);
//        ragDoll.attachChild(uLegR);
//        ragDoll.attachChild(lLegL);
//        ragDoll.attachChild(lLegR);

        rootNode.attachChild(ragDoll);
        bulletAppState.getPhysicsSpace().addAll(ragDoll);
    }



    private PhysicsJoint join(Node A, Node B, Vector3f connectionPoint) {
        Vector3f pivotA = A.worldToLocal(connectionPoint, new Vector3f());
        Vector3f pivotB = B.worldToLocal(connectionPoint, new Vector3f());
        ConeJoint joint = new ConeJoint(A.getControl(RigidBodyControl.class), B.getControl(RigidBodyControl.class), pivotA, pivotB);
        joint.setLimit(1f, 1f, 0);
        return joint;
    }

    public void onAction(String string, boolean bln, float tpf) {
        if ("Pull ragdoll up".equals(string)) {
            if (bln) {
                shoulders.getControl(RigidBodyControl.class).activate();
                applyForce = true;
            } else {
                applyForce = false;
            }
        }
    }

    @Override
    public void simpleUpdate(float tpf) {
        //cam.lookAt(ragDoll.getLocalTranslation(), Vector3f.UNIT_Y);
        if (applyForce) {
            shoulders.getControl(RigidBodyControl.class).applyForce(upforce, Vector3f.ZERO);
        }
    }
}

This is the output from the program:
run:
Jul 04, 2019 9:13:03 AM com.jme3.system.JmeDesktopSystem initialize
INFO: Running on jMonkeyEngine 3.2-stable
* Branch: HEAD
* Git Hash: ea23b6a
* Build Date: 2019-01-02
Jul 04, 2019 9:13:05 AM com.jme3.system.lwjgl.LwjglContext printContextInitInfo
INFO: LWJGL 2.9.3 context running on thread jME3 Main
* Graphics Adapter: null
* Driver Version: null
* Scaling Factor: 1
Jul 04, 2019 9:13:05 AM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFO: OpenGL Renderer Information
* Vendor: Intel Open Source Technology Center
* Renderer: Mesa DRI Intel® Bay Trail
* OpenGL Version: 3.0 Mesa 18.0.5
* GLSL Version: 1.30
* Profile: Compatibility
Jul 04, 2019 9:13:05 AM com.jme3.asset.AssetConfig loadText
WARNING: Cannot find loader com.jme3.scene.plugins.blender.BlenderModelLoader
Jul 04, 2019 9:13:06 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Renderer Information
* Device: OpenAL Soft
* Vendor: OpenAL Community
* Renderer: OpenAL Soft
* Version: 1.1 ALSOFT 1.15.1
* Supported channels: 64
* ALC extensions: ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX ALC_EXT_thread_local_context ALC_SOFT_loopback
* AL extensions: AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFTX_deferred_updates AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_source_latency
Jul 04, 2019 9:13:06 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
WARNING: Pausing audio device not supported.
Jul 04, 2019 9:13:06 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio effect extension version: 1.0
Jul 04, 2019 9:13:06 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio max auxiliary sends: 4
Bullet-Native: Initializing java classes
BUILD SUCCESSFUL (total time: 7 seconds)

Attaching it to the root node also didn’t help:
Node l1 = createLimb(0.1f, 0.1f, new Vector3f(3,-5,-2), false, material);
rootNode.attachChild(l1);
bulletAppState.getPhysicsSpace().addAll(l1);

Welcome to the jMonkey community, Navin.

Before looking at your modifications, I’d like to understand why the unmodified code didn’t work for you.

TestRagDoll should work “out of the box”. You shouldn’t need to modify it to see the capsule shapes, certainly not with native Bullet in JME 3.2.2-stable in Linux, the environment you appear to be running in.

The key bit for making the shapes visible is line 67 of TestRagDoll.java:

bulletAppState.setDebugEnabled(true);

Would you please create a fresh Jme3 Tests project, confirm that this line is unmodified, and run the test again?

Ok, so did a clean install of JME SDK.

Product Version: jMonkeyEngine SDK v3.2.2-stable-sdk1
Java: 1.8.0_192; Java HotSpot(TM) 64-Bit Server VM 25.192-b12
Runtime: Java(TM) SE Runtime Environment 1.8.0_192-b12
System: Linux version 4.4.0-151-generic running on amd64; UTF-8; en_IN (jmonkeyplatform)
User directory: /home/navin/.jmonkeyplatform/v3.2.2-stable-sdk1
Cache directory: /home/navin/.jmonkeyplatform/v3.2.2-stable-sdk1/var/cache

File > New Project > JME3> Jme3 Tests

Built the project:
warning: [options] bootstrap class path not set in conjunction with -source 1.7
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

On running, the floor, the cubes and sphere appear, but the ragdoll doesn’t.

compile:
run:
Jul 04, 2019 2:46:31 PM com.jme3.system.JmeDesktopSystem initialize
INFO: Running on jMonkeyEngine 3.2-stable
 * Branch: HEAD
 * Git Hash: ea23b6a
 * Build Date: 2019-01-02
Jul 04, 2019 2:46:33 PM com.jme3.system.lwjgl.LwjglContext initOpenCL
INFO: Initialize OpenCL wiht LWJGL2
Jul 04, 2019 2:46:33 PM com.jme3.system.lwjgl.LwjglContext initOpenCL
SEVERE: Unable to initialize OpenCL
org.lwjgl.LWJGLException: Could not locate OpenCL library.
	at org.lwjgl.opencl.CL.create(CL.java:122)
	at com.jme3.system.lwjgl.LwjglContext.initOpenCL(LwjglContext.java:267)
	at com.jme3.system.lwjgl.LwjglDisplay.createContext(LwjglDisplay.java:154)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:113)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:211)
	at java.lang.Thread.run(Thread.java:748)

Jul 04, 2019 2:46:33 PM com.jme3.system.lwjgl.LwjglContext printContextInitInfo
INFO: LWJGL 2.9.3 context running on thread jME3 Main
 * Graphics Adapter: null
 * Driver Version: null
 * Scaling Factor: 1
Jul 04, 2019 2:46:33 PM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFO: OpenGL Renderer Information
 * Vendor: Intel Open Source Technology Center
 * Renderer: Mesa DRI Intel(R) Bay Trail 
 * OpenGL Version: 3.0 Mesa 18.0.5
 * GLSL Version: 1.30
 * Profile: Compatibility
Jul 04, 2019 2:46:35 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Renderer Information
 * Device: OpenAL Soft
 * Vendor: OpenAL Community
 * Renderer: OpenAL Soft
 * Version: 1.1 ALSOFT 1.15.1
 * Supported channels: 64
 * ALC extensions: ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX ALC_EXT_thread_local_context ALC_SOFT_loopback
 * AL extensions: AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFTX_deferred_updates AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_source_latency
Jul 04, 2019 2:46:35 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
WARNING: Pausing audio device not supported.
Jul 04, 2019 2:46:35 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio effect extension version: 1.0
Jul 04, 2019 2:46:35 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio max auxiliary sends: 4
Bullet-Native: Initializing java classes
Jul 04, 2019 2:46:58 PM com.jme3.system.lwjgl.LwjglContext initOpenCL
INFO: Initialize OpenCL wiht LWJGL2
Jul 04, 2019 2:46:58 PM com.jme3.system.lwjgl.LwjglContext initOpenCL
SEVERE: Unable to initialize OpenCL
org.lwjgl.LWJGLException: Could not locate OpenCL library.
	at org.lwjgl.opencl.CL.create(CL.java:122)
	at com.jme3.system.lwjgl.LwjglContext.initOpenCL(LwjglContext.java:267)
	at com.jme3.system.lwjgl.LwjglDisplay.createContext(LwjglDisplay.java:154)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:113)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:211)
	at java.lang.Thread.run(Thread.java:748)

Jul 04, 2019 2:46:58 PM com.jme3.system.lwjgl.LwjglContext printContextInitInfo
INFO: LWJGL 2.9.3 context running on thread jME3 Main
 * Graphics Adapter: null
 * Driver Version: null
 * Scaling Factor: 1
Jul 04, 2019 2:46:58 PM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFO: OpenGL Renderer Information
 * Vendor: Intel Open Source Technology Center
 * Renderer: Mesa DRI Intel(R) Bay Trail 
 * OpenGL Version: 3.0 Mesa 18.0.5
 * GLSL Version: 1.30
 * Profile: Compatibility
Jul 04, 2019 2:46:58 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Renderer Information
 * Device: OpenAL Soft
 * Vendor: OpenAL Community
 * Renderer: OpenAL Soft
 * Version: 1.1 ALSOFT 1.15.1
 * Supported channels: 64
 * ALC extensions: ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX ALC_EXT_thread_local_context ALC_SOFT_loopback
 * AL extensions: AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFTX_deferred_updates AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_source_latency
Jul 04, 2019 2:46:58 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
WARNING: Pausing audio device not supported.
Jul 04, 2019 2:46:58 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio effect extension version: 1.0
Jul 04, 2019 2:46:58 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio max auxiliary sends: 4
BUILD SUCCESSFUL (total time: 1 minute 5 seconds)

and yes debug is true: bulletAppState.setDebugEnabled(true);

1 Like

Very interesting. And now I’m seeing that issue too, but only on Linux, not on Windows. Thank you for bringing this to my attention.

I suspect the issue has something to do with ConeJoint. Despite what the documentation says about ConeJoint being good for ragdolls, I usually use SixDofJoint instead.

I’ll investigate and report back.

I’m convinced it’s something about ConeJoint. Changing the test as follows solved the issue for me:

--- a/jme3-examples/src/main/java/jme3test/bullet/TestRagDoll.java
+++ b/jme3-examples/src/main/java/jme3test/bullet/TestRagDoll.java
@@ -38,6 +38,7 @@
 import com.jme3.bullet.control.RigidBodyControl;
 import com.jme3.bullet.joints.ConeJoint;
 import com.jme3.bullet.joints.PhysicsJoint;
+import com.jme3.bullet.joints.SixDofJoint;
 import com.jme3.input.controls.ActionListener;
 import com.jme3.input.controls.MouseButtonTrigger;
 import com.jme3.math.Vector3f;
@@ -126,8 +127,7 @@
     private PhysicsJoint join(Node A, Node B, Vector3f connectionPoint) {
         Vector3f pivotA = A.worldToLocal(connectionPoint, new Vector3f());
         Vector3f pivotB = B.worldToLocal(connectionPoint, new Vector3f());
-        ConeJoint joint = new ConeJoint(A.getControl(RigidBodyControl.class), B.getControl(RigidBodyControl.class), pivotA, pivotB);
-        joint.setLimit(1f, 1f, 0);
+        SixDofJoint joint = new SixDofJoint(A.getControl(RigidBodyControl.class), B.getControl(RigidBodyControl.class), pivotA, pivotB, true);
         return joint;
     }

I’m working on a fix for ConeJoint.

I found a fix for ConeJoint: re-compiling the jme3-bullet-native library with gcc -O3 in place of gcc -Ofast. I’ll try to get this into a release ASAP.

3 Likes

Thank you @sgold. I guess all programs in JME Tests need to be checked, because I remember there were a few more that I tried running and they produced no output.
This is in Ubuntu 16.04.

1 Like

The JME3 Tests are awkward because they must be run by hand. I ran through them all for the 3.2.2 and 3.2.3 releases, but only on Windows, so I never saw this issue. For 3.2.4, I’ll make a point to run the physics tests on Linux.

The next time you see a test behave in an unexpected way, please mention it here—or open an issue at GitHub, or send me a private message.

@sgold do you know of any way that they could be run/verified automated?
If so, I am home for the next two weeks, and after I make the changes on my Shape Key Names PR, I can work on this.

1 Like

For jme3-core there are some automated tests, though the coverage is low. I created automated tests for Minie, so I’m certain something similar could be done for jme3-bullet and the other JME libraries. Automated tests are something I’ve been wanting for a while.

Good candidates for automation include:

  • TestIssue1004
  • TestIssue1029
  • TestIssue894
  • TestIssue911
  • TestIssue918
  • TestIssue928
  • TestIssue931
  • TestIssue970

That was a good suggestion. My testing of the v3.2.4 release candidate has already turned up another jme3-bullet issue that affects Linux but not Windows.

The fix is in jme3-bullet-native v3.2.4-stable .

1 Like

Thank you sgold. Glad to hear this.

1 Like