Search in sources :

Example 1 with AssetLoadException

use of com.jme3.asset.AssetLoadException in project jmonkeyengine by jMonkeyEngine.

the class SceneWithAnimationLoader method load.

@Override
public Object load(AssetInfo assetInfo) throws IOException {
    AssetKey<?> key = assetInfo.getKey();
    if (!(key instanceof ModelKey))
        throw new AssetLoadException("Invalid asset key");
    InputStream stream = assetInfo.openStream();
    Scanner scanner = new Scanner(stream);
    AnimationList animList = new AnimationList();
    String modelName = null;
    try {
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            if (line.startsWith("#"))
                continue;
            if (modelName == null) {
                modelName = line;
                continue;
            }
            String[] split = split(line);
            if (split.length < 3)
                throw new IOException("Unparseable string \"" + line + "\"");
            int start;
            int end;
            try {
                start = Integer.parseInt(split[0]);
                end = Integer.parseInt(split[1]);
            } catch (NumberFormatException e) {
                throw new IOException("Unparseable string \"" + line + "\"", e);
            }
            animList.add(split[2], split.length > 3 ? split[3] : null, start, end);
        }
    } finally {
        scanner.close();
        stream.close();
    }
    return assetInfo.getManager().loadAsset(new SceneKey(key.getFolder() + modelName, animList));
}
Also used : Scanner(java.util.Scanner) ModelKey(com.jme3.asset.ModelKey) InputStream(java.io.InputStream) IOException(java.io.IOException) AssetLoadException(com.jme3.asset.AssetLoadException)

Example 2 with AssetLoadException

use of com.jme3.asset.AssetLoadException in project jmonkeyengine by jMonkeyEngine.

the class TextureHelper method loadImageFromFile.

/**
     * This method loads the textre from outside the blend file using the
     * AssetManager that the blend file was loaded with. It returns a texture
     * with a full assetKey that references the original texture so it later
     * doesn't need to ba packed when the model data is serialized. It searches
     * the AssetManager for the full path if the model file is a relative path
     * and will attempt to truncate the path if it is an absolute file path
     * until the path can be found in the AssetManager. If the texture can not
     * be found, it will issue a load attempt for the initial path anyway so the
     * failed load can be reported by the AssetManagers callback methods for
     * failed assets.
     * 
     * @param name
     *            the path to the image
     * @param imaflag
     *            the image flag
     * @param blenderContext
     *            the blender context
     * @return the loaded image or null if the image cannot be found
     */
