Răsfoiți Sursa

- 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

nor..67 13 ani în urmă
părinte
comite
550499a0d6
1 a modificat fișierele cu 75 adăugiri și 25 ștergeri
  1. 75 25
      engine/src/tools/jme3tools/optimize/TextureAtlas.java

+ 75 - 25
engine/src/tools/jme3tools/optimize/TextureAtlas.java

@@ -35,14 +35,12 @@ 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;
@@ -261,17 +259,63 @@ public class TextureAtlas {
     }
 
     /**
-     * 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 
+     * 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.
+     * @return true if texture has been found and coords have been changed, false otherwise
      */
-    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>();
-        GeometryBatchFactory.gatherGeoms(spat, geometries);
-        //TODO: specular etc. maps, needs to use main atlas for locations
+        GeometryBatchFactory.gatherGeoms(root, geometries);
         TextureAtlas atlas = new TextureAtlas(atlasSize, atlasSize);
         for (Geometry geometry : geometries) {
             Texture diffuse = getMaterialTexture(geometry, "DiffuseMap");
@@ -284,7 +328,7 @@ public class TextureAtlas {
             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.");
+                    return null;
                 } else {
                     if (normal != null && normal.getKey() != null) {
                         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();
         Mesh mesh = new Mesh();
         GeometryBatchFactory.mergeGeometries(geometries, mesh);
@@ -339,19 +401,7 @@ public class TextureAtlas {
                 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);
-                }
-            }
+            atlas.applyCoords(geom, globalVertIndex, outMesh);
 
             globalVertIndex += geomVertCount;
         }