[Solved] Loading models with the Assimp binding

I’ve been working on implementing the Assimp library into my code, and I’ve run into a problem and am unsure if I’m going to have to find another library or if I’m just making a simple mistake.

When I load OBJ files (Assimp won’t load FBX, 3DSmax, or Maya files, citing invalid formats or outdated versions) into AIScene instances with Assimp, the textures are nowhere to be found.

scene.mNumTextures() = 0
Assimp.aiGetMaterialTextureCount(material, Assimp.aiTextureType_DIFFUSE) = 0
Assimp.aiGetMaterialTextureCount(material, Assimp.aiTextureType_NONE) = 0

I load my AIScene instance with:

ByteBuffer file = Utils.read(asset.toInputStream());
		int flags = Assimp.aiProcess_Triangulate | Assimp.aiProcess_GenNormals | Assimp.aiProcess_ImproveCacheLocality
				| Assimp.aiProcess_SortByPType | Assimp.aiProcess_OptimizeMeshes | Assimp.aiProcess_OptimizeGraph
				| Assimp.aiProcess_CalcTangentSpace | Assimp.aiProcess_TransformUVCoords | Assimp.aiProcess_GenUVCoords
				| Assimp.aiProcess_JoinIdenticalVertices | Assimp.aiProcess_FlipUVs;
		AIScene scene = Assimp.aiImportFileFromMemory(file, flags, "");

Any thoughts or ideas would be appreciated.

I just read that OBJ should not be imported from memory, so I will try to import correctly and then update my post.

Nevermind, I solved my problem: I had to use another import method.

		int flags = Assimp.aiProcess_Triangulate | Assimp.aiProcess_GenNormals | Assimp.aiProcess_ImproveCacheLocality
				| Assimp.aiProcess_SortByPType | Assimp.aiProcess_OptimizeMeshes | Assimp.aiProcess_OptimizeGraph
				| Assimp.aiProcess_CalcTangentSpace | Assimp.aiProcess_TransformUVCoords | Assimp.aiProcess_GenUVCoords
				| Assimp.aiProcess_JoinIdenticalVertices | Assimp.aiProcess_FlipUVs;
		AIScene scene = Assimp.aiImportFileEx(asset.getPath(), flags, null);

Have you found a working way to load model files from within the jar file?

@DesertCookie

Assimp’s aiImportFile can take a ByteBuffer input. Surely you could read a file in your jar (as a URL) to a ByteBuffer and pass it in?

The correct way to do it is to use aiImportFileEx and pass an AIFileIO that creates the appropriate AIFile instances. The callbacks in AIFile can be implemented however you wish, including reading everything from in-memory buffers or even streaming data from a jar file. If the root file references other files which are also contained in the archive, it will work without extracting everything to disk.

An advice if you choose this solution: log every callback invocation to get a feel of how it works, what you’re supposed to do in each callback and avoid unnecessarily reading the same data again and again. You will probably need some kind of temporary cache for each aiImportFileEx call. A simple (non-streaming) implementation to get you started is available in lwjgl3-demos.

I tried that but it always resulted in weird artefacts when rendering the meshes; reading it directly from a file works flawlessly. I haven’t checked if the indices are scrambled or what exactly about the imported data is wrong when using the ByteBuffer read from an InputStream as a source.

I’m trying to get into them (had found your answers on the lwjgl-forums after posting here). So far I’ve only been looking at the AMD Tootle-examples; your link helped clarify a few things that werent clear to me from those demos.