protected Texture loadImageFromFile(String name, int imaflag, BlenderContext blenderContext) {
    if (!name.contains(".")) {
        // no extension means not a valid image
        return null;
    }
    // decide if the mipmaps will be generated
    boolean generateMipmaps = false;
    switch(blenderContext.getBlenderKey().getMipmapGenerationMethod()) {
        case ALWAYS_GENERATE:
            generateMipmaps = true;
            break;
        case NEVER_GENERATE:
            break;
        case GENERATE_WHEN_NEEDED:
            generateMipmaps = (imaflag & 0x04) != 0;
            break;
        default:
            throw new IllegalStateException("Unknown mipmap generation method: " + blenderContext.getBlenderKey().getMipmapGenerationMethod());
    }
    AssetManager assetManager = blenderContext.getAssetManager();
    name = name.replace('\\', '/');
    Texture result = null;
    if (name.startsWith("//")) {
        // This is a relative path, so try to find it relative to the .blend file
        String relativePath = name.substring(2);
        // Augument the path with blender key path
        BlenderKey blenderKey = blenderContext.getBlenderKey();
        int idx = blenderKey.getName().lastIndexOf('/');
        String blenderAssetFolder = blenderKey.getName().substring(0, idx != -1 ? idx : 0);
        String absoluteName = blenderAssetFolder + '/' + relativePath;
        // Directly try to load texture so AssetManager can report missing textures
        try {
            TextureKey key = new TextureKey(absoluteName);
            key.setFlipY(true);
            key.setGenerateMips(generateMipmaps);
            result = assetManager.loadTexture(key);
            result.setKey(key);
        } catch (AssetNotFoundException | AssetLoadException e) {
            LOGGER.fine(e.getLocalizedMessage());
        }
    } else {
        // This is a full path, try to truncate it until the file can be found
        // this works as the assetManager root is most probably a part of the
        // image path. E.g. AssetManager has a locator at c:/Files/ and the
        // texture path is c:/Files/Textures/Models/Image.jpg.
        // For this we create a list with every possible full path name from
        // the asset name to the root. Image.jpg, Models/Image.jpg,
        // Textures/Models/Image.jpg (bingo) etc.
        List<String> assetNames = new ArrayList<String>();
        String[] paths = name.split("\\/");
        // the asset name
        StringBuilder sb = new StringBuilder(paths[paths.length - 1]);
        assetNames.add(paths[paths.length - 1]);
        for (int i = paths.length - 2; i >= 0; --i) {
            sb.insert(0, '/');
            sb.insert(0, paths[i]);
            assetNames.add(0, sb.toString());
        }
        // Now try to locate the asset
        for (String assetName : assetNames) {
            try {
                TextureKey key = new TextureKey(assetName);
                key.setFlipY(true);
                key.setGenerateMips(generateMipmaps);
                AssetInfo info = assetManager.locateAsset(key);
                if (info != null) {
                    Texture texture = assetManager.loadTexture(key);
                    result = texture;
                    // Set key explicitly here if other ways fail
                    texture.setKey(key);
                    // If texture is found return it;
                    return result;
                }
            } catch (AssetNotFoundException | AssetLoadException e) {
                LOGGER.fine(e.getLocalizedMessage());
            }
        }
        // the missing asset to subsystems.
        try {
            TextureKey key = new TextureKey(name);
            assetManager.loadTexture(key);
        } catch (AssetNotFoundException | AssetLoadException e) {
            LOGGER.fine(e.getLocalizedMessage());
        }
    }
    return result;
}
Also used : AssetManager(com.jme3.asset.AssetManager) ArrayList(java.util.ArrayList) AssetNotFoundException(com.jme3.asset.AssetNotFoundException) AssetInfo(com.jme3.asset.AssetInfo) Texture(com.jme3.texture.Texture) AssetLoadException(com.jme3.asset.AssetLoadException) GeneratedTextureKey(com.jme3.asset.GeneratedTextureKey) TextureKey(com.jme3.asset.TextureKey) BlenderKey(com.jme3.asset.BlenderKey)

Example 3 with AssetLoadException

use of com.jme3.asset.AssetLoadException in project jmonkeyengine by jMonkeyEngine.

the class FbxMesh method createGeometries.

