jMonkeyEngine / jmonkeyengine

A complete 3-D game development suite written in Java.
http://jmonkeyengine.org
BSD 3-Clause "New" or "Revised" License
3.83k stars 1.12k forks source link

ClassCastException trying to load a MTL material #1174

Open devent opened 5 years ago

devent commented 5 years ago

Another ClassCastException. Code:

        this.box = assetManager.loadModel("assets/models/tiles/box-1.obj");
        Material mat1 = assetManager.loadMaterial("assets/materials/tiles/loam/loam-1-1.mtl")
        return box

It finds all objects and loads the texture. DesktopAssetManager#loadLocatedAsset returns a MaterialList. The obj = proc.postProcess(key, obj); returns the same MaterialList. See

public class CloneableAssetProcessor implements AssetProcessor {

    public Object postProcess(AssetKey key, Object obj) {
        return obj;
    }

Then cache.addToCache(key, (T) obj) is called with cache being WeakRefCloneAssetCache and obj being MaterialList. And then here we get the CCEx CloneableSmartAsset asset = (CloneableSmartAsset) obj because a MaterialList is not a CloneableSmartAsset.

    public <T> void addToCache(AssetKey<T> originalKey, T obj) {
        // Make room for new asset
        removeCollectedAssets();

        CloneableSmartAsset asset = (CloneableSmartAsset) obj;

Error:

java.lang.ClassCastException: class com.jme3.material.MaterialList cannot be cast to class com.jme3.asset.CloneableSmartAsset (com.jme3.material.MaterialList and com.jme3.asset.CloneableSmartAsset are in unnamed module of loader 'app')
    at com.jme3.asset.cache.WeakRefCloneAssetCache.addToCache(WeakRefCloneAssetCache.java:126)
    at com.jme3.asset.DesktopAssetManager.loadLocatedAsset(DesktopAssetManager.java:281)
    at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:373)
    at com.jme3.asset.DesktopAssetManager.loadMaterial(DesktopAssetManager.java:394)

Version: 3.2.4-stable

devent commented 5 years ago

I familiarized myself with JMonkeyEngine for the last couple of weeks and I don't think that a MaterialList is used anywhere else.

Maybe we should just split the MaterialList into Material and load them separately?

Maybe you will elevate a MaterialList to be loaded by the asset manager? Something like assetManager.loadMaterialList() and Geometry#setMaterialList().