Assimp aiGetMaterialColor not finding properties

Started by quew8, July 03, 2017, 22:03:40

Previous topic - Next topic

quew8

I've never used Assimp before but decided that since it came so nicely bundled that I might as well - has to be better than my own home brewed collada importer. Now I'm trying to extract the diffuse colour of one of the materials but the function doesn't seem to be finding it and I must admit I'm a little confused since the definition of this function is different to the standard Assimp one (has the extra "type" and "index" parameters).

Some code to demonstrate the problem:
//Get the material
int materialIndex = mesh.mMaterialIndex();
AIMaterial mtl = AIMaterial.create(scene.mMaterials().get(materialIndex));

//Try to get the diffuse colour
AIColor4D mtlDiffuse = AIColor4D.create();
int success = aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, aiTextureType_DIFFUSE, 0, mtlDiffuse);
switch(success) {
    case aiReturn_SUCCESS:
        System.out.println("aiReturn_SUCCESS");
        break;
    case aiReturn_FAILURE:
        System.out.println("aiReturn_FAILURE");
        break;
    case aiReturn_OUTOFMEMORY:
        System.out.println("aiReturn_OUTOFMEMORY");
        break;
    default:
        break;
}

//List all the properties and whether they match
PointerBuffer props = mtl.mProperties();
for(int j = 0; j < mtl.mNumProperties(); j++) {
    AIMaterialProperty prop = AIMaterialProperty.create(props.get());
    System.out.println(
            "key=\"" + prop.mKey().dataString() + 
                    "\", type=" + prop.mType() + 
                    ", index=" + prop.mIndex() + 
                    " (" + (prop.mKey().dataString().equals(AI_MATKEY_COLOR_DIFFUSE) && 
                            prop.mType() == aiTextureType_DIFFUSE && 
                            prop.mIndex() == 0)
                    + ")"
    );
}

And the important bits of the output:
aiReturn_FAILURE
key="?mat.name", type=3, index=0 (false)
key="$clr.diffuse", type=1, index=0 (true)
key="$clr.specular", type=1, index=0 (false)
key="$mat.shininess", type=1, index=0 (false)
key="$clr.ambient", type=1, index=0 (false)
key="$clr.reflective", type=1, index=0 (false)
key="$mat.blend.diffuse.color", type=1, index=0 (false)


So obviously there is a property matching the colour I want but the function fails to find it. The model I'm trying to load has a single material which is just the base colours with no associated textures which I feel is perhaps the reason why but I don't see why it should be impossible because of that.

So anyone more familiar with Assimp know what I'm supposed to do in this situation? Or anyone more familiar with the LWJGL binding know what the extra parameters are supposed to be?

Thanks everyone.

spasi

Hey quew8,

First of all, the aiGetMaterial* functions are awkward to use because they make extensive use of #defines and macros in the C API. There's no simple/clean way to port that to Java, so only the low-level getters are exposed. It's a good idea to inspect the native headers and code samples when working with Assimp materials, to verify correct use.

On the specific problem you're having, the fix should be simple. Replace aiTextureType_DIFFUSE with 0. The mType member of aiMaterialProperty is actually an aiPropertyTypeInfo value, which is an enum used internally by Assimp. It happens to have the same value as aiTextureType_DIFFUSE, but they are unrelated. aiTextureType_DIFFUSE should be used with aiGetMaterialString to retrieve the diffuse texture name.

quew8

Hey Spasi,

Ah right, of course. Yeah I think even Assimp's own documentation mentions that they're a bit messy. But good point, I'll make sure I look closer in the future.

Yep you're exactly right. And that makes a lot of sense now you say it. I was wondering why a colour property would be associated with a texture. Thanks so much for the insight and the help. Invaluable as ever.

One other thing, I notice in the LWJGL demos that the only Assimp demo just checks that library is all loaded correctly by getting the version strings and whatnot. I assumed that this was because the potential usage of Assimp was so broad that a simple demo couldn't even begin to cover everything but if that isn't the case and a little demo demonstrating loading and rendering a simple model with a single diffuse texture would be helpful I'd be very happy to write that up.

spasi

Quote from: quew8 on July 04, 2017, 15:08:28a little demo demonstrating loading and rendering a simple model with a single diffuse texture would be helpful I'd be very happy to write that up.

It would be very welcome, thanks.

quew8

Well I'll get right on that then. So the point of the demos is to be as on purpose, simple and self contained as they can be right? So immediate mode rendering and no image loading (since that would require stb) would be the best way to go?

spasi

Dependencies to other LWJGL bindings are fine. Modern GL and shaders are also fine.

The only real issue is binary resources, which are kept off source control. Those would have to be uploaded to S3 and downloaded by the build script. So, I'd say your budget is 1 scene file + 1 texture for a simple demo.

If you'd like to contribute something more complex: submit a simple demo to lwjgl3 and a complex one (or more) to lwjgl3-demos. You can go crazy with resources there.