Page 1 of 2

Multple UV textures for player model.

PostPosted: Sat May 18, 2013 20:54
by stu
I wasn't really sure where to post this so moderators feel free to move.

It would be very helpful for some mods (especially some of my own) if the player model could support more than one UV texture. I know irrlicht can do this with node->setMaterialTexture() but I have no idea where to start looking in the minetest source code.

I do have some limited c++ experience and could perhaps implement this myself if someone could point me in then right direction.

Cheers!

PostPosted: Sat May 18, 2013 21:05
by PilzAdam
content_cao.cpp:554
GenericCAO is used for players and LuaEntities.

PostPosted: Sun May 19, 2013 19:06
by stu
PilzAdam wrote:content_cao.cpp:554
GenericCAO is used for players and LuaEntities.

Thank you PilzAdam, that has been extremely helpful.

Am I right in thinking that this is where textures are applied to the player mesh?
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
content_cao.cpp

1293:        if(m_animated_meshnode)
1294:        {
1295:            if(m_prop.visual == "mesh")
1296:            {
1297:                for (u32 i = 0; i < m_prop.textures.size() && i < m_animated_meshnode->getMaterialCount(); ++i)
.
.
1311:                m_animated_meshnode->setMaterialTexture(i, texture);           

If so, it looks as if multiple textures should be already supported. However, if I supply more than one texture in the player object properties table, only the first one appears to be loaded.

Any ideas why that might be?

Is the player entity an animated meshnode or am I looking in the wrong place?

PostPosted: Sun May 19, 2013 19:19
by PilzAdam
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
m_animated_meshnode->getMaterialCount()

is 1, so only one texture can be applied.
Seems like only 1 texture per material is supported.

PostPosted: Sun May 19, 2013 20:55
by stu
PilzAdam wrote:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
m_animated_meshnode->getMaterialCount()

is 1, so only one texture can be applied.
Seems like only 1 texture per material is supported.

Well I guess that would make sense but looking at irrlicht ISceneNode::getMaterialCount(); it shoud infact return zero unless its overridden by the derived class. I can't find where this done in minetest besides farmesh.cpp

I guess this is not going to be as easy as I thought :(

Thank you again for your help.

PostPosted: Sun May 19, 2013 21:00
by PilzAdam
stu wrote:
PilzAdam wrote:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
m_animated_meshnode->getMaterialCount()

is 1, so only one texture can be applied.
Seems like only 1 texture per material is supported.

Well I guess that would make sense but looking at irrlicht ISceneNode::getMaterialCount(); it shoud infact return zero unless its overridden by the derived class. I can't find where this done in minetest besides farmesh.cpp

I guess this is not going to be as easy as I thought :(

Thank you again for your help.

No problem, its always interesting to dig into a part of Minetest's code.

PostPosted: Tue May 21, 2013 20:47
by stu
Ok well I think I am beginning to make some progress. It turns out that node->getMaterialCount() should do just exactly what it says; return the number of materials a model supplies. My model has 2 materials, therefore getMaterialCount returns 2.

I have proven this by applying the following to the irrlicht 'HelloWorld' example.
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
        node->getMaterial(0).TextureLayer[0].Texture = driver->getTexture("wieldview_character.png");
        node->getMaterial(1).TextureLayer[0].Texture = driver->getTexture("armor.png");

        video::SMaterial& material_player = node->getMaterial(0);
        video::SMaterial& material_armor = node->getMaterial(1);

        material_player.setFlag(video::EMF_LIGHTING, false);
        material_armor.setFlag(video::EMF_LIGHTING, false);

        node->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);

        printf("Material Count: %d \n", node->getMaterialCount());


This works fine in the example but for some reason only the first material is loaded when I use the same model in minetest.
My guess is that it has to do with how content.cao applies the material texture.

Notably this does NOT work when used with the example above.
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
        node->setMaterialTexture( 0, driver->getTexture("wieldview_character.png") );
        node->setMaterialTexture( 1, driver->getTexture("armor.png") );

PostPosted: Tue May 21, 2013 20:50
by PilzAdam
stu wrote:Ok well I think I am beginning to make some progress. It turns out that node->getMaterialCount() should do just exactly what it says; return the number of materials a model supplies. My model has 2 materials, therefore getMaterialCount returns 2.

I have proven this by applying the following to the irrlicht 'HelloWorld' example.
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
        node->getMaterial(0).TextureLayer[0].Texture = driver->getTexture("wieldview_character.png");
        node->getMaterial(1).TextureLayer[0].Texture = driver->getTexture("armor.png");

        video::SMaterial& material_player = node->getMaterial(0);
        video::SMaterial& material_armor = node->getMaterial(1);

        material_player.setFlag(video::EMF_LIGHTING, false);
        material_armor.setFlag(video::EMF_LIGHTING, false);

        node->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);

        printf("Material Count: %d \n", node->getMaterialCount());


This works fine in the example but for some reason only the first material is loaded when I use the same model in minetest.
My guess is that it has to do with how content.cao applies the material texture.

Notably this does NOT work when used with the example above.
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
        node->setMaterialTexture( 0, driver->getTexture("wieldview_character.png") );
        node->setMaterialTexture( 1, driver->getTexture("armor.png") );

Interesting. Would be cool if you find a fix for the Minetest code and provide it as a patch.

PostPosted: Tue May 21, 2013 21:26
by stu
Yay, I changed:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
 m_animated_meshnode->setMaterialTexture(i, texture);
To:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
 m_animated_meshnode->setMaterial(i).TextureLayer[0].Texture = texture;

Recompiled and it works! :D

Do you think that would be accepted as a pull request?

PostPosted: Tue May 21, 2013 21:28
by PilzAdam
stu wrote:Yay, I changed:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
 m_animated_meshnode->setMaterialTexture(i, texture);
To:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
 m_animated_meshnode->setMaterial(i).TextureLayer[0].Texture = texture;

Recompiled and it works! :D

Do you think that would be accepted as a pull request?

Definetly worth a try. Also add a short description how to test it (maybe a testmodel included).

PostPosted: Tue May 21, 2013 21:38
by stu
Thanks, I will give it a shot. I would really love this to be included in 0.4.7, it would make my armor and weildview mods sooo much easier to implement and no more issues with conflicting texture resolutions.

Really speaking, I consider this to be a bug in minetest since the loop in updateTextures has clearly been desgined to cope with multiple materials/textures...it just does not work the way it is.

PostPosted: Wed May 22, 2013 02:42
by RealBadAngel
I used multitextured objects already without problems.
if model comes with materials defined in it (like .x model for example) engine will load textures defined here, without even need to mention them in code.

Also sample objects loading from my skydome code:

scene::IAnimatedMesh *mesh;
mesh = mgr->getMesh("sky_sphere.x");
m_sky_sphere = mgr->addAnimatedMeshSceneNode(mesh, NULL);
mesh->drop();
mesh = mgr->getMesh("sky_dome.x");
m_sky_dome = mgr->addMeshSceneNode(mesh, NULL);
mesh->drop();
m_sky_sphere->animateJoints();
m_sky_sphere->setFrameLoop(1, 250);
m_sky_sphere->setAnimationSpeed(0);
m_sky_sphere->setPosition(v3f(0,0,0));
m_sky_sphere->setScale(v3f(1000,1000,1000));
u8 li = 255;
setMeshColor(m_sky_sphere->getMesh(), video::SColor(255,li,li,li));
m_sky_sphere->setMaterialFlag(video::EMF_LIGHTING, false);
m_sky_sphere->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
m_sky_sphere->setMaterialFlag(video::EMF_FOG_ENABLE, false);
m_sky_sphere->setMaterialFlag(video::EMF_BACK_FACE_CULLING, false);
m_sky_sphere->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
m_sky_sphere->setMaterialFlag(video::EMF_ZBUFFER, false);

m_sky_dome->setPosition(v3f(0,400,0));
m_sky_dome->setScale(v3f(20,20,20));
m_sky_dome->setMaterialFlag(video::EMF_LIGHTING, false);
m_sky_dome->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
m_sky_dome->setMaterialFlag(video::EMF_FOG_ENABLE, false);
m_sky_dome->setMaterialFlag(video::EMF_BACK_FACE_CULLING, false);
//m_sky_dome->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
//m_sky_dome->setMaterialFlag(video::EMF_ZBUFFER, false);
m_sky_dome->setMaterialTexture(0, mgr->getVideoDriver()->getTexture(getTexturePath("sky.png").c_str()));
m_sky_dome->setMaterialTexture(1, mgr->getVideoDriver()->getTexture(getTexturePath("glow.png").c_str()));
m_sky_dome->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL);
video::E_MATERIAL_TYPE sky_shader = m_client->getShaderSource()->getShader("test_shader_4").material;
m_sky_dome->setMaterialType(sky_shader);
m_sky_dome->setRotation (v3f(-90,0,0));
sky_sphere->setMaterialTexture(0, mgr->getVideoDriver()->getTexture(getTexturePath("sky.png").c_str()));
sky_sphere->setMaterialTexture(1, mgr->getVideoDriver()->getTexture(getTexturePath("glow.png").c_str()));
sky_sphere->setMaterialTexture(2, mgr->getVideoDriver()->getTexture(getTexturePath("stars.jpg").c_str()));
sky_sphere->setMaterialTexture(3, mgr->getVideoDriver()->getTexture(getTexturePath("moon.png").c_str()));

PostPosted: Wed May 22, 2013 18:23
by stu
RealBadAngel wrote:I used multitextured objects already without problems.
if model comes with materials defined in it (like .x model for example) engine will load textures defined here, without even need to mention them in code.


I am aware that I can export textures with the model, however, it is currently only possible to update the first material dynamically through lua.

My suggested change should fix that also.

btw, there is a typo in the code I posted above, it should be:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
  // Set material flags and texture
  m_animated_meshnode->getMaterial(i).TextureLayer[0].Texture = texture;

PostPosted: Wed May 22, 2013 18:34
by Jordach
I was thinking something like this could make custom skins even further refined:

You could have one texture for eyes, hair, hats, clothes etc and no one will have a pron skin ever.

PostPosted: Wed May 22, 2013 19:45
by stu
Jordach wrote:I was thinking something like this could make custom skins even further refined:

You could have one texture for eyes, hair, hats, clothes etc and no one will have a pron skin ever.

Sure, there are lots of possibilities for this if it gets added.

Anyway I just made my very first pull request...and I mean like ever!

Hope I got it right.

PostPosted: Wed May 22, 2013 22:28
by jojoa1997
stu wrote:
Jordach wrote:I was thinking something like this could make custom skins even further refined:

You could have one texture for eyes, hair, hats, clothes etc and no one will have a pron skin ever.

Sure, there are lots of possibilities for this if it gets added.

Anyway I just made my very first pull request...and I mean like ever!

Hope I got it right.
link

PostPosted: Thu May 23, 2013 04:45
by Jordach
jojoa1997 wrote:
stu wrote:
Jordach wrote:I was thinking something like this could make custom skins even further refined:

You could have one texture for eyes, hair, hats, clothes etc and no one will have a pron skin ever.

Sure, there are lots of possibilities for this if it gets added.

Anyway I just made my very first pull request...and I mean like ever!

Hope I got it right.
link
We never even did ANYTHING.

Next time Jojoa, try reading posts first. There are no links.

PostPosted: Thu May 23, 2013 09:44
by jojoa1997
You mean this
https://github.com/minetest/minetest/pull/733
I finally got time to search for it

PostPosted: Thu May 23, 2013 23:52
by stu
I have put together a simple mod to demonstrate the problem.

Image

Download: https://www.dropbox.com/s/fesymfg9gklm6zi/chainbox.zip

You will need to look for chainbox:chainbox_node in creative,
this is a simple transparent entity placement node.

With the current version you should only see the outer chains.

With the patch applied you should also see the inner texture.

License is WTFPL btw, if anyone wants to use any of this in a real mod.

PostPosted: Sat May 25, 2013 19:57
by stu
Potential next-generation wieldview & armor mods if this patch is merged.
Fully compatible with HDX texture packs.
Image
Otherwise not possible!

PostPosted: Mon Jun 03, 2013 21:38
by PilzAdam
Merged, will be in 0.4.7

PostPosted: Thu Jun 06, 2013 18:46
by stu
PilzAdam wrote:Merged, will be in 0.4.7

I read the logs and see this has now been reverted. I do think this was the right decision under the circumstances, I would hate to break a new release.

I think the problem here is how Pavel_S is applying materials to the model or maybe he has a broken exporter. The method I am using to apply textures to materials is perfectly valid, however, given the chance I would write it sightly differently.
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
         // Set material flags and texture
         video::SMaterial& material = m_animated_meshnode->getMaterial(i);
         material.TextureLayer[0].Texture = texture;
         material.setFlag(video::EMF_LIGHTING, false);
         material.setFlag(video::EMF_BILINEAR_FILTER, false);

Looks much better.

PostPosted: Tue Jun 11, 2013 21:37
by stu
It turns out that Pavel_S' helicopter model is in fact proof that my suggested fix does work. The exported directx file lists three materials, therefore minetest expects to see three textures in the entity property table. It only appears to work correctly at the moment because of the lacking multi-texture support in the engine. Pavel_S could make the model so that only one material is exported or he could even exploit the situation as it is.

For example, using my feature branch
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
    visual = "mesh",
    mesh = "heli.x",
    textures = {"wool_red.png", "heli.png", "wool_blue.png"},

Image

Also, I found the irrlicht forum thread that helped me get this working.

http://irrlicht.sourceforge.net/forum/viewtopic.php?f=1&t=37046&p=215659

Pull request re-opened https://github.com/minetest/minetest/pull/767

PostPosted: Tue Jun 11, 2013 22:51
by jin_xi
nice

PostPosted: Wed Jun 12, 2013 03:37
by Inocudom
Here is to hoping that this feature will be in Minetest one day.

PostPosted: Sat Jun 15, 2013 16:54
by stu
Inocudom wrote:Here is to hoping that this feature will be in Minetest one day.

This feature should already be in Minetest.
MirceaKitsune wrote:I added model support to Minetest (or rather connected the Irrlicht functions to the Minetest code). The intention was for models to support multiple materials, and for Lua to assign any texture to each. I'm surprised the texture list I initially coded doesn't work, although I never got around to testing it. I hope this fixes the problem... it would suck not to be able to use multiple mesh materials properly.

PostPosted: Sat Jun 15, 2013 22:47
by Mito551
stu wrote:Potential next-generation wieldview & armor mods if this patch is merged.
Fully compatible with HDX texture packs.
Image
Otherwise not possible!


is this mt or mc?

PostPosted: Sat Jun 15, 2013 22:52
by Evergreen
Mito551 wrote:
stu wrote:Potential next-generation wieldview & armor mods if this patch is merged.
Fully compatible with HDX texture packs.
Image
Otherwise not possible!


is this mt or mc?

Minetest. :D

PostPosted: Sun Jun 16, 2013 10:00
by Jordach
Mito551 wrote:
stu wrote:Potential next-generation wieldview & armor mods if this patch is merged.
Fully compatible with HDX texture packs.
Image
Otherwise not possible!


is this mt or mc?
1) MC doesn't have shields.
2) The wielditem isn't 3D, as MC is.

PostPosted: Sun Jun 16, 2013 17:33
by stu
This is the current dev version of mintest-3d_armor featuring the awesome sphax HD texture pack.

I have made a copy available as a feature branch for anyone interested in testing it.

Branch now deleted.

github: https://github.com/stujones11/minetest-3d_armor/tree/multi-uv-model
download: https://github.com/stujones11/minetest-3d_armor/archive/multi-uv-model.zip


Requires engine patch: https://github.com/minetest/minetest/pull/767