- add some more static helper methods to TextureAtlas

- add functions to apply atlas coords to geometry to TextureAtlas

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9045 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
nor..67 13 years ago
parent a265e72759
commit 550499a0d6
  1. 100
      engine/src/tools/jme3tools/optimize/TextureAtlas.java

@ -35,14 +35,12 @@ import com.jme3.asset.AssetKey;
import com.jme3.asset.AssetManager; import com.jme3.asset.AssetManager;
import com.jme3.material.MatParamTexture; import com.jme3.material.MatParamTexture;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.Matrix4f;
import com.jme3.math.Vector2f; import com.jme3.math.Vector2f;
import com.jme3.scene.Geometry; import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh; import com.jme3.scene.Mesh;
import com.jme3.scene.Spatial; import com.jme3.scene.Spatial;
import com.jme3.scene.VertexBuffer; import com.jme3.scene.VertexBuffer;
import com.jme3.scene.VertexBuffer.Type; import com.jme3.scene.VertexBuffer.Type;
import com.jme3.scene.mesh.IndexBuffer;
import com.jme3.texture.Image; import com.jme3.texture.Image;
import com.jme3.texture.Image.Format; import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
@ -261,17 +259,63 @@ public class TextureAtlas {
} }
/** /**
* Creates one geometry out of the given root spatial and merges all single * Applies the texture coordinates to the given geometry
* textures into one texture of the given size. * if its DiffuseMap or ColorMap exists in the atlas.
* @param spat The root spatial of the scene to batch * @param geom The geometry to change the texture coordinate buffer on.
* @param mgr An assetmanager that can be used to create the material * @return true if texture has been found and coords have been changed, false otherwise
* @param atlasSize A size for the atlas texture, it has to be large enough to hold all single textures
* @return
*/ */
public static Geometry makeAtlasBatch(Spatial spat, AssetManager mgr, int atlasSize) { public boolean applyCoords(Geometry geom) {
return applyCoords(geom, 0, geom.getMesh());
}
/**
* Applies the texture coordinates to the given geometry
* if its DiffuseMap or ColorMap exists in the atlas.
* @param geom The geometry to change the texture coordinate buffer on.
* @param offset Target buffer offset
* @param outMesh The mesh to set the coords in (can be same as input)
* @return true if texture has been found and coords have been changed, false otherwise
*/
public boolean applyCoords(Geometry geom, int offset, Mesh outMesh) {
Mesh inMesh = geom.getMesh();
geom.computeWorldMatrix();
VertexBuffer inBuf = inMesh.getBuffer(Type.TexCoord);
VertexBuffer outBuf = outMesh.getBuffer(Type.TexCoord);
if (inBuf == null || outBuf == null) {
throw new IllegalStateException("Geometry mesh has no texture coordinate buffer.");
}
Texture tex = getMaterialTexture(geom, "DiffuseMap");
if (tex == null) {
tex = getMaterialTexture(geom, "ColorMap");
}
if (tex != null) {
TextureAtlasTile tile = getAtlasTile(tex);
if (tile != null) {
FloatBuffer inPos = (FloatBuffer) inBuf.getData();
FloatBuffer outPos = (FloatBuffer) outBuf.getData();
tile.transformTextureCoords(inPos, offset, outPos);
return true;
} else {
return false;
}
} else {
throw new IllegalStateException("Geometry has no proper texture.");
}
}
/**
* Create a texture atlas for the given root node, containing DiffuseMap, NormalMap and SpecularMap.
* @param root The rootNode to create the atlas for
* @param atlasSize The size of the atlas (width and height)
* @return Null if the atlas cannot be created because not all textures fit
*/
public static TextureAtlas createAtlas(Spatial root, int atlasSize) {
List<Geometry> geometries = new ArrayList<Geometry>(); List<Geometry> geometries = new ArrayList<Geometry>();
GeometryBatchFactory.gatherGeoms(spat, geometries); GeometryBatchFactory.gatherGeoms(root, geometries);
//TODO: specular etc. maps, needs to use main atlas for locations
TextureAtlas atlas = new TextureAtlas(atlasSize, atlasSize); TextureAtlas atlas = new TextureAtlas(atlasSize, atlasSize);
for (Geometry geometry : geometries) { for (Geometry geometry : geometries) {
Texture diffuse = getMaterialTexture(geometry, "DiffuseMap"); Texture diffuse = getMaterialTexture(geometry, "DiffuseMap");
@ -284,7 +328,7 @@ public class TextureAtlas {
if (diffuse != null && diffuse.getKey() != null) { if (diffuse != null && diffuse.getKey() != null) {
String keyName = diffuse.getKey().getName(); String keyName = diffuse.getKey().getName();
if (!atlas.addTexture(diffuse, "DiffuseMap")) { if (!atlas.addTexture(diffuse, "DiffuseMap")) {
throw new IllegalStateException("Adding diffuse texture" + keyName + "to atlas failed, atlas full."); return null;
} else { } else {
if (normal != null && normal.getKey() != null) { if (normal != null && normal.getKey() != null) {
atlas.addTexture(diffuse, "NormalMap", keyName); atlas.addTexture(diffuse, "NormalMap", keyName);
@ -295,6 +339,24 @@ public class TextureAtlas {
} }
} }
} }
return atlas;
}
/**
* Creates one geometry out of the given root spatial and merges all single
* textures into one texture of the given size.
* @param spat The root spatial of the scene to batch
* @param mgr An assetmanager that can be used to create the material
* @param atlasSize A size for the atlas texture, it has to be large enough to hold all single textures
* @return A new geometry that uses the generated texture atlas and merges all meshes of the root spatial, null if the atlas cannot be created because not all textures fit
*/
public static Geometry makeAtlasBatch(Spatial spat, AssetManager mgr, int atlasSize) {
List<Geometry> geometries = new ArrayList<Geometry>();
GeometryBatchFactory.gatherGeoms(spat, geometries);
TextureAtlas atlas = createAtlas(spat, atlasSize);
if (atlas == null) {
return null;
}
Geometry geom = new Geometry(); Geometry geom = new Geometry();
Mesh mesh = new Mesh(); Mesh mesh = new Mesh();
GeometryBatchFactory.mergeGeometries(geometries, mesh); GeometryBatchFactory.mergeGeometries(geometries, mesh);
@ -339,19 +401,7 @@ public class TextureAtlas {
continue; continue;
} }
Texture tex = getMaterialTexture(geom, "DiffuseMap"); atlas.applyCoords(geom, globalVertIndex, outMesh);
if (tex == null) {
tex = getMaterialTexture(geom, "ColorMap");
}
if (tex != null) {
TextureAtlasTile tile = atlas.getAtlasTile(tex);
if (tile != null) {
FloatBuffer inPos = (FloatBuffer) inBuf.getData();
FloatBuffer outPos = (FloatBuffer) outBuf.getData();
tile.transformTextureCoords(inPos, globalVertIndex, outPos);
}
}
globalVertIndex += geomVertCount; globalVertIndex += geomVertCount;
} }

Loading…
Cancel
Save