raylib: [models] MTL files fail to load automatically on Android
- I tested it on latest raylib version from master branch
- I checked there is no similar issue already reported
- My code has no errors or misuse of raylib
Issue description
The MTL files linked to an OBJ file fail to load automatically on Android when loading the OBJ file, whereas for the same example, it works on PC.
Android logs:
2023-06-28 15:05:28.324 22364-22505 raylib com.raylib.objmtltest I FILEIO: [suv.obj] Text file loaded successfully
2023-06-28 15:05:28.342 22364-22505 raylib com.raylib.objmtltest I MODEL: [suv.obj] OBJ data loaded successfully: 5 meshes/0 materials
2023-06-28 15:05:28.342 22364-22505 raylib com.raylib.objmtltest I MODEL: No materials, putting all meshes in a default material
2023-06-28 15:05:28.344 22364-22505 raylib com.raylib.objmtltest I VAO: [ID 2] Mesh uploaded successfully to VRAM (GPU)
2023-06-28 15:05:28.344 22364-22505 raylib com.raylib.objmtltest W MATERIAL: [suv.obj] Failed to load material data, default to white material
Desktop logs:
INFO: FILEIO: [suv.obj] Text file loaded successfully
INFO: MODEL: [suv.obj] OBJ data loaded successfully: 5 meshes/8 materials
INFO: MODEL: model has 8 material meshes
INFO: VAO: [ID 2] Mesh uploaded successfully to VRAM (GPU)
INFO: VAO: [ID 3] Mesh uploaded successfully to VRAM (GPU)
INFO: VAO: [ID 4] Mesh uploaded successfully to VRAM (GPU)
INFO: VAO: [ID 5] Mesh uploaded successfully to VRAM (GPU)
INFO: VAO: [ID 6] Mesh uploaded successfully to VRAM (GPU)
INFO: VAO: [ID 7] Mesh uploaded successfully to VRAM (GPU)
INFO: VAO: [ID 8] Mesh uploaded successfully to VRAM (GPU)
INFO: VAO: [ID 9] Mesh uploaded successfully to VRAM (GPU)
Issue Screenshot
Android:
Desktop:
Code Example
Example Android/Desktop (.zip)
#include "raylib.h"
#include "raymath.h"
int main()
{
InitWindow(800, 450, "raylib - OBJ/MTL test");
Camera camera = { };
camera.position = { 10.0f, 10.0f, 10.0f };
camera.target = { 0.0f, 0.0f, 0.0f };
camera.up = { 0.0f, 1.0f, 0.0f };
camera.fovy = 45.0f;
camera.projection = CAMERA_PERSPECTIVE;
Model models = LoadModel("suv.obj");
{
BoundingBox bb = GetModelBoundingBox(models);
Vector3 center = { };
center.x = bb.min.x + (((bb.max.x - bb.min.x)/2));
center.z = bb.min.z + (((bb.max.z - bb.min.z)/2));
Matrix matTranslate = MatrixTranslate(-center.x, 0, -center.z);
models.transform = matTranslate;
}
SetTargetFPS(60);
while (!WindowShouldClose())
{
UpdateCamera(&camera, CAMERA_ORBITAL);
BeginDrawing();
ClearBackground(RAYWHITE);
BeginMode3D(camera);
DrawModel(models, { 0, 0, 0 }, 1.0f, WHITE);
DrawGrid(10, 1.0);
EndMode3D();
EndDrawing();
}
UnloadModel(models);
CloseWindow();
return 0;
}
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 24 (22 by maintainers)
Yes, a new C obj loader library is required with improvements over
tinyobj_loader_c.h
but implementation from scratch requires a considerable amount of work. Requirements:sscanf()
and similar)Creating and maintaining that library requires some work…
Related comment: https://github.com/raysan5/raylib/issues/2219#issuecomment-1004250177
@Bigfoot71
Based on the fact that a
\r
showed up in a filename in the model-loading process, I am unclear how converting all LF to CRLF is going to help with that. It seems to me that you might want to do the opposite and usedos2unix
rather thanunix2dos
.It looks like there is a parsing problem in the model loading code. A sane solution, generally, is to treat all
\r' and
\n` codes as white space and be flexible about treating runs of whitespace as a single whitespace. I assume the “parser” in model loading is more rigid than that. My guesswork only.Runs of the failing program having varying success/failure patterns from one run to the next signals that there may be an uninitialized variable or an over-run value somewhere. This could happen with a pointer misuse too (e.g., using the pointer instead of what it is pointed at, or even vice versa). It might even matter whether
char
is handled as a signed or unsigned smallint
.Final observation. In the distant past, there was a time when
\r
alone was used the same as\n
is in Unix, not in a pair. Also, use of\r
alone can be intentional to overwrite a line in output to astdout
terminal, as when presenting a countdown, or other busy behavior, without scrolling down the screen. That usually works independent of whether\n
is converted to a single LF or a CRLF in the stream to the device. Here, I suppose, it might be important to know whether the compiler used handles\r
properly if at all or whether there is an ill-escaped usage.Hi everyone.
Took a look with the android debugger and it seems like indeed there’s an issue with how
tinyobj_loader
parses that particular obj given in your example @Bigfoot71 . Here’s what has been parsed intinyobj_parse_obj()
So, the resulting filename contains a trailing CR (
\r
) which is in turn given toandroid_fopen
and then to android’sAAssetManager_open
function which seems to fail because of it.Doing quick and dirty removal of this trailing CR loads the file successfully, but app crashes somewhere else which I did not investigate why. Maybe there’s something horribly wrong with that obj file? or the obj loader needs refinement. For now, I do not know.