Trouble using BatchNode

I can’t understand why the following code works fine:

[java]

Material mateo = new Material(myApp.getAssetManager(),“Common/MatDefs/Light/Lighting.j3md”);

mateo.setTexture(“DiffuseMap”, myApp.getAssetManager().loadTexture("/Materials/BlueMaterial.png")); // a file containing blue background



Geometry geom = (Geometry) mySpatial;

geom.setMaterial(mateo);

batch.attachChild(mySpatial);

… later after attaching all the children…

batch.batch();

myApp.getRootNode().attachChild(batch);

[/java]





and this code using an atlas.png file gives me an illegalArgument error :S

[java]

Material mateo = new Material(myApp.getAssetManager(),“Common/MatDefs/Light/Lighting.j3md”);

mateo.setTexture(“DiffuseMap”, myApp.getAssetManager().loadTexture("/Materials/TextureAtlas/atlasColors.png"));





Vector2f[] texCoord = new Vector2f[4];

texCoord[0] = new Vector2f(0, 0);

texCoord[1] = new Vector2f(0.1f,0);

texCoord[2] = new Vector2f(0,.1f);

texCoord[3] = new Vector2f(.1f,.1f);



Geometry geom = (Geometry) mySpatial;

geom.getMesh().setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord));

geom.getMesh().updateBound();



geom.setMaterial(mateo);

batch.attachChild(mySpatial);

… later …

batch.batch();

myApp.getRootNode().attachChild(batch);



[/java]





error:

[xml]Mar 26, 2012 12:52:18 AM com.jme3.app.Application handleError

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

java.lang.IllegalArgumentException

at java.nio.Buffer.limit(Buffer.java:249)

at com.jme3.scene.VertexBuffer.copyElements(VertexBuffer.java:831)

at com.jme3.scene.BatchNode.mergeGeometries(BatchNode.java:495)

at com.jme3.scene.BatchNode.doBatch(BatchNode.java:202)

at com.jme3.scene.BatchNode.batch(BatchNode.java:175)[/xml]



triggered at batch.batch()

Well in the first case you don’t mess with the buffers…in the second case you do.



My guess is that you only set 4 tex coords, and that your mesh has more than that 4 vertices. Is your mesh a quad?

Hmmm. That’s exactly the problem except that my object is complex and has a lot of vertices. Anyway I could set them all at the same time?

create UV coords in your 3d editing program

I’m not quite sure what the texture atlas is for and I’m not that knowledgeable regarding the inner workings of meshes, but if I’m understanding your intentions with this, can’t you just UV unwrap your meshes to different parts of a big texture directly in blender and then use that texture in the materials of all the meshes, instead of mapping texture coordinates in code?

@homsi said:
Hmmm. That's exactly the problem except that my object is complex and has a lot of vertices. Anyway I could set them all at the same time?

You need texture coordinates for each vertex of your mesh. If your mesh is complex, then doing it in the code will just make your eyes bleed.
You should follow Wezrule's advice and create your UVs in a 3D editor.

and to understand the advice:


create UV coords in your 3d editing program


I create my models (shelves) in Blender 2.6 and import it to jME (j3o or .obj) and apply the material on it.I create the materials separately by combining all of them in one atlas file. Then I use teh code shown to map to that file by changing the texture coordinates on the mesh which apparently like u said I am doing only 4 and it's not a quad - its more complicated.

so what do you mean by creating my coords in my 3d editing program? at which step do I do that? can u be more specific? can it be done in Blender?

http://lmgtfy.com/?q=create+uv+in+blender

1 Like

Just UV unwrap your mesh in Blender, like you would for a normal texture.

Edit mode → Select all vertices → Mesh → UV unwrap → some option here

1 Like

@nehon i wish i could give you two thumbs up for that

Good girl gina

“Tries to code in JME… actually reads the tutorials”

Guys I apologize for not being very knowledgable in this… the reason I was trying to avoid UV unwrapping is that even though my models are complex the material applied is really simple (just a simple COLOR). Isn’t there anyway where I can set ALL the vertices on a specific mesh to a particular texture? I am not worried too much how it would apply that texture and unwraps as its really just a COLOR.



I am using an atlas file containing a lot of colors (grouped in squares) my point was to try mapping to a certain texture on that file by giving it the location of that texture. So honestly I dont understand why so I need to uv unwrap, and if so , let’s say I unwrap my object, how would I use that?



Edit: to sound less stupid:



In blender before exporting the object into jME I go to Texture and to the Mapping section and make the Coordinates UV. but then what? how do I setthe buffer with these coords???



[java] geom.getMesh().setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord));[/java] <<<<<<<

If you just want a solid colour why not skip the texture and use a solid colour in the material (“Diffuse” if you’re using Lighting.j3md)?

czI am batching everything and thus I need to change the color of an already batched node (which is not allowed) hence I am putting all the colors as textures in a texture atlas and trying to point to it

Can’t you change the material of a batched node? Even if you can’t then why not remove the node from the batch, change the material then rebatch it?

All children of a batch have the same material. They have to because they become one mesh.



The real solution to this problem is to use vertex colors… but Lighting does not support vertex colors as far as I know. Some shader tweaking would be necessary and I strongly believe this is beyond the original poster’s abilities.



@original poster, In an atlased batch, the texture for all faces is the same and it is the texture coordinates that control what part of that texture is used. You really mean you want to change the texture coordinates for a face so that it is a different sub-part of the texture.



That’s not hard. Find the child geometry you want to change and then reset its texture buffer. Test it on a simple unbatched Box geometry first.



The problem is going to be what to set the values to… but since you don’t have real textures then you could give all of the vertexes the same texture coordinate that represents a point smack in the middle of the sub-part of the texture that has the color you want.

See, if you create your models with this atlas in the 3d editor, you can just add and remove loaded models to the batch and everything will be fine. Just make green/red etc. boxes and whatever beforehand. Again this would all be easier if you started a bit smaller.

The material can’t be changed, but could a material param be changed for a given model?



If so, switching the color of a model’s material could work.



Alternatively, if you have 3-4 colors, you could have 3-4 batched nodes and switch the appropriate model to the right-colored node.



Never had to use batching so if I’m in the left lane, forgive my intrusion. :wink:

@madjack said:
The material can't be changed, but could a material param be changed for a given model?

If so, switching the color of a model's material could work.

Alternatively, if you have 3-4 colors, you could have 3-4 batched nodes and switch the appropriate model to the right-colored node.

Never had to use batching so if I'm in the left lane, forgive my intrusion. ;)


By definition, a batch = 1 geometry. 1 geometry = 1 material

ergo: changing the material parameter changes it for the whole mesh.
That’s not hard. Find the child geometry you want to change and then reset its texture buffer. Test it on a simple unbatched Box geometry first.


I already have it working on a small box (quad), it's the shelf model that I am importing that I am having difficulties with.


but since you don’t have real textures then you could give all of the vertexes the same texture coordinate that represents a point smack in the middle of the sub-part of the texture that has the color you want.


and thats exactly my question how do I do that?

for quad I simply do something like
[java] Vector2f[] texCoord = new Vector2f[4];
texCoord[0] = new Vector2f(0, 0);
texCoord[1] = new Vector2f(0.1f,0);
texCoord[2] = new Vector2f(0,.1f);
texCoord[3] = new Vector2f(.1f,.1f);[/java]

but for a more complex models (non quad) I have more vertices and the question is how can I give all the vertices the same texture coordinate that represents say the blue part of my atlas file below:

8A3no.png

edit:
dont judge the ugliness of my atlas lol