Assimp importing problem
mudlee opened this issue · 5 comments
I try to import obj files from MagicaVoxel and from Blender as well. Both have materials.
You can check those here: https://drive.google.com/open?id=1E6g-rqI3QPTFfMnMi90CPjKzcxx9tyYp
What I see when importing from blender:
- The importer always says that the diffuse color is 0.6-0.6-0.6 which is simply not true
- It has two materials
What I see when importing from MagicaVoxel:
- The importer always says that the diffuse color is 0.6-0.6-0.6 which is simply not true
- It has two materials
However, both have one material and not that diffuse color. For fun, I tried to export the monkey to FBX, where the diffuse color looks OK.
What can be the problem? Code is the same you wrote.
Sure, I'll try to help.
Just one question, when you import it from blender it also says that diffuse is 0.6 ?
Only if I use obj when exporting from blender or use MagicaVoxel.
So three cases I tried:
- obj from MagicaVoxel -> failed
- obj from blender -> failed
- fbx from blender -> colors look ok
All of them work in Unity.
Here is the code and the output for the blender-obj: https://gist.github.com/mudlee/25e734d77c1cb2542ce772e77eb3e18e
Ok, here are my findings:
- Don't get confused by the number of materials. It seems that assimp allways adds an extra material.
- This is not an issue if, when you are constructing the mesh, you use the material which occupies the index stated by aiMesh.mMaterialIndex.
- That extra material always has 0.6-0.6-0.6 for the diffuse component.
- With one of the obj files (tower.obj, the one created with MagicaVoxel), assimp was returning a wrong value for the index of the material associated to the unique mesh. It was returning 0 instead of 1.
- If i move the material declarations of the obj file at the begining of the file (before the group is defined), assimp returns the correct index. That is:
`mtllib
tower.mtl
usemtl palette
g tower
`
If I have more time I will check the wavefront material spec, but the code is ok.
OK, it looks like OK, as I moved the mtl declaration before the model group. Also, I use the mMaterialIndex and works like the charm. I recommend to update with these infos with the book :)
Oh, and one more. If you package your game into a jar, you will not be able to use aiImportFile as its not available in the jar. According to Spaasi from the lwjgl forum, you have to options:
- use aiImportFileEx
- extract files to the disk
I choose the second one, here is the code (not well polished):
`
URL res = StaticMeshLoader.class.getResource(resourcePath);
if (res.toString().startsWith("jar:")) {
objPath = unpackModelsFromJar(resourcePath);
}
WHERE
private static String unpackModelsFromJar(String resourcePath) {
String origName = resourcePath.substring(resourcePath.lastIndexOf("/") + 1).replace(".obj", "");
try {
String tempDir = System.getProperty("java.io.tmpdir");
LOGGER.debug("> Model found in a jar file, extracting files to a temp directory: {}", tempDir);
// OBJ
File objFile = new File(tempDir + origName + ".obj");
objFile.deleteOnExit();
objFile.createNewFile();
InputStream objInput = StaticMeshLoader.class.getResourceAsStream(resourcePath);
Files.write(objFile.toPath(), objInput.readAllBytes());
LOGGER.debug("> File {} extracted", tempDir + origName + ".obj");
// MTL
File mtlFile = new File(tempDir + origName + ".mtl");
mtlFile.deleteOnExit();
mtlFile.createNewFile();
InputStream mtlInput = StaticMeshLoader.class.getResourceAsStream(resourcePath.replace(".obj", ".mtl"));
Files.write(mtlFile.toPath(), mtlInput.readAllBytes());
LOGGER.debug("> File {} extracted", tempDir + origName + ".mtl");
// MTL
File textureFile = new File(tempDir + origName + ".png");
textureFile.deleteOnExit();
textureFile.createNewFile();
InputStream textureInput = StaticMeshLoader.class.getResourceAsStream(resourcePath.replace(".obj", ".png"));
Files.write(textureFile.toPath(), textureInput.readAllBytes());
LOGGER.debug("> File {} extracted", tempDir + origName + ".png");
return objFile.getPath();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
`