|
@@ -80,6 +80,7 @@ public class BatchNode extends Node implements Savable {
|
|
private float[] tmpFloatT;
|
|
private float[] tmpFloatT;
|
|
int maxVertCount = 0;
|
|
int maxVertCount = 0;
|
|
boolean useTangents = false;
|
|
boolean useTangents = false;
|
|
|
|
+ boolean needsFullRebatch = true;
|
|
|
|
|
|
/**
|
|
/**
|
|
* Construct a batchNode
|
|
* Construct a batchNode
|
|
@@ -178,16 +179,25 @@ public class BatchNode extends Node implements Savable {
|
|
}
|
|
}
|
|
|
|
|
|
protected void doBatch() {
|
|
protected void doBatch() {
|
|
- ///List<Geometry> tmpList = new ArrayList<Geometry>();
|
|
|
|
Map<Material, List<Geometry>> matMap = new HashMap<Material, List<Geometry>>();
|
|
Map<Material, List<Geometry>> matMap = new HashMap<Material, List<Geometry>>();
|
|
maxVertCount = 0;
|
|
maxVertCount = 0;
|
|
- gatherGeomerties(matMap, this);
|
|
|
|
- batches.clear();
|
|
|
|
int nbGeoms = 0;
|
|
int nbGeoms = 0;
|
|
|
|
+
|
|
|
|
+ gatherGeomerties(matMap, this, needsFullRebatch);
|
|
|
|
+ if (needsFullRebatch) {
|
|
|
|
+ for (Batch batch : batches.values()) {
|
|
|
|
+ batch.geometry.removeFromParent();
|
|
|
|
+ }
|
|
|
|
+ batches.clear();
|
|
|
|
+ }
|
|
|
|
+
|
|
for (Material material : matMap.keySet()) {
|
|
for (Material material : matMap.keySet()) {
|
|
Mesh m = new Mesh();
|
|
Mesh m = new Mesh();
|
|
List<Geometry> list = matMap.get(material);
|
|
List<Geometry> list = matMap.get(material);
|
|
nbGeoms += list.size();
|
|
nbGeoms += list.size();
|
|
|
|
+ if (!needsFullRebatch) {
|
|
|
|
+ list.add(batches.get(material).geometry);
|
|
|
|
+ }
|
|
mergeGeometries(m, list);
|
|
mergeGeometries(m, list);
|
|
m.setDynamic();
|
|
m.setDynamic();
|
|
Batch batch = new Batch();
|
|
Batch batch = new Batch();
|
|
@@ -202,30 +212,36 @@ public class BatchNode extends Node implements Savable {
|
|
batch.geometry.getMesh().updateBound();
|
|
batch.geometry.getMesh().updateBound();
|
|
batches.put(material, batch);
|
|
batches.put(material, batch);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ logger.log(Level.INFO, "Batched {0} geometries in {1} batches.", new Object[]{nbGeoms, batches.size()});
|
|
|
|
+
|
|
|
|
+
|
|
//init temp float arrays
|
|
//init temp float arrays
|
|
tmpFloat = new float[maxVertCount * 3];
|
|
tmpFloat = new float[maxVertCount * 3];
|
|
tmpFloatN = new float[maxVertCount * 3];
|
|
tmpFloatN = new float[maxVertCount * 3];
|
|
if (useTangents) {
|
|
if (useTangents) {
|
|
tmpFloatT = new float[maxVertCount * 4];
|
|
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 (n.getClass() == Geometry.class) {
|
|
|
|
|
|
if (!isBatch(n) && n.getBatchHint() != BatchHint.Never) {
|
|
if (!isBatch(n) && n.getBatchHint() != BatchHint.Never) {
|
|
Geometry g = (Geometry) n;
|
|
Geometry g = (Geometry) n;
|
|
- if (g.getMaterial() == null) {
|
|
|
|
- throw new IllegalStateException("No material is set for Geometry: " + g.getName() + " please set a material before batching");
|
|
|
|
- }
|
|
|
|
- List<Geometry> list = map.get(g.getMaterial());
|
|
|
|
- if (list == null) {
|
|
|
|
- list = new ArrayList<Geometry>();
|
|
|
|
- map.put(g.getMaterial(), list);
|
|
|
|
|
|
+ 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");
|
|
|
|
+ }
|
|
|
|
+ List<Geometry> list = map.get(g.getMaterial());
|
|
|
|
+ if (list == null) {
|
|
|
|
+ list = new ArrayList<Geometry>();
|
|
|
|
+ map.put(g.getMaterial(), list);
|
|
|
|
+ }
|
|
|
|
+ g.setTransformRefresh();
|
|
|
|
+ list.add(g);
|
|
}
|
|
}
|
|
- list.add(g);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
} else if (n instanceof Node) {
|
|
} else if (n instanceof Node) {
|
|
@@ -233,7 +249,7 @@ public class BatchNode extends Node implements Savable {
|
|
if (child instanceof BatchNode) {
|
|
if (child instanceof BatchNode) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- gatherGeomerties(map, child);
|
|
|
|
|
|
+ gatherGeomerties(map, child, rebatch);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -465,12 +481,12 @@ public class BatchNode extends Node implements Savable {
|
|
}
|
|
}
|
|
} else if (VertexBuffer.Type.Position.ordinal() == bufType) {
|
|
} else if (VertexBuffer.Type.Position.ordinal() == bufType) {
|
|
FloatBuffer inPos = (FloatBuffer) inBuf.getData();
|
|
FloatBuffer inPos = (FloatBuffer) inBuf.getData();
|
|
- FloatBuffer outPos = (FloatBuffer) outBuf.getData();
|
|
|
|
- doCopyBuffer(inPos, globalVertIndex, outPos,3);
|
|
|
|
|
|
+ FloatBuffer outPos = (FloatBuffer) outBuf.getData();
|
|
|
|
+ doCopyBuffer(inPos, globalVertIndex, outPos, 3);
|
|
} else if (VertexBuffer.Type.Normal.ordinal() == bufType || VertexBuffer.Type.Tangent.ordinal() == bufType) {
|
|
} else if (VertexBuffer.Type.Normal.ordinal() == bufType || VertexBuffer.Type.Tangent.ordinal() == bufType) {
|
|
FloatBuffer inPos = (FloatBuffer) inBuf.getData();
|
|
FloatBuffer inPos = (FloatBuffer) inBuf.getData();
|
|
- FloatBuffer outPos = (FloatBuffer) outBuf.getData();
|
|
|
|
- doCopyBuffer(inPos, globalVertIndex, outPos,compsForBuf[bufType]);
|
|
|
|
|
|
+ FloatBuffer outPos = (FloatBuffer) outBuf.getData();
|
|
|
|
+ doCopyBuffer(inPos, globalVertIndex, outPos, compsForBuf[bufType]);
|
|
if (VertexBuffer.Type.Tangent.ordinal() == bufType) {
|
|
if (VertexBuffer.Type.Tangent.ordinal() == bufType) {
|
|
useTangents = true;
|
|
useTangents = true;
|
|
}
|
|
}
|
|
@@ -584,9 +600,9 @@ public class BatchNode extends Node implements Savable {
|
|
tmpFloatT[tanIndex++] = tan.x;
|
|
tmpFloatT[tanIndex++] = tan.x;
|
|
tmpFloatT[tanIndex++] = tan.y;
|
|
tmpFloatT[tanIndex++] = tan.y;
|
|
tmpFloatT[tanIndex++] = tan.z;
|
|
tmpFloatT[tanIndex++] = tan.z;
|
|
-
|
|
|
|
|
|
+
|
|
//Skipping 4th element of tangent buffer (handedness)
|
|
//Skipping 4th element of tangent buffer (handedness)
|
|
- tanIndex++;
|
|
|
|
|
|
+ tanIndex++;
|
|
|
|
|
|
}
|
|
}
|
|
vars.release();
|
|
vars.release();
|
|
@@ -626,4 +642,12 @@ public class BatchNode extends Node implements Savable {
|
|
Geometry geometry;
|
|
Geometry geometry;
|
|
boolean needMeshUpdate = false;
|
|
boolean needMeshUpdate = false;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ protected void setNeedsFullRebatch(boolean needsFullRebatch) {
|
|
|
|
+ this.needsFullRebatch = needsFullRebatch;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public int getOffsetIndex(Geometry batchedGeometry){
|
|
|
|
+ return batchedGeometry.startIndex;
|
|
|
|
+ }
|
|
}
|
|
}
|