private void gatherGeomerties(Map<Material, List<Geometry>> map, Spatial n, boolean rebatch) { if (n instanceof Geometry) { 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"); } List<Geometry> list = map.get(g.getMaterial()); if (list == null) { // trying to compare materials with the isEqual method for (Map.Entry<Material, List<Geometry>> mat : map.entrySet()) { if (g.getMaterial().contentEquals(mat.getKey())) { list = mat.getValue(); } } } if (list == null) { 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, rebatch); } } }
protected void doBatch() { Map<Material, List<Geometry>> matMap = new HashMap<Material, List<Geometry>>(); int nbGeoms = 0; gatherGeomerties(matMap, this, needsFullRebatch); if (needsFullRebatch) { for (Batch batch : batches.getArray()) { batch.geometry.removeFromParent(); } batches.clear(); batchesByGeom.clear(); } // only reset maxVertCount if there is something new to batch if (matMap.size() > 0) { maxVertCount = 0; } for (Map.Entry<Material, List<Geometry>> entry : matMap.entrySet()) { Mesh m = new Mesh(); Material material = entry.getKey(); List<Geometry> list = entry.getValue(); nbGeoms += list.size(); String batchName = name + "-batch" + batches.size(); Batch batch; if (!needsFullRebatch) { 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); m.setDynamic(); batch.updateGeomList(list); batch.geometry = new Geometry(batchName); batch.geometry.setMaterial(material); this.attachChild(batch.geometry); batch.geometry.setMesh(m); batch.geometry.getMesh().updateCounts(); batch.geometry.getMesh().updateBound(); batches.add(batch); } if (batches.size() > 0) { needsFullRebatch = false; } logger.log( Level.FINE, "Batched {0} geometries in {1} batches.", new Object[] {nbGeoms, batches.size()}); // init the temp arrays if something has been batched only. if (matMap.size() > 0) { // TODO these arrays should be allocated by chunk instead to avoid recreating them each time // the batch is changed. // init temp float arrays tmpFloat = new float[maxVertCount * 3]; tmpFloatN = new float[maxVertCount * 3]; if (useTangents) { tmpFloatT = new float[maxVertCount * 4]; } } }