Hello,
I’m trying to use DynamicAnimControl and I’m getting this exception when using GLTF models:
java.lang.IllegalArgumentException: The controlled spatial must have a SkinningControl or a SkeletonControl. Make sure the Control is there and not on some other Spatial.
at com.jme3.bullet.animation.DacLinks.createSpatialData(DacLinks.java:771)
at com.jme3.bullet.control.AbstractPhysicsControl.setSpatial(AbstractPhysicsControl.java:405)
at com.jme3.scene.Spatial.addControl(Spatial.java:775)
at com.scenemaxeng.projector.SceneMaxApp$6.run(SceneMaxApp.java:1422)
at com.jme3.app.LegacyApplication$RunnableWrapper.call(LegacyApplication.java:822)
at com.jme3.app.AppTask.invoke(AppTask.java:147)
at com.jme3.app.LegacyApplication.runQueuedTasks(LegacyApplication.java:733)
at com.jme3.app.LegacyApplication.update(LegacyApplication.java:748)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:247)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:197)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:232)
at java.lang.Thread.run(Thread.java:745)
It works fine with J3O model however…
What am I doing wrong? Or does DynamicAnimControl works only with J3O models?
Here is the code which causes the exception:
DynamicAnimControl modelCtl = new DynamicAnimControl();
model.addControl(modelCtl);
modelCtl.setPhysicsSpace(bulletAppState.getPhysicsSpace());
Gltf loader wraps the loaded model inside a parent node I guess, so most probably the SkinningControl (if you are using JME 3.3) or SkeletonControl (if you are using JME 3.2) object should be in the child. So you should find that child and add DynamicAnimControl to that.
Thanks guys. Everything is working!
How hard do you think it is to display all bones in a models with labels of their names for debugging \ educating purpose?
I don’t care much for the hierarchy but rather for selecting main bones for linking…
Do we have such demo in any of our tests?
I’m on my phone, hard to type code. But basically I query the joints and put them in a lemur’s listbox. Once you have the joint names, you can display them however you want.
List joints = control.getArmature().getJointList().stream()
.map(Joint::getName)
.collect(Collectors.toList());
Maybe you can use Heart for this? It’s a utility lib of @sgold. I use it to display armatures.
An easy solution would probably be to add a label with the joint name to the attachmentsnode of the joint. You can even add a BillboardControl to it if needed.
Thanks Stephen, I changed my code to using findSControl. I would like to suggest that for public methods such as this one maybe it will be better to use a little bit more verbose names for example: findSkinningControl