- Changed BatchNode and GeometryBatchFactory according to material recent changes.

- BatchNode now does incremental batch upon adding a new geom to the batch (was there before but didn't work properly).

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9361 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
rem..om 13 years ago
parent 960837fe02
commit d33cbce333
  1. 57
      engine/src/core/com/jme3/scene/BatchNode.java
  2. 2
      engine/src/core/com/jme3/scene/SimpleBatchNode.java
  3. 2
      engine/src/tools/jme3tools/optimize/GeometryBatchFactory.java

@ -37,6 +37,7 @@ import com.jme3.math.Matrix4f;
import com.jme3.math.Transform; import com.jme3.math.Transform;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.scene.mesh.IndexBuffer; import com.jme3.scene.mesh.IndexBuffer;
import com.jme3.util.SafeArrayList;
import com.jme3.util.TempVars; import com.jme3.util.TempVars;
import java.io.IOException; import java.io.IOException;
import java.nio.Buffer; import java.nio.Buffer;
@ -68,11 +69,11 @@ public class BatchNode extends Node implements Savable {
private static final Logger logger = Logger.getLogger(BatchNode.class.getName()); private static final Logger logger = Logger.getLogger(BatchNode.class.getName());
/** /**
* the map of geometry holding the batched meshes * the list of geometry holding the batched meshes
*/ */
protected Map<Material, Batch> batches = new HashMap<Material, Batch>(); protected SafeArrayList<Batch> batches = new SafeArrayList<Batch>(Batch.class);
/** /**
* a map storing he batches by geometry to qickly acces the batch when updating * a map storing he batches by geometry to quickly acces the batch when updating
*/ */
protected Map<Geometry, Batch> batchesByGeom = new HashMap<Geometry, Batch>(); protected Map<Geometry, Batch> batchesByGeom = new HashMap<Geometry, Batch>();
/** /**
@ -119,7 +120,7 @@ public class BatchNode extends Node implements Savable {
child.updateGeometricState(); child.updateGeometricState();
} }
for (Batch batch : batches.values()) { for (Batch batch : batches.getArray()) {
if (batch.needMeshUpdate) { if (batch.needMeshUpdate) {
batch.geometry.getMesh().updateBound(); batch.geometry.getMesh().updateBound();
batch.geometry.updateWorldBound(); batch.geometry.updateWorldBound();
@ -176,7 +177,7 @@ public class BatchNode extends Node implements Savable {
public void batch() { public void batch() {
doBatch(); doBatch();
//we set the batch geometries to ignore transforms to avoid transforms of parent nodes to be applied twice //we set the batch geometries to ignore transforms to avoid transforms of parent nodes to be applied twice
for (Batch batch : batches.values()) { for (Batch batch : batches.getArray()) {
batch.geometry.setIgnoreTransform(true); batch.geometry.setIgnoreTransform(true);
} }
} }
@ -188,7 +189,7 @@ public class BatchNode extends Node implements Savable {
gatherGeomerties(matMap, this, needsFullRebatch); gatherGeomerties(matMap, this, needsFullRebatch);
if (needsFullRebatch) { if (needsFullRebatch) {
for (Batch batch : batches.values()) { for (Batch batch : batches.getArray()) {
batch.geometry.removeFromParent(); batch.geometry.removeFromParent();
} }
batches.clear(); batches.clear();
@ -199,15 +200,26 @@ public class BatchNode extends Node implements Savable {
Material material = entry.getKey(); Material material = entry.getKey();
List<Geometry> list = entry.getValue(); List<Geometry> list = entry.getValue();
nbGeoms += list.size(); nbGeoms += list.size();
String batchName = name + "-batch" + batches.size();
Batch batch;
if (!needsFullRebatch) { if (!needsFullRebatch) {
list.add(batches.get(material).geometry); batch = findBatchByMaterial(material);
if (batch != null) {
list.add(0, batch.geometry);
batchName = batch.geometry.getName();
batch.geometry.removeFromParent();
} else {
batch = new Batch();
}
} else {
batch = new Batch();
} }
mergeGeometries(m, list); mergeGeometries(m, list);
m.setDynamic(); m.setDynamic();
Batch batch = new Batch();
batch.updateGeomList(list); batch.updateGeomList(list);
batch.geometry = new Geometry(name + "-batch" + batches.size()); batch.geometry = new Geometry(batchName);
batch.geometry.setMaterial(material); batch.geometry.setMaterial(material);
this.attachChild(batch.geometry); this.attachChild(batch.geometry);
@ -215,9 +227,13 @@ public class BatchNode extends Node implements Savable {
batch.geometry.setMesh(m); batch.geometry.setMesh(m);
batch.geometry.getMesh().updateCounts(); batch.geometry.getMesh().updateCounts();
batch.geometry.getMesh().updateBound(); batch.geometry.getMesh().updateBound();
batches.put(material, batch); batches.add(batch);
}
if (batches.size() > 0) {
needsFullRebatch = false;
} }
logger.log(Level.INFO, "Batched {0} geometries in {1} batches.", new Object[]{nbGeoms, batches.size()}); logger.log(Level.INFO, "Batched {0} geometries in {1} batches.", new Object[]{nbGeoms, batches.size()});
@ -241,9 +257,9 @@ public class BatchNode extends Node implements Savable {
} }
List<Geometry> list = map.get(g.getMaterial()); List<Geometry> list = map.get(g.getMaterial());
if (list == null) { if (list == null) {
//trying to compare materials with the contentEquals method //trying to compare materials with the isEqual method
for (Map.Entry<Material, List<Geometry>> mat : map.entrySet()) { for (Map.Entry<Material, List<Geometry>> mat : map.entrySet()) {
if (g.getMaterial().contentEquals(mat.getKey())) { if (g.getMaterial().dynamicHashCode() == mat.getKey().dynamicHashCode()) {
list = mat.getValue(); list = mat.getValue();
} }
} }
@ -268,8 +284,17 @@ public class BatchNode extends Node implements Savable {
} }
private Batch findBatchByMaterial(Material m) {
for (Batch batch : batches.getArray()) {
if (batch.geometry.getMaterial().dynamicHashCode() == m.dynamicHashCode()) {
return batch;
}
}
return null;
}
private boolean isBatch(Spatial s) { private boolean isBatch(Spatial s) {
for (Batch batch : batches.values()) { for (Batch batch : batches.getArray()) {
if (batch.geometry == s) { if (batch.geometry == s) {
return true; return true;
} }
@ -302,7 +327,7 @@ public class BatchNode extends Node implements Savable {
*/ */
public Material getMaterial() { public Material getMaterial() {
if (!batches.isEmpty()) { if (!batches.isEmpty()) {
Batch b = batches.get(batches.keySet().iterator().next()); Batch b = batches.iterator().next();
return b.geometry.getMaterial(); return b.geometry.getMaterial();
} }
return null;//material; return null;//material;
@ -466,7 +491,9 @@ public class BatchNode extends Node implements Savable {
for (Geometry geom : geometries) { for (Geometry geom : geometries) {
Mesh inMesh = geom.getMesh(); Mesh inMesh = geom.getMesh();
if (!isBatch(geom)) {
geom.batch(this, globalVertIndex); geom.batch(this, globalVertIndex);
}
int geomVertCount = inMesh.getVertexCount(); int geomVertCount = inMesh.getVertexCount();
int geomTriCount = inMesh.getTriangleCount(); int geomTriCount = inMesh.getTriangleCount();
@ -658,9 +685,11 @@ public class BatchNode extends Node implements Savable {
*/ */
void updateGeomList(List<Geometry> list) { void updateGeomList(List<Geometry> list) {
for (Geometry geom : list) { for (Geometry geom : list) {
if (!isBatch(geom)) {
batchesByGeom.put(geom, this); batchesByGeom.put(geom, this);
} }
} }
}
Geometry geometry; Geometry geometry;
boolean needMeshUpdate = false; boolean needMeshUpdate = false;
} }

@ -40,7 +40,7 @@ public class SimpleBatchNode extends BatchNode {
refreshFlags |= RF_TRANSFORM; refreshFlags |= RF_TRANSFORM;
setBoundRefresh(); setBoundRefresh();
for (Batch batch : batches.values()) { for (Batch batch : batches.getArray()) {
batch.geometry.setTransformRefresh(); batch.geometry.setTransformRefresh();
} }
} }

@ -291,7 +291,7 @@ public class GeometryBatchFactory {
if (outList == null) { if (outList == null) {
//trying to compare materials with the contentEquals method //trying to compare materials with the contentEquals method
for (Material mat : matToGeom.keySet()) { for (Material mat : matToGeom.keySet()) {
if (geom.getMaterial().contentEquals(mat)) { if (geom.getMaterial().dynamicHashCode() == mat.dynamicHashCode()) {
outList = matToGeom.get(mat); outList = matToGeom.get(mat);
} }
} }

Loading…
Cancel
Save