Hi,
I’m using the most recent snapshot of the jme3.1 engine and SDK with jBullet libraries.
I have tried to move an old project to the new SDK. Unfortunately i extended RigidBodyControl (don’t ask why ;)). I have problems with saving a spatial with this control attached. Maybe there are problems with the cloning methods?
I recreated the problem in a simple testcase:
Main.java:
package mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.AssetManager;
import com.jme3.asset.DesktopAssetManager;
import com.jme3.asset.plugins.FileLocator;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.export.binary.BinaryExporter;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* This is the Main Class of your Game. You should only do initialization here.
* Move your Logic into AppStates or Controls
*
* @author normenhansen
*/
public class Main extends SimpleApplication {
BulletAppState bulletAppState;
public static void main(String[] args) {
Main app = new Main();
app.start();
}
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
Box b = new Box(1, 1, 1);
Geometry geom = new Geometry("Box", b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Blue);
geom.setMaterial(mat);
CustomRBControl control = new CustomRBControl();
geom.addControl(control);
bulletAppState.getPhysicsSpace().add(control);
rootNode.attachChild(geom);
save(System.getProperty("user.home") + "\\Documents\\"+"test.j3o");
rootNode.detachAllChildren();
((DesktopAssetManager)assetManager).clearCache();
load(System.getProperty("user.home") + "\\Documents\\", "test.j3o");
}
@Override
public void simpleUpdate(float tpf) {
//TODO: add update code
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
public boolean save(String filePath) {
BinaryExporter exporter = BinaryExporter.getInstance();
File file = new File(filePath);
try {
exporter.save(rootNode.getChild("Box"), file);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, "Error: Failed to save game!", ex);
return false;
}
return true;
}
public boolean load(String parentPath, String fileName) {
assetManager.registerLocator(parentPath, FileLocator.class);
Geometry geom = (Geometry) assetManager.loadModel(fileName);
rootNode.attachChild(geom);
return true;
}
}
CustomRBControl extends RigidBodyControl and has an empty body.
In jme3.0 this code runs as expected. When running this code in jme3.1 the output reads:
Uncaught exception thrown in Thread[jME3 Main,5,main]
java.lang.ClassCastException: Cannot cast com.jme3.bullet.control.RigidBodyControl to mygame.CustomRBControl
at java.lang.Class.cast(Class.java:3369)
at com.jme3.util.clone.Cloner.clone(Cloner.java:276)
at com.jme3.util.clone.Cloner.clone(Cloner.java:160)
at com.jme3.util.clone.ListCloneFunction.cloneFields(ListCloneFunction.java:66)
at com.jme3.util.clone.ListCloneFunction.cloneFields(ListCloneFunction.java:43)
at com.jme3.util.clone.Cloner.clone(Cloner.java:228)
at com.jme3.util.clone.Cloner.clone(Cloner.java:160)
at com.jme3.scene.Spatial.cloneFields(Spatial.java:1505)
at com.jme3.scene.Geometry.cloneFields(Geometry.java:560)
at com.jme3.util.clone.Cloner.clone(Cloner.java:255)
at com.jme3.util.clone.Cloner.clone(Cloner.java:160)
at com.jme3.scene.Spatial.clone(Spatial.java:1360)
at com.jme3.scene.Geometry.clone(Geometry.java:496)
at com.jme3.scene.Geometry.clone(Geometry.java:537)
at com.jme3.scene.Geometry.clone(Geometry.java:62)
at com.jme3.asset.CloneableAssetProcessor.createClone(CloneableAssetProcessor.java:48)
at com.jme3.asset.DesktopAssetManager.registerAndCloneSmartAsset(DesktopAssetManager.java:317)
at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:379)
at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:416)
at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:420)
at mygame.Main.load(Main.java:85)
at mygame.Main.simpleInitApp(Main.java:57)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:220)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:130)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:211)
at java.lang.Thread.run(Thread.java:745)