The previous post concerning min3D raised a lot of interesting questions and comments (thanks to all the visitors for their contribution!) concerning the usage of textures, the export of OBJ and the addition of features such as rotation listeners in min3D. I’ve decided to wrap up all of the comments and emails I’ve received concerning min3D. I hope you can find a solution for your problem, and don’t forget to post a comment if you can’t find the solution for your problem. I will edit and update this page with your input and your question, so don’t hesitate!
Blender and min3D: how to export the OBJ 3D model?
Oh yes, this is the most frequently asked question: how to correctly export OBJ from Blender to min3D. Here is a small tutorial to explain you each step. Some “hacking” is needed, so be sure to know how an OBJ and .mtl files work (not very difficult: http://people.sc.fsu.edu/~jburkardt/data/mtl/mtl.html)
I will be using the latest version of Blender (2.58a) for this tutorial, so be sure to use the same version, otherwise you will get faulty OBJ exporter. Yes this is a real problem, because the previous version of Blender couldn’t export the .mtl file correctly; in fact it was missing, leaving developers to create and edit manually a .mtl or to reconvert and re-import the OBJ over Daz3D.
So here is the start point in Blender, a textured dice (yes, a really basic example 😉 ):
The cube has 6 textures (stored in a file named dice.png). The texture has a size of a power of two (1024×1024). After applying the texture to the dice we will now export it.
Go to File > Export > Wavefront (.obj) and leave the settings as is and export it (e.g. dice.mtl)
Blender will now export the obj and the .mtl file. Please note that the path contained in the .mtl is false and must be manually edited.
Change the file path to the correct usemtl
usemtl dice.png
and of course a small modification in dice.mtl on the map_Kd line:
map_Kd dice.png
And here is the result:
Here are the files:
Since the newest Blender version, the OBJ exporter works as expected and can be used to export OBJ for min3D.
Daz3D and min3D: how to export the OBJ 3D model?
If you prefer to use Daz3D (www.daz3d.com) for creating and generating your 3D models, here are the parameters for the export of OBJ models:
Then you must manually edit the generated .mtl and .obj in order to set the correct paths to the textures.
Help, my texture does not display on the 3D object!!!
This is the most frequently asked question and I must say the most interesting because obviously there are some differences between devices, but let’s start with the simplest solutions to common texture problems:
#1: Check the mtl file
There is a slight problem with the mtl files generated by several 3D softwares: they contain bad characters (ok not bad, but hidden) that might be not correctly parsed such as return carriage/lines (/r /n) and tabulations (/t). The solution is to remove the tabulations at the beginning of each line in the mtl, otherwise the texture won’t load.
#2: Check the path in the mtl file
The mtl file contains in its first line the path to the .png / .jpg. Check if this path is correct.
#3: The NotPowerOfTwo problem with OpenGL on Android devices
This is the weirdest problem, and unfortunately there is not a lot input about this. I’ve never noticed this problem on my Android device (Dell Streak) till the day I’ve got message from users telling me that they couldn’t load textures on their Nexus S.
I first thought something else might be wrong with the paths till I’ve tested it myself: no textures!
But what is the difference between the Dell Streak and the Nexus S? Apparently there is a curious difference between the implementation of OpenGL on these Android devices. In fact some devices have not the support of NotPowerOfTwo textures in OpenGL. Many visitors also faced this problem; apparently the support of NonPowerOfTwo textures is not completely implemented/ not supported in OpenGL in some Android devices (http://code.google.com/p/min3d/issues/detail?id=5&can=1&q=NPOT) and http://stackoverflow.com/questions/5705753/android-opengl-es-loading-a-non-power-of-2-texture, meaning the way OpenGL is implemented in each device might differ. That’s the reason why the Dell Streak shows the textures and the Nexus S not (that is my explanation).
But there is another problem linked to this NotPowerOfTwo problem: min3D loads all the textures into a TextureAtlas (http://code.google.com/p/min3d/source/browse/trunk/src/min3d/parser/AParser.java).
The texture atlas is a sort of big texture composed by each single texture. Min3d will reference internally to this “big texture” and here seems to be a caveat on some Android devices : in fact you must also take care that the whole texture map (TextureAtlas) is a power of two, meaning if you have 4 textures à 512x512px each it will work but if you have 5 textures à 512x512px each it won’t work because 2560 is not a power of two.
Be aware that this is my personal explication to the problem; I couldn’t find any other explanation to this problem especially a list of Android devices supporting the NotPowerOfTwo textures in OpenGL. But in any case you should always use PowerOfTwo textures: they are quicker to load.
The 3D object does not appear!
Solution #1: Check the raw/your_obj path
This is a very common mistake: please check that the path to the OBJ file is correct and contains the full package name (com.yourPackage.). Note that you don’t need to put the extension .obj to the file path.
IParser myParser = Parser.createParser(Parser.Type.OBJ, getResources(),"com.testObj:raw/face_obj",true);
Anyway, the missing file or bad path will lead to a Resource$NotFoundException. That should be a first hint to check if the path to the file is correct:
Solution #2: Check the scale
This sounds stupid, but especially if you are using several programs to generate your 3D object, you should be aware which scale you are using: Blender and DAZ 3D are not using the same scale leading to export sometimes huge 3D models. The best way is to test several scale parameters.
faceObject3D.scale().x = faceObject3D.scale().y = faceObject3D.scale().z = 0.5f;
This is also the case when you are loading an OBJ found on the web and if you don’t know which scale units where used by the exporter.