How to properly scale UV texture coordinates dynamically loaded j3o meshes?

Hi all,

I’m dynamically loading j3o models at runtime. For example, the fence model only has 1 material (1 texture) and when I tested it earlier, I found out the texture is not scaled enough, so I modified my .mtl file like this: map_Kd -s 2 1 0 wood.jpg

JME3 ignores the -s flag and so I found this FAQ page: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:faq#how_do_i_scale_mirror_or_wrap_a_texture

I’m using this code to load my model (which has been compressed to a j3o file beforehand) and scale the texture coordinates so that it repeats more times across the model:

[java]
Spatial fence_model = assetManager.loadModel(“Models/fence/fence.j3o”);
fence_model.setName(“Fence”);
fence_model.scale(0.5f);
fence_model.move(-1f, -0.255f, 1.34f);
((Geometry)fence_model).getMesh().scaleTextureCoordinates(new Vector2f(2.5f, 2.5f));
rootNode.attachChild(fence_model);
[/java]

This WORKS FINE but the problem arises when I execute the same code again later on. All fences on the scene get their UV texture coordinates ADDITIVELY scaled at the same time, so 2.5f becomes 2.5f+2.5f then 2.5f+2.5f+2.5f, because (I guess) the mesh data is only there once in memory (cached by JME3) so every call to scaleTextureCoordinates() is done on 1 unique mesh instead of each fence having their mesh. It does make sense for optimization, but… what would be the best route to go to have many j3o model instances but yet only scale their UV texture coordinates once? inb4 make an IF branch and hold a boolean variable to later detect if this is the first time we loaded this mesh or not and if this is the first time, then scale the UV texture coordinates, else do nothing.

I mean, is there another function call that would be better suited for dynamic j3o models loading that need UV coordinates modifications like in this scenario?

Thx all.

Well i would say, fix the model’s uv corrdinates?

You mean like in Blender or another program like that?

In this cas I see three options

-> blender
->as it is a obj, you could edit them by hand (eg just multiply all by 2.5)
-> use the sdk for jme load it do whatever is necesary, save again as a j3o for further use.

-> blender // I’ll have to study how to do this, not sure ATM.
-> as it is a obj, you could edit them by hand // … 100000 lines, no thanks hahaha!!!
-> use the sdk for jme load it do whatever is necesary, save again as a j3o for further use // YES, but I’m unsure how to exactly proceed to do this, would you share the method please? I only have been able to view 3D models using the SDK, I’m using the latest stable release. Haven’t found anything to scale UV parameters or anything of that sort yet.

Thanks.

Well not sure, I don’t use the sdk, I’m one of the eclipse users here :stuck_out_tongue:

You could write a simpleappliction tho that loads it, does the scaling, and then uses binaryexporter to save it again.
(After all anything the sdk does is no magic)

@.Ben. said: -> blender // I'll have to study how to do this, not sure ATM. -> as it is a obj, you could edit them by hand // ... 100000 lines, no thanks hahaha!!! -> use the sdk for jme load it do whatever is necesary, save again as a j3o for further use // YES, but I'm unsure how to exactly proceed to do this, would you share the method please? I only have been able to view 3D models using the SDK, I'm using the latest stable release. Haven't found anything to scale UV parameters or anything of that sort yet.

Thanks.

Blender: Go to the UV editor. Press “s” then enter 2.5. Might have to reposition it relative to 0, 0
OBJ: Write a script which parses it and multiplies it by 2.5
SDK: Like @empire says, resave it as a j3o after.

Most dynamic and easy approach:

[java]private bool modifiedFence = false;

void createFence()
{
Spatial fence_model = assetManager.loadModel(“Models/fence/fence.j3o”);
fence_model.setName(“Fence”);
fence_model.scale(0.5f);
fence_model.move(-1f, -0.255f, 1.34f);

if (!modifiedFence)
    {
    ((Geometry)fence_model).getMesh().scaleTextureCoordinates(new Vector2f(2.5f, 2.5f)); 
    modifiedFence = true;
    }

rootNode.attachChild(fence_model);

}
[/java]

Most convenient is the IF branch I inb4’ed in the OP. SIGH I wish I knew how to properly use Blender. There are so many options available and keyboard shortcuts are so unusual in Blender :frowning:

I’ll have to study how to do it now. Because even if the IF branch is VERY VERY fast and convenient, it won’t be very convenient if I have a lot of models like this later on. It’s better to correct the OBJ file already and be done with it once and for all.

Thanks to both of you.

1 Like