Skip to content

Commit

Permalink
Cleaned up BatchNode a bit and implemented collideWith to work only w…
Browse files Browse the repository at this point in the history
…ith non-batched children.
  • Loading branch information
tomocesnik committed Feb 26, 2016
1 parent 4047d2d commit 1073eba
Showing 1 changed file with 33 additions and 94 deletions.
127 changes: 33 additions & 94 deletions jme3-core/src/main/java/com/jme3/scene/BatchNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -48,13 +40,22 @@
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.
Expand All @@ -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>();
/**
Expand Down Expand Up @@ -118,7 +119,6 @@ public void onMeshChange(Geometry geom) {
public void onGeoemtryUnassociated(Geometry geom) {
setNeedsFullRebatch(true);
}


protected Matrix4f getTransformMatrix(Geometry g){
return g.cachedWorldMat;
Expand Down Expand Up @@ -166,18 +166,18 @@ protected void updateSubBatch(Geometry bg) {
*/
public void batch() {
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.getArray()) {
batch.geometry.setIgnoreTransform(true);
batch.geometry.setUserData(UserData.JME_PHYSICSIGNORE, true);
}
}

protected void doBatch() {
Map<Material, List<Geometry>> matMap = new HashMap<Material, List<Geometry>>();
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();
Expand Down Expand Up @@ -221,7 +221,7 @@ protected void doBatch() {

batch.geometry.setMesh(m);
batch.geometry.getMesh().updateCounts();
batch.geometry.updateModelBound();
batch.geometry.updateModelBound();
batches.add(batch);
}
if (batches.size() > 0) {
Expand Down Expand Up @@ -271,7 +271,7 @@ private void unbatchSubGraph(Spatial s) {
}


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) {

Expand Down Expand Up @@ -304,7 +304,7 @@ private void gatherGeomerties(Map<Material, List<Geometry>> map, Spatial n, bool
if (child instanceof BatchNode) {
continue;
}
gatherGeomerties(map, child, rebatch);
gatherGeometries(map, child, rebatch);
}
}

Expand All @@ -319,7 +319,7 @@ private Batch findBatchByMaterial(Material m) {
return null;
}

private boolean isBatch(Spatial s) {
public final boolean isBatch(Spatial s) {
for (Batch batch : batches.getArray()) {
if (batch.geometry == s) {
return true;
Expand All @@ -336,9 +336,6 @@ private boolean isBatch(Spatial s) {
*/
@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");
}

Expand All @@ -356,74 +353,7 @@ public Material getMaterial() {
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;
}

/**
Expand Down Expand Up @@ -494,7 +424,7 @@ private void mergeGeometries(Mesh outMesh, List<Geometry> geometries) {
if (mode != null && mode != listMode) {
throw new UnsupportedOperationException("Cannot combine different"
+ " primitive types: " + mode + " != " + listMode);
}
}
mode = listMode;
if (mode == Mesh.Mode.Lines) {
if (lineWidth != 1f && listLineWidth != lineWidth) {
Expand All @@ -510,8 +440,7 @@ private void mergeGeometries(Mesh outMesh, List<Geometry> geometries) {
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;
Expand Down Expand Up @@ -733,7 +662,6 @@ private void doCopyBuffer(FloatBuffer inBuf, int offset, FloatBuffer outBuf, int
}

protected class Batch {

/**
* update the batchesByGeom map for this batch with the given List of geometries
* @param list
Expand All @@ -745,7 +673,7 @@ void updateGeomList(List<Geometry> list) {
}
}
}
Geometry geometry;
Geometry geometry;
}

protected void setNeedsFullRebatch(boolean needsFullRebatch) {
Expand All @@ -771,4 +699,15 @@ public Node clone(boolean cloneMaterials) {
}
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;
}
}

0 comments on commit 1073eba

Please sign in to comment.