BatchNode enhancements :
- batching after adding a new geometry only does an incremental batch instead of rebatching all geometries - there is now a getOffsetIndex(geometry) method that returns the index of the first vertex of the geometry in the batch. git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9176 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
446c03935e
commit
03da8d5316
@ -80,6 +80,7 @@ public class BatchNode extends Node implements Savable {
|
||||
private float[] tmpFloatT;
|
||||
int maxVertCount = 0;
|
||||
boolean useTangents = false;
|
||||
boolean needsFullRebatch = true;
|
||||
|
||||
/**
|
||||
* Construct a batchNode
|
||||
@ -178,16 +179,25 @@ public class BatchNode extends Node implements Savable {
|
||||
}
|
||||
|
||||
protected void doBatch() {
|
||||
///List<Geometry> tmpList = new ArrayList<Geometry>();
|
||||
Map<Material, List<Geometry>> matMap = new HashMap<Material, List<Geometry>>();
|
||||
maxVertCount = 0;
|
||||
gatherGeomerties(matMap, this);
|
||||
batches.clear();
|
||||
int nbGeoms = 0;
|
||||
|
||||
gatherGeomerties(matMap, this, needsFullRebatch);
|
||||
if (needsFullRebatch) {
|
||||
for (Batch batch : batches.values()) {
|
||||
batch.geometry.removeFromParent();
|
||||
}
|
||||
batches.clear();
|
||||
}
|
||||
|
||||
for (Material material : matMap.keySet()) {
|
||||
Mesh m = new Mesh();
|
||||
List<Geometry> list = matMap.get(material);
|
||||
nbGeoms += list.size();
|
||||
if (!needsFullRebatch) {
|
||||
list.add(batches.get(material).geometry);
|
||||
}
|
||||
mergeGeometries(m, list);
|
||||
m.setDynamic();
|
||||
Batch batch = new Batch();
|
||||
@ -202,21 +212,25 @@ public class BatchNode extends Node implements Savable {
|
||||
batch.geometry.getMesh().updateBound();
|
||||
batches.put(material, batch);
|
||||
}
|
||||
|
||||
logger.log(Level.INFO, "Batched {0} geometries in {1} batches.", new Object[]{nbGeoms, batches.size()});
|
||||
|
||||
|
||||
//init temp float arrays
|
||||
tmpFloat = new float[maxVertCount * 3];
|
||||
tmpFloatN = new float[maxVertCount * 3];
|
||||
if (useTangents) {
|
||||
tmpFloatT = new float[maxVertCount * 4];
|
||||
}
|
||||
logger.log(Level.INFO, "Batched {0} geometries in {1} batches.", new Object[]{nbGeoms, batches.size()});
|
||||
}
|
||||
|
||||
private void gatherGeomerties(Map<Material, List<Geometry>> map, Spatial n) {
|
||||
private void gatherGeomerties(Map<Material, List<Geometry>> map, Spatial n, boolean rebatch) {
|
||||
|
||||
if (n.getClass() == Geometry.class) {
|
||||
|
||||
if (!isBatch(n) && n.getBatchHint() != BatchHint.Never) {
|
||||
Geometry g = (Geometry) n;
|
||||
if (!g.isBatched() || rebatch) {
|
||||
if (g.getMaterial() == null) {
|
||||
throw new IllegalStateException("No material is set for Geometry: " + g.getName() + " please set a material before batching");
|
||||
}
|
||||
@ -225,15 +239,17 @@ public class BatchNode extends Node implements Savable {
|
||||
list = new ArrayList<Geometry>();
|
||||
map.put(g.getMaterial(), list);
|
||||
}
|
||||
g.setTransformRefresh();
|
||||
list.add(g);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (n instanceof Node) {
|
||||
for (Spatial child : ((Node) n).getChildren()) {
|
||||
if (child instanceof BatchNode) {
|
||||
continue;
|
||||
}
|
||||
gatherGeomerties(map, child);
|
||||
gatherGeomerties(map, child, rebatch);
|
||||
}
|
||||
}
|
||||
|
||||
@ -466,11 +482,11 @@ public class BatchNode extends Node implements Savable {
|
||||
} else if (VertexBuffer.Type.Position.ordinal() == bufType) {
|
||||
FloatBuffer inPos = (FloatBuffer) inBuf.getData();
|
||||
FloatBuffer outPos = (FloatBuffer) outBuf.getData();
|
||||
doCopyBuffer(inPos, globalVertIndex, outPos,3);
|
||||
doCopyBuffer(inPos, globalVertIndex, outPos, 3);
|
||||
} else if (VertexBuffer.Type.Normal.ordinal() == bufType || VertexBuffer.Type.Tangent.ordinal() == bufType) {
|
||||
FloatBuffer inPos = (FloatBuffer) inBuf.getData();
|
||||
FloatBuffer outPos = (FloatBuffer) outBuf.getData();
|
||||
doCopyBuffer(inPos, globalVertIndex, outPos,compsForBuf[bufType]);
|
||||
doCopyBuffer(inPos, globalVertIndex, outPos, compsForBuf[bufType]);
|
||||
if (VertexBuffer.Type.Tangent.ordinal() == bufType) {
|
||||
useTangents = true;
|
||||
}
|
||||
@ -626,4 +642,12 @@ public class BatchNode extends Node implements Savable {
|
||||
Geometry geometry;
|
||||
boolean needMeshUpdate = false;
|
||||
}
|
||||
|
||||
protected void setNeedsFullRebatch(boolean needsFullRebatch) {
|
||||
this.needsFullRebatch = needsFullRebatch;
|
||||
}
|
||||
|
||||
public int getOffsetIndex(Geometry batchedGeometry){
|
||||
return batchedGeometry.startIndex;
|
||||
}
|
||||
}
|
||||
|
@ -322,8 +322,8 @@ public class Geometry extends Spatial {
|
||||
this.startIndex = 0;
|
||||
prevBatchTransforms = null;
|
||||
cachedOffsetMat = null;
|
||||
//once the geometry is removed from the screnegraph we call batch on the batchNode before unreferencing it.
|
||||
this.batchNode.batch();
|
||||
//once the geometry is removed from the screnegraph the batchNode needs to be rebatched.
|
||||
this.batchNode.setNeedsFullRebatch(true);
|
||||
this.batchNode = null;
|
||||
setCullHint(CullHint.Dynamic);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user