private List<Geometry> createGeometries() throws IOException {
    Mesh mesh = new Mesh();
    mesh.setMode(Mode.Triangles);
    // Moreover quads should be triangulated (this increases number of vertices)
    if (indices != null) {
        iCount = indices.length;
        srcVertexCount = vertices.length / 3;
        // Indices contains negative numbers to define polygon last index
        // Check indices strides to be sure we have triangles or quads
        vCount = 0;
        // Count number of vertices to be produced
        int polyVertCount = 0;
        for (int i = 0; i < iCount; ++i) {
            int index = indices[i];
            polyVertCount++;
            if (index < 0) {
                if (polyVertCount == 3) {
                    // A triangle
                    vCount += 3;
                } else if (polyVertCount == 4) {
                    // A quad produce two triangles
                    vCount += 6;
                } else {
                    throw new AssetLoadException("Unsupported PolygonVertexIndex stride");
                }
                polyVertCount = 0;
            }
        }
        // Unroll index array into vertex mapping
        vertexMap = new ArrayList<>(vCount);
        indexMap = new ArrayList<>(vCount);
        polyVertCount = 0;
        for (int i = 0; i < iCount; ++i) {
            int index = indices[i];
            polyVertCount++;
            if (index < 0) {
                int lastIndex = -(index + 1);
                if (polyVertCount == 3) {
                    vertexMap.add(indices[i - 2]);
                    vertexMap.add(indices[i - 1]);
                    vertexMap.add(lastIndex);
                    indexMap.add(i - 2);
                    indexMap.add(i - 1);
                    indexMap.add(i - 0);
                } else if (polyVertCount == 4) {
                    vertexMap.add(indices[i - 3]);
                    vertexMap.add(indices[i - 2]);
                    vertexMap.add(indices[i - 1]);
                    vertexMap.add(indices[i - 3]);
                    vertexMap.add(indices[i - 1]);
                    vertexMap.add(lastIndex);
                    indexMap.add(i - 3);
                    indexMap.add(i - 2);
                    indexMap.add(i - 1);
                    indexMap.add(i - 3);
                    indexMap.add(i - 1);
                    indexMap.add(i - 0);
                }
                polyVertCount = 0;
            }
        }
        // Build reverse vertex mapping
        reverseVertexMap = new ArrayList<>(srcVertexCount);
        for (int i = 0; i < srcVertexCount; ++i) reverseVertexMap.add(new ArrayList<Integer>());
        for (int i = 0; i < vCount; ++i) {
            int index = vertexMap.get(i);
            reverseVertexMap.get(index).add(i);
        }
    } else {
        // Stub for no vertex indexing (direct mapping)
        iCount = vCount = srcVertexCount;
        vertexMap = new ArrayList<>(vCount);
        indexMap = new ArrayList<>(vCount);
        reverseVertexMap = new ArrayList<>(vCount);
        for (int i = 0; i < vCount; ++i) {
            vertexMap.set(i, i);
            indexMap.set(i, i);
            List<Integer> l = new ArrayList<Integer>(1);
            l.add(i);
            reverseVertexMap.add(l);
        }
    }
    if (vertices != null) {
        // Unroll vertices data array
        FloatBuffer posBuf = BufferUtils.createFloatBuffer(vCount * 3);
        mesh.setBuffer(VertexBuffer.Type.Position, 3, posBuf);
        int srcCount = vertices.length / 3;
        for (int i = 0; i < vCount; ++i) {
            int index = vertexMap.get(i);
            if (index > srcCount)
                throw new AssetLoadException("Invalid vertex mapping. Unexpected lookup vertex " + index + " from " + srcCount);
            // XXX Why we should scale by unit size?
            float x = (float) vertices[3 * index + 0] / scene.unitSize * scene.xAxis;
            float y = (float) vertices[3 * index + 1] / scene.unitSize * scene.yAxis;
            float z = (float) vertices[3 * index + 2] / scene.unitSize * scene.zAxis;
            posBuf.put(x).put(y).put(z);
        }
    }
    if (normals != null) {
        // Unroll normals data array
        FloatBuffer normBuf = BufferUtils.createFloatBuffer(vCount * 3);
        mesh.setBuffer(VertexBuffer.Type.Normal, 3, normBuf);
        List<Integer> mapping = null;
        if (normalsMapping.equals("ByVertice"))
            mapping = vertexMap;
        else if (normalsMapping.equals("ByPolygonVertex"))
            mapping = indexMap;
        else
            throw new IOException("Unknown normals mapping type: " + normalsMapping);
        int srcCount = normals.length / 3;
        for (int i = 0; i < vCount; ++i) {
            int index = mapping.get(i);
            if (index > srcCount)
                throw new AssetLoadException("Invalid normal mapping. Unexpected lookup normal " + index + " from " + srcCount);
            float x = (float) normals[3 * index + 0] * scene.xAxis;
            float y = (float) normals[3 * index + 1] * scene.yAxis;
            float z = (float) normals[3 * index + 2] * scene.zAxis;
            normBuf.put(x).put(y).put(z);
        }
    }
    if (tangents != null) {
        // Unroll normals data array
        FloatBuffer tanBuf = BufferUtils.createFloatBuffer(vCount * 4);
        mesh.setBuffer(VertexBuffer.Type.Tangent, 4, tanBuf);
        List<Integer> mapping = null;
        if (tangentsMapping.equals("ByVertice"))
            mapping = vertexMap;
        else if (tangentsMapping.equals("ByPolygonVertex"))
            mapping = indexMap;
        else
            throw new IOException("Unknown tangents mapping type: " + tangentsMapping);
        int srcCount = tangents.length / 3;
        for (int i = 0; i < vCount; ++i) {
            int index = mapping.get(i);
            if (index > srcCount)
                throw new AssetLoadException("Invalid tangent mapping. Unexpected lookup tangent " + index + " from " + srcCount);
            float x = (float) tangents[3 * index + 0] * scene.xAxis;
            float y = (float) tangents[3 * index + 1] * scene.yAxis;
            float z = (float) tangents[3 * index + 2] * scene.zAxis;
            tanBuf.put(x).put(y).put(z).put(-1.0f);
        }
    }
    if (binormals != null) {
        // Unroll normals data array
        FloatBuffer binormBuf = BufferUtils.createFloatBuffer(vCount * 3);
        mesh.setBuffer(VertexBuffer.Type.Binormal, 3, binormBuf);
        List<Integer> mapping = null;
        if (binormalsMapping.equals("ByVertice"))
            mapping = vertexMap;
        else if (binormalsMapping.equals("ByPolygonVertex"))
            mapping = indexMap;
        else
            throw new IOException("Unknown binormals mapping type: " + binormalsMapping);
        int srcCount = binormals.length / 3;
        for (int i = 0; i < vCount; ++i) {
            int index = mapping.get(i);
            if (index > srcCount)
                throw new AssetLoadException("Invalid binormal mapping. Unexpected lookup binormal " + index + " from " + srcCount);
            float x = (float) binormals[3 * index + 0] * scene.xAxis;
            float y = (float) binormals[3 * index + 1] * scene.yAxis;
            float z = (float) binormals[3 * index + 2] * scene.zAxis;
            binormBuf.put(x).put(y).put(z);
        }
    }
    for (int uvLayer = 0; uvLayer < uvs.size(); ++uvLayer) {
        double[] uv = uvs.get(uvLayer);
        int[] uvIndex = uvIndexes.size() > uvLayer ? uvIndexes.get(uvLayer) : null;
        List<Integer> unIndexMap = vertexMap;
        if (uvIndex != null) {
            int uvIndexSrcCount = uvIndex.length;
            if (uvIndexSrcCount != iCount)
                throw new AssetLoadException("Invalid number of texcoord index data " + uvIndexSrcCount + " expected " + iCount);
            // Unroll UV index array
            unIndexMap = new ArrayList<>(vCount);
            int polyVertCount = 0;
            for (int i = 0; i < iCount; ++i) {
                int index = indices[i];
                polyVertCount++;
                if (index < 0) {
                    if (polyVertCount == 3) {
                        unIndexMap.add(uvIndex[i - 2]);
                        unIndexMap.add(uvIndex[i - 1]);
                        unIndexMap.add(uvIndex[i - 0]);
                    } else if (polyVertCount == 4) {
                        unIndexMap.add(uvIndex[i - 3]);
                        unIndexMap.add(uvIndex[i - 2]);
                        unIndexMap.add(uvIndex[i - 1]);
                        unIndexMap.add(uvIndex[i - 3]);
                        unIndexMap.add(uvIndex[i - 1]);
                        unIndexMap.add(uvIndex[i - 0]);
                    }
                    polyVertCount = 0;
                }
            }
        }
        // Unroll UV data array
        FloatBuffer tcBuf = BufferUtils.createFloatBuffer(vCount * 2);
        VertexBuffer.Type type = VertexBuffer.Type.TexCoord;
        switch(uvLayer) {
            case 1:
                type = VertexBuffer.Type.TexCoord2;
                break;
            case 2:
                type = VertexBuffer.Type.TexCoord3;
                break;
            case 3:
                type = VertexBuffer.Type.TexCoord4;
                break;
            case 4:
                type = VertexBuffer.Type.TexCoord5;
                break;
            case 5:
                type = VertexBuffer.Type.TexCoord6;
                break;
            case 6:
                type = VertexBuffer.Type.TexCoord7;
                break;
            case 7:
                type = VertexBuffer.Type.TexCoord8;
                break;
        }
        mesh.setBuffer(type, 2, tcBuf);
        int srcCount = uv.length / 2;
        for (int i = 0; i < vCount; ++i) {
            int index = unIndexMap.get(i);
            if (index > srcCount)
                throw new AssetLoadException("Invalid texcoord mapping. Unexpected lookup texcoord " + index + " from " + srcCount);
            float u = (index >= 0) ? (float) uv[2 * index + 0] : 0;
            float v = (index >= 0) ? (float) uv[2 * index + 1] : 0;
            tcBuf.put(u).put(v);
        }
    }
    List<Geometry> geometries = new ArrayList<Geometry>();
    if (materialsReference.equals("IndexToDirect") && materialsMapping.equals("ByPolygon")) {
        IntMap<List<Integer>> indexBuffers = new IntMap<>();
        for (int polygon = 0; polygon < materials.length; ++polygon) {
            int material = materials[polygon];
            List<Integer> list = indexBuffers.get(material);
            if (list == null) {
                list = new ArrayList<>();
                indexBuffers.put(material, list);
            }
            list.add(polygon * 3 + 0);
            list.add(polygon * 3 + 1);
            list.add(polygon * 3 + 2);
        }
        Iterator<Entry<List<Integer>>> iterator = indexBuffers.iterator();
        while (iterator.hasNext()) {
            Entry<List<Integer>> e = iterator.next();
            int materialId = e.getKey();
            List<Integer> indexes = e.getValue();
            Mesh newMesh = mesh.clone();
            newMesh.setBuffer(VertexBuffer.Type.Index, 3, toArray(indexes.toArray(new Integer[indexes.size()])));
            newMesh.setStatic();
            newMesh.updateBound();
            newMesh.updateCounts();
            Geometry geom = new Geometry();
            geom.setMesh(newMesh);
            geometries.add(geom);
            geom.setUserData("FBXMaterial", materialId);
        }
    } else {
        mesh.setStatic();
        mesh.updateBound();
        mesh.updateCounts();
        Geometry geom = new Geometry();
        geom.setMesh(mesh);
        geometries.add(geom);
    }
    return geometries;
}
Also used : VertexBuffer(com.jme3.scene.VertexBuffer) ArrayList(java.util.ArrayList) Mesh(com.jme3.scene.Mesh) FloatBuffer(java.nio.FloatBuffer) IOException(java.io.IOException) AssetLoadException(com.jme3.asset.AssetLoadException) Geometry(com.jme3.scene.Geometry) Entry(com.jme3.util.IntMap.Entry) IntMap(com.jme3.util.IntMap) ArrayList(java.util.ArrayList) List(java.util.List)

