use of com.jme3.material.Material in project jmonkeyengine by jMonkeyEngine.
the class GeometryBatchFactory method mergeGeometries.
/**
* Merges all geometries in the collection into
* the output mesh. Creates a new material using the TextureAtlas.
*
* @param geometries
* @param outMesh
*/
public static void mergeGeometries(Collection<Geometry> geometries, Mesh outMesh) {
int[] compsForBuf = new int[VertexBuffer.Type.values().length];
Format[] formatForBuf = new Format[compsForBuf.length];
boolean[] normForBuf = new boolean[VertexBuffer.Type.values().length];
int totalVerts = 0;
int totalTris = 0;
int totalLodLevels = 0;
int maxWeights = -1;
Mode mode = null;
for (Geometry geom : geometries) {
totalVerts += geom.getVertexCount();
totalTris += geom.getTriangleCount();
totalLodLevels = Math.min(totalLodLevels, geom.getMesh().getNumLodLevels());
Mode listMode;
int components;
switch(geom.getMesh().getMode()) {
case Points:
listMode = Mode.Points;
components = 0;
break;
case LineLoop:
case LineStrip:
case Lines:
listMode = Mode.Lines;
components = 2;
break;
case TriangleFan:
case TriangleStrip:
case Triangles:
listMode = Mode.Triangles;
components = 3;
break;
default:
throw new UnsupportedOperationException();
}
for (VertexBuffer vb : geom.getMesh().getBufferList().getArray()) {
int currentCompsForBuf = compsForBuf[vb.getBufferType().ordinal()];
if (vb.getBufferType() != Type.Index && currentCompsForBuf != 0 && currentCompsForBuf != vb.getNumComponents()) {
throw new UnsupportedOperationException("The geometry " + geom + " buffer " + vb.getBufferType() + " has different number of components than the rest of the meshes " + "(this: " + vb.getNumComponents() + ", expected: " + currentCompsForBuf + ")");
}
compsForBuf[vb.getBufferType().ordinal()] = vb.getNumComponents();
formatForBuf[vb.getBufferType().ordinal()] = vb.getFormat();
normForBuf[vb.getBufferType().ordinal()] = vb.isNormalized();
}
maxWeights = Math.max(maxWeights, geom.getMesh().getMaxNumWeights());
if (mode != null && mode != listMode) {
throw new UnsupportedOperationException("Cannot combine different" + " primitive types: " + mode + " != " + listMode);
}
mode = listMode;
compsForBuf[Type.Index.ordinal()] = components;
}
outMesh.setMaxNumWeights(maxWeights);
outMesh.setMode(mode);
if (totalVerts >= 65536) {
// make sure we create an UnsignedInt buffer so
// we can fit all of the meshes
formatForBuf[Type.Index.ordinal()] = Format.UnsignedInt;
} else {
formatForBuf[Type.Index.ordinal()] = Format.UnsignedShort;
}
// generate output buffers based on retrieved info
for (int i = 0; i < compsForBuf.length; i++) {
if (compsForBuf[i] == 0) {
continue;
}
Buffer data;
if (i == Type.Index.ordinal()) {
data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalTris);
} else {
data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalVerts);
}
VertexBuffer vb = new VertexBuffer(Type.values()[i]);
vb.setupData(Usage.Static, compsForBuf[i], formatForBuf[i], data);
vb.setNormalized(normForBuf[i]);
outMesh.setBuffer(vb);
}
int globalVertIndex = 0;
int globalTriIndex = 0;
for (Geometry geom : geometries) {
Mesh inMesh = geom.getMesh();
geom.computeWorldMatrix();
Matrix4f worldMatrix = geom.getWorldMatrix();
int geomVertCount = inMesh.getVertexCount();
int geomTriCount = inMesh.getTriangleCount();
for (int bufType = 0; bufType < compsForBuf.length; bufType++) {
VertexBuffer inBuf = inMesh.getBuffer(Type.values()[bufType]);
VertexBuffer outBuf = outMesh.getBuffer(Type.values()[bufType]);
if (inBuf == null || outBuf == null) {
continue;
}
if (Type.Index.ordinal() == bufType) {
int components = compsForBuf[bufType];
IndexBuffer inIdx = inMesh.getIndicesAsList();
IndexBuffer outIdx = outMesh.getIndexBuffer();
for (int tri = 0; tri < geomTriCount; tri++) {
for (int comp = 0; comp < components; comp++) {
int idx = inIdx.get(tri * components + comp) + globalVertIndex;
outIdx.put((globalTriIndex + tri) * components + comp, idx);
}
}
} else if (Type.Position.ordinal() == bufType) {
FloatBuffer inPos = (FloatBuffer) inBuf.getDataReadOnly();
FloatBuffer outPos = (FloatBuffer) outBuf.getData();
doTransformVerts(inPos, globalVertIndex, outPos, worldMatrix);
} else if (Type.Normal.ordinal() == bufType) {
FloatBuffer inPos = (FloatBuffer) inBuf.getDataReadOnly();
FloatBuffer outPos = (FloatBuffer) outBuf.getData();
doTransformNorms(inPos, globalVertIndex, outPos, worldMatrix);
} else if (Type.Tangent.ordinal() == bufType) {
FloatBuffer inPos = (FloatBuffer) inBuf.getDataReadOnly();
FloatBuffer outPos = (FloatBuffer) outBuf.getData();
int components = inBuf.getNumComponents();
doTransformTangents(inPos, globalVertIndex, components, outPos, worldMatrix);
} else {
inBuf.copyElements(0, outBuf, globalVertIndex, geomVertCount);
}
}
globalVertIndex += geomVertCount;
globalTriIndex += geomTriCount;
}
}
use of com.jme3.material.Material in project jmonkeyengine by jMonkeyEngine.
the class TextureAtlas method makeAtlasBatch.
/**
* 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);
applyAtlasCoords(geometries, mesh, atlas);
mesh.updateCounts();
mesh.updateBound();
geom.setMesh(mesh);
Material mat = new Material(mgr, "Common/MatDefs/Light/Lighting.j3md");
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;
}
use of com.jme3.material.Material in project jmonkeyengine by jMonkeyEngine.
the class MaterialMatParamTest method material.
private void material(String path) {
AssetManager assetManager = TestUtil.createAssetManager();
geometry.setMaterial(new Material(assetManager, path));
}
use of com.jme3.material.Material in project jmonkeyengine by jMonkeyEngine.
the class MaterialMatParamTest method testRemoveTexture.
@Test
public void testRemoveTexture() {
material("Common/MatDefs/Light/Lighting.j3md");
Texture2D tex = new Texture2D(128, 128, Format.RGBA8);
reset();
inputMpo(mpoTexture2D("DiffuseMap", tex));
outDefines(def("DIFFUSEMAP", VarType.Texture2D, tex));
outUniforms(uniform("DiffuseMap", VarType.Int, 0));
outTextures(tex);
reset();
geometry.clearMatParamOverrides();
root.updateGeometricState();
outDefines();
outUniforms();
outTextures();
}
use of com.jme3.material.Material in project jmonkeyengine by jMonkeyEngine.
the class MaterialMatParamTest method testRemoveTextureOverride.
@Test
public void testRemoveTextureOverride() {
material("Common/MatDefs/Light/Lighting.j3md");
Texture2D tex1 = new Texture2D(128, 128, Format.RGBA8);
Texture2D tex2 = new Texture2D(128, 128, Format.RGBA8);
reset();
inputMp(mpoTexture2D("DiffuseMap", tex1));
outDefines(def("DIFFUSEMAP", VarType.Texture2D, tex1));
outUniforms(uniform("DiffuseMap", VarType.Int, 0));
outTextures(tex1);
reset();
inputMpo(mpoTexture2D("DiffuseMap", tex2));
outDefines(def("DIFFUSEMAP", VarType.Texture2D, tex2));
outUniforms(uniform("DiffuseMap", VarType.Int, 0));
outTextures(tex2);
reset();
geometry.clearMatParamOverrides();
root.updateGeometricState();
outDefines(def("DIFFUSEMAP", VarType.Texture2D, tex1));
outUniforms(uniform("DiffuseMap", VarType.Int, 0));
outTextures(tex1);
}
Aggregations