TextureAtlas creation and packed Texture handling in SDK

Hey,

another set of new features for the SDK, I already briefly mentioned one of them, you can now batch geometry and create a TextureAtlas at the same time:


The resulting single geometry is very efficient to render, so you can combine models in the SDK SceneComposer and create one geometry with one texture atlas for all models.

Note that the TextureAtlas tool (which is part of the engine and usable from code as well btw) has some limitations which are:

  • Repeating textures will not work properly due to how texture atlases work generally
  • The diffuse and other maps (normal etc.) have to be the same size for each model or there will be mapping issues

But theres even more… :smiley: The TextureAtlas is a packed texture and these cannot really be handled via j3m files and paths and are generally impractical as they easily cause multiple instances of the same texture. This is why I now added texture unpacking to PNG files for materials as well :slight_smile: When you create a j3m file for your model, you will be asked for paths to export your textures to and these will be used in the new material.


Of course this also allows you to unpack other packed textures, like those from procedural blender textures which are supported by @Kaelthas awesome importer.

Oh and btw Undo now also works for these batching operations :wink:

Cheers,
Normen

7 Likes

… look at this guy over here :smiley:

Nice one. A much desired tool.
Thanks Normen.

sweet :slight_smile: is this only for static scenes?

@wezrule said: sweet :) is this only for static scenes?
Well your scene is static once you made it a single geometry.. but! You should be able to reuse existing AnimControls as the anim indices of the mesh are kept... Ofc this could cause some confusion with overlapping indices etc. Also I am not sure if I added copy-pasing of AnimControls or Controls in general yet.. Gotta add that if not ^^

ah sorry i missed the “the resulting single geometry” part ^_^. I wasn’t sure if we were able to create BatchNodes from the JMEDK yet or not, and cool :slight_smile:

Great !

How many news in our favorite sdk the last few days :slight_smile:
Thanks Normen.

It would be awesome (especially for mobile games) if setting the atlas size would also rescale the textures to fit. That woul allow to shrink the textures automatically and create models with reduced memory consumption automatically correct? Currently im using the texture atlas tool because often the j3o files which look correct in the desktop app do not look correct anymore in the Android app. So this might also be a good usage scenario for that tool (maybe even a rightclick on j3o file -> tools -> merge textures ?:wink:

I wrote some code to test the TextureAtlas but it seems to have problems with all of the models I use for testing. This is the code I use:

[java]public void optimizeGeometryAndTextures(Node node, int atlasSize) {

	node = (Node) GeometryBatchFactory.optimize(node);
            // either auto-create from node:
	TextureAtlas atlas = TextureAtlas.createAtlas(node, atlasSize);
	// create material and set texture
	Material mat = new Material(assetManager,
			"Common/MatDefs/Light/Lighting.j3md");
	mat.getAdditionalRenderState().setAlphaTest(true);
   		Texture diffuseMap = atlas.getAtlasTexture("DiffuseMap");
	Texture normalMap = atlas.getAtlasTexture("NormalMap");
	Texture specularMap = atlas.getAtlasTexture("SpecularMap");
	if (diffuseMap != null) {
		mat.setTexture("DiffuseMap", diffuseMap);
	}
	if (normalMap != null) {
		mat.setTexture("NormalMap", normalMap);
	}
	if (specularMap != null) {
		mat.setTexture("SpecularMap", specularMap);
	}
	mat.setFloat("Shininess", 16.0f);

	List<Geometry> geometries = new ArrayList<Geometry>();
	GeometryBatchFactory.gatherGeoms(node, geometries);
	util.Log.d(LOG_TAG, "geometries.size()=" + geometries.size());
	for (Geometry geom : geometries) {
		try {
			if (atlas.applyCoords(geom)) {
				geom.setMaterial(mat);
			}
		} catch (Exception e) {
			// skip all geometries which do not have a texture
		}
	}
}[/java] 

For some geometries in the passed node is applies the correct texture coordinates but for most it does not. Can someone please tell me what I am doing wrong? I wrote this method because the default TextureAtlas.makeAtlasBatch(…) method did not handle models with not fully textured models.

are all texcoords between 0 and 1 ? And no repeating used?

@Empire Phoenix said: are all texcoords between 0 and 1 ? And no repeating used?

Well when I display the model without calling this method before the model looks quite fine and I don’t modify it I just use the asset manager to load it

@simon.heinen said: Well when I display the model without calling this method before the model looks quite fine and I don't modify it I just use the asset manager to load it

That doesn’t answer the question.

@normen said: That doesn't answer the question.

I generate the colada model with sketchup and in the one model I have a window texture for example which i use for multiple walls. If the tex coords of the original model were not between 0 and 1 wouldnt it be displayed incorrect? How can i check the tex coords in a generated colada model other then displaying it?

@simon.heinen said: I generate the colada model with sketchup and in the one model I have a window texture for example which i use for multiple walls. If the tex coords of the original model were not between 0 and 1 wouldnt it be displayed incorrect? How can i check the tex coords in a generated colada model other then displaying it?

If some texture repeats then the coords go over 0-1 and you cannot atlas it this way.

Hm well you could go trough the xml by hand for a low level solution.

Basically outside 0-1 means that the texture is repeated, this creates obviously some problems with an atlas, as there are other textures next to it, instead of the border.