Example 4 with AssetLoadException

use of com.jme3.asset.AssetLoadException in project jmonkeyengine by jMonkeyEngine.

the class FbxImage method toJmeObject.

@Override
protected Object toJmeObject() {
    Image image = null;
    String fileName = null;
    String relativeFilePathJme;
    if (filePath != null) {
        fileName = getFileName(filePath);
    } else if (relativeFilePath != null) {
        fileName = getFileName(relativeFilePath);
    }
    if (fileName != null) {
        try {
            // Try to load filename relative to FBX folder
            key = new TextureKey(sceneFolderName + fileName);
            key.setGenerateMips(true);
            image = loadImageSafe(assetManager, key);
            // Try to load relative filepath relative to FBX folder
            if (image == null && relativeFilePath != null) {
                // Convert Windows paths to jME3 paths
                relativeFilePathJme = relativeFilePath.replace('\\', '/');
                key = new TextureKey(sceneFolderName + relativeFilePathJme);
                key.setGenerateMips(true);
                image = loadImageSafe(assetManager, key);
            }
            // Try to load embedded image
            if (image == null && content != null && content.length > 0) {
                key = new TextureKey(fileName);
                key.setGenerateMips(true);
                InputStream is = new ByteArrayInputStream(content);
                image = assetManager.loadAssetFromStream(key, is).getImage();
                // NOTE: embedded texture doesn't exist in the asset manager,
                //       so the texture key must not be saved.
                key = null;
            }
        } catch (AssetLoadException ex) {
            logger.log(Level.WARNING, "Error while attempting to load texture {0}:\n{1}", new Object[] { name, ex.toString() });
        }
    }
    if (image == null) {
        logger.log(Level.WARNING, "Cannot locate {0} for texture {1}", new Object[] { fileName, name });
        image = PlaceholderAssets.getPlaceholderImage(assetManager);
    }
    return image;
}
Also used : TextureKey(com.jme3.asset.TextureKey) ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) FbxObject(com.jme3.scene.plugins.fbx.obj.FbxObject) Image(com.jme3.texture.Image) AssetLoadException(com.jme3.asset.AssetLoadException)

