- move TextureAtlas methods out of GeometryBatchFactory
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9044 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
f04654ee20
commit
a265e72759
@ -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);
|
||||
|
@ -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<Geometry> 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<Geometry> 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<Geometry> geometries = new ArrayList<Geometry>();
|
||||
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<Geometry> geoms) {
|
||||
public static void gatherGeoms(Spatial scene, List<Geometry> geoms) {
|
||||
if (scene instanceof Node) {
|
||||
Node node = (Node) scene;
|
||||
for (Spatial child : node.getChildren()) {
|
||||
|
@ -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<Geometry> geometries = new ArrayList<Geometry>();
|
||||
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<Geometry> 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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user