Why is it saying material instances cannot be shared when I am not sharing them?

The following exception occurs whenever I uncomment the code below. Any idea how the code could be causing this?

java.lang.UnsupportedOperationException: Material instances cannot be shared when hardware skinning is used. Ensure all models use unique material instances.
subject = (Node)toHighlight;
highlightSpatial = toHighlight.clone(true);
highlightSpatial.setMaterial(null);

highlightSpatial.breadthFirstTraversal(new SceneGraphVisitor() {
	@Override
	public void visit(Spatial spatial) {
		if (spatial.getName().startsWith("highlight")) {
			spatial.removeFromParent();
		} else if (spatial instanceof Geometry) {
			spatial.setMaterial(material.clone());
		}
	}
});
		
highlightSpatial.setName(id);
subject.attachChild(highlightSpatial);

Well, I never did figure out why this was happening, but I realized that I can accomplish what I was trying to accomplish much better using MatParamOverride.

The only way I can think this would happen is if materials were already shared in ‘subject’ before you got to it. Even though you clone(true) to clone materials that will clone all of the unique materials but if two child spatials shared the same material before then they will share the same cloned material after. Your traversal makes sure to reset every material to a new clone so no previously shared materials will be shared after.

There is also the non-zero chance that some material is not getting cloned but you’d have to do more debugging to prove that. I’m not sure which code was commented out when it fails versus other code so I can’t comment for sure. (Debugging example: traverse your subject before and write the System.identityHashCode()s for all of the Geometry.getMaterial()s… then do it again after.)

Or it might be helpful to post the full stack trace for the exception. It’s possible that the message is incorrectly reporting a different kind of problem.

1 Like