From a265e727596941ead1ad7dd30f99206db966390a Mon Sep 17 00:00:00 2001 From: "nor..67" Date: Sun, 15 Jan 2012 02:43:09 +0000 Subject: [PATCH] - move TextureAtlas methods out of GeometryBatchFactory git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9044 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../test/jme3test/tools/TestTextureAtlas.java | 4 +- .../optimize/GeometryBatchFactory.java | 99 +------------- .../jme3tools/optimize/TextureAtlas.java | 124 ++++++++++++++++++ 3 files changed, 127 insertions(+), 100 deletions(-) diff --git a/engine/src/test/jme3test/tools/TestTextureAtlas.java b/engine/src/test/jme3test/tools/TestTextureAtlas.java index cb59e27d6..d749e47eb 100644 --- a/engine/src/test/jme3test/tools/TestTextureAtlas.java +++ b/engine/src/test/jme3test/tools/TestTextureAtlas.java @@ -40,7 +40,7 @@ import com.jme3.scene.Geometry; import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.scene.shape.Quad; -import jme3tools.optimize.GeometryBatchFactory; +import jme3tools.optimize.TextureAtlas; public class TestTextureAtlas extends SimpleApplication { @@ -69,7 +69,7 @@ public class TestTextureAtlas extends SimpleApplication { scene.attachChild(obj4); scene.attachChild(obj5); - Geometry geom = GeometryBatchFactory.makeAtlasBatch(scene, assetManager, 2048); + Geometry geom = TextureAtlas.makeAtlasBatch(scene, assetManager, 2048); AmbientLight al = new AmbientLight(); rootNode.addLight(al); diff --git a/engine/src/tools/jme3tools/optimize/GeometryBatchFactory.java b/engine/src/tools/jme3tools/optimize/GeometryBatchFactory.java index a0573c2f8..2e703065e 100644 --- a/engine/src/tools/jme3tools/optimize/GeometryBatchFactory.java +++ b/engine/src/tools/jme3tools/optimize/GeometryBatchFactory.java @@ -1,7 +1,5 @@ package jme3tools.optimize; -import com.jme3.asset.AssetManager; -import com.jme3.material.MatParamTexture; import com.jme3.material.Material; import com.jme3.math.Matrix4f; import com.jme3.math.Transform; @@ -12,7 +10,6 @@ import com.jme3.scene.VertexBuffer.Format; import com.jme3.scene.VertexBuffer.Type; import com.jme3.scene.VertexBuffer.Usage; import com.jme3.scene.mesh.IndexBuffer; -import com.jme3.texture.Texture; import com.jme3.util.BufferUtils; import com.jme3.util.IntMap.Entry; import java.nio.Buffer; @@ -20,7 +17,6 @@ import java.nio.FloatBuffer; import java.nio.ShortBuffer; import java.util.*; import java.util.logging.Logger; -import jme3tools.optimize.TextureAtlas.TextureAtlasTile; public class GeometryBatchFactory { @@ -74,18 +70,6 @@ public class GeometryBatchFactory { * @param outMesh */ public static void mergeGeometries(Collection geometries, Mesh outMesh) { - mergeGeometries(geometries, outMesh, null); - } - - /** - * Merges all geometries in the collection into - * the output mesh. Creates a new material using the TextureAtlas. - * - * @param geometries - * @param outMesh - * @param atlas the TextureAtlas to use - */ - public static void mergeGeometries(Collection geometries, Mesh outMesh, TextureAtlas atlas) { int[] compsForBuf = new int[VertexBuffer.Type.values().length]; Format[] formatForBuf = new Format[compsForBuf.length]; @@ -201,20 +185,6 @@ public class GeometryBatchFactory { FloatBuffer inPos = (FloatBuffer) inBuf.getData(); FloatBuffer outPos = (FloatBuffer) outBuf.getData(); doTransformNorms(inPos, globalVertIndex, outPos, worldMatrix); - } else if (Type.TexCoord.ordinal() == bufType && atlas != null) { - Texture tex = getMaterialTexture(geom, "DiffuseMap"); - 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); - } - } } else { for (int vert = 0; vert < geomVertCount; vert++) { int curGlobalVertIndex = globalVertIndex + vert; @@ -321,74 +291,7 @@ public class GeometryBatchFactory { return retVal; } - public static Geometry makeAtlasBatch(Spatial spat, AssetManager mgr, int atlasSize) { - List geometries = new ArrayList(); - gatherGeoms(spat, geometries); - //TODO: specular etc. maps, needs to use main atlas for locations - TextureAtlas atlas = new TextureAtlas(atlasSize, atlasSize); - for (Geometry geometry : geometries) { - Texture diffuse = getMaterialTexture(geometry, "DiffuseMap"); - Texture normal = getMaterialTexture(geometry, "NormalMap"); - Texture specular = getMaterialTexture(geometry, "SpecularMap"); - if (diffuse == null) { - diffuse = getMaterialTexture(geometry, "ColorMap"); - - } - if (diffuse != null && diffuse.getKey() != null) { - String keyName = diffuse.getKey().getName(); - if (!atlas.addTexture(diffuse, "DiffuseMap")) { - throw new IllegalStateException("Adding diffuse texture" + keyName + "to atlas failed, atlas full."); - } else { - if (normal != null && normal.getKey() != null) { - atlas.addTexture(diffuse, "NormalMap", keyName); - } - if (specular != null && specular.getKey() != null) { - atlas.addTexture(specular, "SpecularMap", keyName); - } - } - } - } - Geometry geom = new Geometry(); - Mesh mesh = new Mesh(); - mergeGeometries(geometries, mesh, atlas); - mesh.updateCounts(); - mesh.updateBound(); - geom.setMesh(mesh); - - Material mat = new Material(mgr, "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); - - geom.setMaterial(mat); - return geom; - } - - private static Texture getMaterialTexture(Geometry geometry, String mapName) { - Material mat = geometry.getMaterial(); - if (mat == null || mat.getParam(mapName) == null || !(mat.getParam(mapName) instanceof MatParamTexture)) { - return null; - } - MatParamTexture param = (MatParamTexture) mat.getParam(mapName); - Texture texture = param.getTextureValue(); - if (texture == null) { - return null; - } - return texture; - } - - private static void gatherGeoms(Spatial scene, List geoms) { + public static void gatherGeoms(Spatial scene, List geoms) { if (scene instanceof Node) { Node node = (Node) scene; for (Spatial child : node.getChildren()) { diff --git a/engine/src/tools/jme3tools/optimize/TextureAtlas.java b/engine/src/tools/jme3tools/optimize/TextureAtlas.java index 6c3567235..c1885a88c 100644 --- a/engine/src/tools/jme3tools/optimize/TextureAtlas.java +++ b/engine/src/tools/jme3tools/optimize/TextureAtlas.java @@ -32,7 +32,17 @@ package jme3tools.optimize; import com.jme3.asset.AssetKey; +import com.jme3.asset.AssetManager; +import com.jme3.material.MatParamTexture; +import com.jme3.material.Material; +import com.jme3.math.Matrix4f; import com.jme3.math.Vector2f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.Spatial; +import com.jme3.scene.VertexBuffer; +import com.jme3.scene.VertexBuffer.Type; +import com.jme3.scene.mesh.IndexBuffer; import com.jme3.texture.Image; import com.jme3.texture.Image.Format; import com.jme3.texture.Texture; @@ -40,7 +50,9 @@ import com.jme3.texture.Texture2D; import com.jme3.util.BufferUtils; import java.nio.ByteBuffer; import java.nio.FloatBuffer; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -248,6 +260,118 @@ public class TextureAtlas { return null; } + /** + * 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 + */ + public static Geometry makeAtlasBatch(Spatial spat, AssetManager mgr, int atlasSize) { + List geometries = new ArrayList(); + GeometryBatchFactory.gatherGeoms(spat, geometries); + //TODO: specular etc. maps, needs to use main atlas for locations + TextureAtlas atlas = new TextureAtlas(atlasSize, atlasSize); + for (Geometry geometry : geometries) { + Texture diffuse = getMaterialTexture(geometry, "DiffuseMap"); + Texture normal = getMaterialTexture(geometry, "NormalMap"); + Texture specular = getMaterialTexture(geometry, "SpecularMap"); + if (diffuse == null) { + diffuse = getMaterialTexture(geometry, "ColorMap"); + + } + if (diffuse != null && diffuse.getKey() != null) { + String keyName = diffuse.getKey().getName(); + if (!atlas.addTexture(diffuse, "DiffuseMap")) { + throw new IllegalStateException("Adding diffuse texture" + keyName + "to atlas failed, atlas full."); + } else { + if (normal != null && normal.getKey() != null) { + atlas.addTexture(diffuse, "NormalMap", keyName); + } + if (specular != null && specular.getKey() != null) { + atlas.addTexture(specular, "SpecularMap", keyName); + } + } + } + } + Geometry geom = new Geometry(); + Mesh mesh = new Mesh(); + GeometryBatchFactory.mergeGeometries(geometries, mesh); + applyAtlasCoords(geometries, mesh, atlas); + mesh.updateCounts(); + mesh.updateBound(); + geom.setMesh(mesh); + + Material mat = new Material(mgr, "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); + + geom.setMaterial(mat); + return geom; + } + + private static void applyAtlasCoords(List geometries, Mesh outMesh, TextureAtlas atlas) { + int globalVertIndex = 0; + + for (Geometry geom : geometries) { + Mesh inMesh = geom.getMesh(); + geom.computeWorldMatrix(); + + int geomVertCount = inMesh.getVertexCount(); + + VertexBuffer inBuf = inMesh.getBuffer(Type.TexCoord); + VertexBuffer outBuf = outMesh.getBuffer(Type.TexCoord); + + if (inBuf == null || outBuf == null) { + continue; + } + + Texture tex = getMaterialTexture(geom, "DiffuseMap"); + 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; + } + } + + private static Texture getMaterialTexture(Geometry geometry, String mapName) { + Material mat = geometry.getMaterial(); + if (mat == null || mat.getParam(mapName) == null || !(mat.getParam(mapName) instanceof MatParamTexture)) { + return null; + } + MatParamTexture param = (MatParamTexture) mat.getParam(mapName); + Texture texture = param.getTextureValue(); + if (texture == null) { + return null; + } + return texture; + + + } + private class Node { public TextureAtlasTile location;