Example 5 with AssetLoadException

use of com.jme3.asset.AssetLoadException in project jmonkeyengine by jMonkeyEngine.

the class ShaderNodeDefinitionLoader method load.

@Override
public Object load(AssetInfo assetInfo) throws IOException {
    AssetKey k = assetInfo.getKey();
    if (!(k instanceof ShaderNodeDefinitionKey)) {
        throw new IOException("ShaderNodeDefinition file must be loaded via ShaderNodeDefinitionKey");
    }
    ShaderNodeDefinitionKey key = (ShaderNodeDefinitionKey) k;
    loaderDelegate = new ShaderNodeLoaderDelegate();
    InputStream in = assetInfo.openStream();
    List<Statement> roots = BlockLanguageParser.parse(in);
    if (roots.size() == 2) {
        Statement exception = roots.get(0);
        String line = exception.getLine();
        if (line.startsWith("Exception")) {
            throw new AssetLoadException(line.substring("Exception ".length()));
        } else {
            throw new MatParseException("In multiroot shader node definition, expected first statement to be 'Exception'", exception);
        }
    } else if (roots.size() != 1) {
        throw new MatParseException("Too many roots in J3SN file", roots.get(0));
    }
    return loaderDelegate.readNodesDefinitions(roots.get(0).getContents(), key);
}
Also used : AssetKey(com.jme3.asset.AssetKey) ShaderNodeDefinitionKey(com.jme3.asset.ShaderNodeDefinitionKey) InputStream(java.io.InputStream) Statement(com.jme3.util.blockparser.Statement) IOException(java.io.IOException) AssetLoadException(com.jme3.asset.AssetLoadException)

Aggregations

AssetLoadException (com.jme3.asset.AssetLoadException)10 IOException (java.io.IOException)6 InputStream (java.io.InputStream)6 TextureKey (com.jme3.asset.TextureKey)3 ModelKey (com.jme3.asset.ModelKey)2 VertexBuffer (com.jme3.scene.VertexBuffer)2 Image (com.jme3.texture.Image)2 Statement (com.jme3.util.blockparser.Statement)2 FloatBuffer (java.nio.FloatBuffer)2 ArrayList (java.util.ArrayList)2 AssetInfo (com.jme3.asset.AssetInfo)1 AssetKey (com.jme3.asset.AssetKey)1 AssetManager (com.jme3.asset.AssetManager)1 AssetNotFoundException (com.jme3.asset.AssetNotFoundException)1 BlenderKey (com.jme3.asset.BlenderKey)1 GeneratedTextureKey (com.jme3.asset.GeneratedTextureKey)1 ShaderNodeDefinitionKey (com.jme3.asset.ShaderNodeDefinitionKey)1 Geometry (com.jme3.scene.Geometry)1 Mesh (com.jme3.scene.Mesh)1 Spatial (com.jme3.scene.Spatial)1