|
|
|
@ -31,14 +31,6 @@ |
|
|
|
|
*/ |
|
|
|
|
package com.jme3.scene; |
|
|
|
|
|
|
|
|
|
import com.jme3.export.*; |
|
|
|
|
import com.jme3.material.Material; |
|
|
|
|
import com.jme3.math.Matrix4f; |
|
|
|
|
import com.jme3.math.Vector3f; |
|
|
|
|
import com.jme3.scene.mesh.IndexBuffer; |
|
|
|
|
import com.jme3.util.SafeArrayList; |
|
|
|
|
import com.jme3.util.TempVars; |
|
|
|
|
import java.io.IOException; |
|
|
|
|
import java.nio.Buffer; |
|
|
|
|
import java.nio.FloatBuffer; |
|
|
|
|
import java.util.ArrayList; |
|
|
|
@ -48,13 +40,22 @@ import java.util.Map; |
|
|
|
|
import java.util.logging.Level; |
|
|
|
|
import java.util.logging.Logger; |
|
|
|
|
|
|
|
|
|
import com.jme3.collision.Collidable; |
|
|
|
|
import com.jme3.collision.CollisionResults; |
|
|
|
|
import com.jme3.material.Material; |
|
|
|
|
import com.jme3.math.Matrix4f; |
|
|
|
|
import com.jme3.math.Vector3f; |
|
|
|
|
import com.jme3.scene.mesh.IndexBuffer; |
|
|
|
|
import com.jme3.util.SafeArrayList; |
|
|
|
|
import com.jme3.util.TempVars; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* BatchNode holds geometries that are a batched version of all the geometries that are in its sub scenegraph. |
|
|
|
|
* There is one geometry per different material in the sub tree. |
|
|
|
|
* The geometries are directly attached to the node in the scene graph. |
|
|
|
|
* Usage is like any other node except you have to call the {@link #batch()} method once all the geometries have been attached to the sub scene graph and their material set |
|
|
|
|
* (see todo more automagic for further enhancements) |
|
|
|
|
* All the geometries that have been batched are set to {@link CullHint#Always} to not render them. |
|
|
|
|
* All the geometries that have been batched are set to not be rendered - {@link CullHint} is left intact. |
|
|
|
|
* The sub geometries can be transformed as usual, their transforms are used to update the mesh of the geometryBatch. |
|
|
|
|
* Sub geoms can be removed but it may be slower than the normal spatial removing |
|
|
|
|
* Sub geoms can be added after the batch() method has been called but won't be batched and will just be rendered as normal geometries. |
|
|
|
@ -72,7 +73,7 @@ public class BatchNode extends GeometryGroupNode { |
|
|
|
|
*/ |
|
|
|
|
protected SafeArrayList<Batch> batches = new SafeArrayList<Batch>(Batch.class); |
|
|
|
|
/** |
|
|
|
|
* a map storing he batches by geometry to quickly acces the batch when updating |
|
|
|
|
* a map for storing the batches by geometry to quickly access the batch when updating |
|
|
|
|
*/ |
|
|
|
|
protected Map<Geometry, Batch> batchesByGeom = new HashMap<Geometry, Batch>(); |
|
|
|
|
/** |
|
|
|
@ -119,7 +120,6 @@ public class BatchNode extends GeometryGroupNode { |
|
|
|
|
setNeedsFullRebatch(true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected Matrix4f getTransformMatrix(Geometry g){ |
|
|
|
|
return g.cachedWorldMat; |
|
|
|
|
} |
|
|
|
@ -177,7 +177,7 @@ public class BatchNode extends GeometryGroupNode { |
|
|
|
|
Map<Material, List<Geometry>> matMap = new HashMap<Material, List<Geometry>>(); |
|
|
|
|
int nbGeoms = 0; |
|
|
|
|
|
|
|
|
|
gatherGeomerties(matMap, this, needsFullRebatch); |
|
|
|
|
gatherGeometries(matMap, this, needsFullRebatch); |
|
|
|
|
if (needsFullRebatch) { |
|
|
|
|
for (Batch batch : batches.getArray()) { |
|
|
|
|
batch.geometry.removeFromParent(); |
|
|
|
@ -271,7 +271,7 @@ public class BatchNode extends GeometryGroupNode { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void gatherGeomerties(Map<Material, List<Geometry>> map, Spatial n, boolean rebatch) { |
|
|
|
|
private void gatherGeometries(Map<Material, List<Geometry>> map, Spatial n, boolean rebatch) { |
|
|
|
|
|
|
|
|
|
if (n instanceof Geometry) { |
|
|
|
|
|
|
|
|
@ -304,7 +304,7 @@ public class BatchNode extends GeometryGroupNode { |
|
|
|
|
if (child instanceof BatchNode) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
gatherGeomerties(map, child, rebatch); |
|
|
|
|
gatherGeometries(map, child, rebatch); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -319,7 +319,7 @@ public class BatchNode extends GeometryGroupNode { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private boolean isBatch(Spatial s) { |
|
|
|
|
public final boolean isBatch(Spatial s) { |
|
|
|
|
for (Batch batch : batches.getArray()) { |
|
|
|
|
if (batch.geometry == s) { |
|
|
|
|
return true; |
|
|
|
@ -336,9 +336,6 @@ public class BatchNode extends GeometryGroupNode { |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public void setMaterial(Material material) { |
|
|
|
|
// for (Batch batch : batches.values()) {
|
|
|
|
|
// batch.geometry.setMaterial(material);
|
|
|
|
|
// }
|
|
|
|
|
throw new UnsupportedOperationException("Unsupported for now, please set the material on the geoms before batching"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -356,74 +353,7 @@ public class BatchNode extends GeometryGroupNode { |
|
|
|
|
Batch b = batches.iterator().next(); |
|
|
|
|
return b.geometry.getMaterial(); |
|
|
|
|
} |
|
|
|
|
return null;//material;
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// /**
|
|
|
|
|
// * Sets the material to the a specific batch of this BatchNode
|
|
|
|
|
// *
|
|
|
|
|
// *
|
|
|
|
|
// * @param material the material to use for this geometry
|
|
|
|
|
// */
|
|
|
|
|
// public void setMaterial(Material material,int batchIndex) {
|
|
|
|
|
// if (!batches.isEmpty()) {
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// /**
|
|
|
|
|
// * Returns the material that is used for the first batch of this BatchNode
|
|
|
|
|
// *
|
|
|
|
|
// * use getMaterial(Material material,int batchIndex) to get a material from a specific batch
|
|
|
|
|
// *
|
|
|
|
|
// * @return the material that is used for the first batch of this BatchNode
|
|
|
|
|
// *
|
|
|
|
|
// * @see #setMaterial(com.jme3.material.Material)
|
|
|
|
|
// */
|
|
|
|
|
// public Material getMaterial(int batchIndex) {
|
|
|
|
|
// if (!batches.isEmpty()) {
|
|
|
|
|
// Batch b = batches.get(batches.keySet().iterator().next());
|
|
|
|
|
// return b.geometry.getMaterial();
|
|
|
|
|
// }
|
|
|
|
|
// return null;//material;
|
|
|
|
|
// }
|
|
|
|
|
@Override |
|
|
|
|
public void write(JmeExporter ex) throws IOException { |
|
|
|
|
super.write(ex); |
|
|
|
|
OutputCapsule oc = ex.getCapsule(this); |
|
|
|
|
//
|
|
|
|
|
// if (material != null) {
|
|
|
|
|
// oc.write(material.getAssetName(), "materialName", null);
|
|
|
|
|
// }
|
|
|
|
|
// oc.write(material, "material", null);
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public void read(JmeImporter im) throws IOException { |
|
|
|
|
super.read(im); |
|
|
|
|
InputCapsule ic = im.getCapsule(this); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// material = null;
|
|
|
|
|
// String matName = ic.readString("materialName", null);
|
|
|
|
|
// if (matName != null) {
|
|
|
|
|
// // Material name is set,
|
|
|
|
|
// // Attempt to load material via J3M
|
|
|
|
|
// try {
|
|
|
|
|
// material = im.getAssetManager().loadMaterial(matName);
|
|
|
|
|
// } catch (AssetNotFoundException ex) {
|
|
|
|
|
// // Cannot find J3M file.
|
|
|
|
|
// logger.log(Level.FINE, "Could not load J3M file {0} for Geometry.",
|
|
|
|
|
// matName);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// // If material is NULL, try to load it from the geometry
|
|
|
|
|
// if (material == null) {
|
|
|
|
|
// material = (Material) ic.readSavable("material", null);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -510,8 +440,7 @@ public class BatchNode extends GeometryGroupNode { |
|
|
|
|
outMesh.setMode(mode); |
|
|
|
|
outMesh.setLineWidth(lineWidth); |
|
|
|
|
if (totalVerts >= 65536) { |
|
|
|
|
// make sure we create an UnsignedInt buffer so
|
|
|
|
|
// we can fit all of the meshes
|
|
|
|
|
// make sure we create an UnsignedInt buffer so we can fit all of the meshes
|
|
|
|
|
formatForBuf[VertexBuffer.Type.Index.ordinal()] = VertexBuffer.Format.UnsignedInt; |
|
|
|
|
} else { |
|
|
|
|
formatForBuf[VertexBuffer.Type.Index.ordinal()] = VertexBuffer.Format.UnsignedShort; |
|
|
|
@ -733,7 +662,6 @@ public class BatchNode extends GeometryGroupNode { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected class Batch { |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* update the batchesByGeom map for this batch with the given List of geometries |
|
|
|
|
* @param list |
|
|
|
@ -771,4 +699,15 @@ public class BatchNode extends GeometryGroupNode { |
|
|
|
|
} |
|
|
|
|
return clone; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public int collideWith(Collidable other, CollisionResults results) { |
|
|
|
|
int total = 0; |
|
|
|
|
for (Spatial child : children.getArray()){ |
|
|
|
|
if (!isBatch(child)) { |
|
|
|
|
total += child.collideWith(other, results); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return total; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|