jkvargas / russimp

Assimp bindings for Rust
Other
84 stars 27 forks source link

Embedded textures not working #27

Closed FredrikNoren closed 1 year ago

FredrikNoren commented 1 year ago

Hi,

Great library, but I think I've found a bug; when trying to import a fairly standard Mixamo character, I don't see any embedded textures in the data, even though I know it's available in the model file. I've attached an example file with this problem.

Vanguard By T. Choonyung 7.4.fbx.zip

jkvargas commented 1 year ago

I will take a look as soon as I can, mate =)

jkvargas commented 1 year ago

So, checking your file seems that the textures are pointing to a location "../../../../home/app/mixamo-mini/tmp/skins_960af4bb-c10a-4b61-9029-e02500b12e83.fbm/vanguard_diffuse1.png"

FredrikNoren commented 1 year ago

@jkvargas Hm but it definitely contains embedded textures, I can open it in blender and see the textures (I'm not the creator of the model so I don't even have access to the original textures). Or if I open it here I also see the textures: https://3dviewer.net/

jkvargas commented 1 year ago

I will work on a fix, will update it as soon as it is done =)

FredrikNoren commented 1 year ago

@jkvargas Awesome:)

jkvargas commented 1 year ago

hey mate, I am releasing 2.0 with the fix for embedded textures and some changes on the material and texture structures. would you mind to check if that fixes your issue? :)

FredrikNoren commented 1 year ago

@jkvargas Awesome! I'm out traveling right now but I'll try this when I'm back again after new years :)

FredrikNoren commented 1 year ago

@jkvargas Hm so it seems like all Textures have a non-optional data field in the latest version, how do I work with non embedded textures now? 😅

jkvargas commented 1 year ago

Yes, I believe you can get the filenames from the material properties. If you take a look on this test on material.rs "filenames_available_for_textures" its loading a model which does not have embedded textures,

your property will have key = "$tex.file", data is going to be a string and semantic is going to be the texture type.

jkvargas commented 1 year ago

Hey mate, Hows your project going? Were you able to use the material properties for the non embedded textures? =)

FredrikNoren commented 1 year ago

@jkvargas Hey, well yeah I think I can make it work with that, I just need to spend some time with figuring out what the different properties are etc. so other things got in between :) In general, for me it would be great if this maps the assimp api as closely as possible; from their docs it seems like the GetTexture functions is just a helper for getting all textures (embedded and not). Otherwise I'll see if I can make it work through the raw properties this week though (just need to find some models with and without those props etc.)

jkvargas commented 1 year ago

I will double check as soon as I get home what does it do. The model which does not have textures embedded that I am using on the test "filenames_available_for_textures" does not bring any texture on scene->mTextures which is the base assimp type.

jkvargas commented 1 year ago

hey bud, so I did check the source,

aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial *mat,
        aiTextureType type,
        unsigned int index,
        C_STRUCT aiString *path,
        aiTextureMapping *_mapping /*= nullptr*/,
        unsigned int *uvindex /*= nullptr*/,
        ai_real *blend /*= nullptr*/,
        aiTextureOp *op /*= nullptr*/,
        aiTextureMapMode *mapmode /*= nullptr*/,
        unsigned int *flags /*= nullptr*/
) {
    ai_assert(nullptr != mat);
    ai_assert(nullptr != path);

    // Get the path to the texture
    if (AI_SUCCESS != aiGetMaterialString(mat, AI_MATKEY_TEXTURE(type, index), path)) {
        return AI_FAILURE;
    }

    // Determine mapping type
    int mapping_ = static_cast<int>(aiTextureMapping_UV);
    aiGetMaterialInteger(mat, AI_MATKEY_MAPPING(type, index), &mapping_);
    aiTextureMapping mapping = static_cast<aiTextureMapping>(mapping_);
    if (_mapping)
        *_mapping = mapping;

    // Get UV index
    if (aiTextureMapping_UV == mapping && uvindex) {
        aiGetMaterialInteger(mat, AI_MATKEY_UVWSRC(type, index), (int *)uvindex);
    }
    // Get blend factor
    if (blend) {
        aiGetMaterialFloat(mat, AI_MATKEY_TEXBLEND(type, index), blend);
    }
    // Get texture operation
    if (op) {
        aiGetMaterialInteger(mat, AI_MATKEY_TEXOP(type, index), (int *)op);
    }
    // Get texture mapping modes
    if (mapmode) {
        aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_U(type, index), (int *)&mapmode[0]);
        aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_V(type, index), (int *)&mapmode[1]);
    }
    // Get texture flags
    if (flags) {
        aiGetMaterialInteger(mat, AI_MATKEY_TEXFLAGS(type, index), (int *)flags);
    }

    return AI_SUCCESS;
}

so, basically its a helper method which goes into the material properties and get its contents.

path of the material is mapped to "$tex.file", then you have some other stuff like mapmode mapped to "$tex.mapmodeu" and "$tex.mapmodev" =)

FredrikNoren commented 1 year ago

@jkvargas Ah ok awesome, thanks! :)