[SOLVED] It takes a long time to create a collision shape in the STL file

Hello
I am speaking in translation because I am not good at English.
I loaded the STL file from the Minie library using HelloMadMallet.java
at Minie/HelloMadMallet.java at 14d4f6af68c439e3413adc6ea27f3f90919d26ab · stephengold/Minie · GitHub
and wrote a test code where the object fell from top to bottom.
But it took 12 seconds to shape the collision of the object.
This object has a small file size of 1.6 MB. Can you tell me why?

It’s the code I wrote.

package jme3utilities.tutorial;

import com.jme3.app.SimpleApplication;
import com.jme3.asset.plugins.ClasspathLocator;
import com.jme3.asset.plugins.FileLocator;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.collision.shapes.CompoundCollisionShape;
import com.jme3.bullet.collision.shapes.CylinderCollisionShape;
import com.jme3.bullet.collision.shapes.HullCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.objects.PhysicsBody;
import com.jme3.bullet.objects.PhysicsRigidBody;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;

import jme3utilities.stl.STLLoader;

public class HelloMadMallet extends SimpleApplication {
	private PhysicsSpace physicsSpace;
	BulletAppState _bulletAppState;
	
    public static void main(String[] arguments) {
        HelloMadMallet application = new HelloMadMallet();
        application.start();
    }
    /**
     * Initialize this application.
     */
    @Override
    public void simpleInitApp() {
        // Set up Bullet physics and create a physics space.
    	_bulletAppState = new BulletAppState();
    	_bulletAppState.setDebugEnabled(true);
        stateManager.attach(_bulletAppState);
        physicsSpace = _bulletAppState.getPhysicsSpace();

        physicsSpace.setGravity(new Vector3f(0f, -50f, 0f));

        // Visualize the local axes of each collision object.
        _bulletAppState.setDebugAxisLength(1f);
        
        meshLoad();

        // Create a static disc and add it to the space.
        float discRadius = 5f;
        float discThickness = 0.5f;
        CollisionShape discShape = new CylinderCollisionShape(discRadius,
                discThickness, PhysicsSpace.AXIS_Y);
        PhysicsRigidBody disc
                = new PhysicsRigidBody(discShape, PhysicsBody.massForStatic);
        physicsSpace.addCollisionObject(disc);
        disc.setPhysicsLocation(new Vector3f(0f, -3f, 0f));

        // Re-position the camera for a better view.
        cam.setLocation(new Vector3f(10f, -2.75f, 0f));
        Vector3f targetLocation = new Vector3f(0f, -2.75f, 0f);
        Vector3f upDirection = Vector3f.UNIT_Y;
        cam.lookAt(targetLocation, upDirection);
    }
    
    public void meshLoad() {
        // Set assetManager
    	assetManager.registerLocator("C:/", FileLocator.class);
  		assetManager.registerLocator("/", ClasspathLocator.class);
  		assetManager.registerLoader(STLLoader.class, "stl");
  		
		// Add a model to the scene.
  		long stl_beforeTime = System.currentTimeMillis();
		Geometry geo = (Geometry) assetManager
				.loadModel("conveyorBelt.stl");
		Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md");
		long stl_afterTime = System.currentTimeMillis();
        long stl_secDiffTime = (stl_afterTime - stl_beforeTime);
        System.out.print("stl time : " + stl_secDiffTime + " (ms)\n");
		
        // Add collision shape
		long collision_beforeTime = System.currentTimeMillis();
		HullCollisionShape shape = new HullCollisionShape(geo.getMesh());
		RigidBodyControl control = new RigidBodyControl(shape, 1f);
		long collision_afterTime = System.currentTimeMillis();
        long collision_secDiffTime = (collision_afterTime - collision_beforeTime);
        System.out.print("collision time : " + collision_secDiffTime + " (ms)\n");
        
		geo.addControl(control);
		control.setPhysicsLocation(new Vector3f(0f, 4f, 0f));
		physicsSpace.add(geo);
		geo.setMaterial(mat);
		geo.scale(1f);
		rootNode.attachChild(geo);
    }
}

Results screen

Console

Time to load the stl file : 0.088s
Time to create conflict shapes for stl files : 12s

1 Like

This object has a small file size of 1.6 MB. Can you tell me why?

The time to generate a HullCollisionShape depends on the number of vertices in the mesh. Page 36 of the Bullet documentation recommends using less then 100 vertices.

If the STL file size is 1.6 megabytes, that suggests to me that that model contains far more than 100 vertices. That may explain why shape generation took 12 seconds.

2 Likes

In the documentation, it is the best to use BoxCollisionShape() for furniture that is Oblong or Cubic

1 Like

Thank you I checked the number of vertices in the mesh: 98676 I think we should use a different collision shape

1 Like

Thank you. When using BoxCollisionShape(), it loads at 80ms quickly

2 Likes

Glad it helps