Merge pull request #196 from Bebul/collideWithOptimization

Collide with optimization
experimental
Kirill Vainer 10 years ago
commit 5508dc05f5
  1. 45
      jme3-core/src/main/java/com/jme3/bounding/BoundingBox.java
  2. 42
      jme3-core/src/main/java/com/jme3/bounding/BoundingSphere.java
  3. 11
      jme3-core/src/main/java/com/jme3/bounding/BoundingVolume.java
  4. 13
      jme3-core/src/main/java/com/jme3/scene/Node.java

@ -761,6 +761,35 @@ public class BoundingBox extends BoundingVolume {
}
}
private int collideWithRay(Ray ray) {
TempVars vars = TempVars.get();
try {
Vector3f diff = vars.vect1.set(ray.origin).subtractLocal(center);
Vector3f direction = vars.vect2.set(ray.direction);
//float[] t = {0f, Float.POSITIVE_INFINITY};
float[] t = vars.fWdU; // use one of the tempvars arrays
t[0] = 0;
t[1] = Float.POSITIVE_INFINITY;
float saveT0 = t[0], saveT1 = t[1];
boolean notEntirelyClipped = clip(+direction.x, -diff.x - xExtent, t)
&& clip(-direction.x, +diff.x - xExtent, t)
&& clip(+direction.y, -diff.y - yExtent, t)
&& clip(-direction.y, +diff.y - yExtent, t)
&& clip(+direction.z, -diff.z - zExtent, t)
&& clip(-direction.z, +diff.z - zExtent, t);
if (notEntirelyClipped && (t[0] != saveT0 || t[1] != saveT1)) {
if (t[1] > t[0]) return 2;
else return 1;
}
return 0;
} finally {
vars.release();
}
}
public int collideWith(Collidable other, CollisionResults results) {
if (other instanceof Ray) {
Ray ray = (Ray) other;
@ -777,6 +806,22 @@ public class BoundingBox extends BoundingVolume {
throw new UnsupportedCollisionException("With: " + other.getClass().getSimpleName());
}
}
@Override
public int collideWith(Collidable other) {
if (other instanceof Ray) {
Ray ray = (Ray) other;
return collideWithRay(ray);
} else if (other instanceof Triangle) {
Triangle t = (Triangle) other;
if (intersects(t.get1(), t.get2(), t.get3())) {
return 1;
}
return 0;
} else {
throw new UnsupportedCollisionException("With: " + other.getClass().getSimpleName());
}
}
/**
* C code ported from <a href="http://www.cs.lth.se/home/Tomas_Akenine_Moller/code/tribox3.txt">

@ -792,7 +792,35 @@ public class BoundingSphere extends BoundingVolume {
return 1;
}
}
private int collideWithRay(Ray ray) {
TempVars vars = TempVars.get();
Vector3f diff = vars.vect1.set(ray.getOrigin()).subtractLocal(
center);
float a = diff.dot(diff) - (getRadius() * getRadius());
float a1, discr;
if (a <= 0.0) {
// inside sphere
vars.release();
return 1;
}
a1 = ray.direction.dot(diff);
vars.release();
if (a1 >= 0.0) {
return 0;
}
discr = a1 * a1 - a;
if (discr < 0.0) {
return 0;
} else if (discr >= FastMath.ZERO_TOLERANCE) {
return 2;
}
return 1;
}
private int collideWithTri(Triangle tri, CollisionResults results) {
TempVars tvars = TempVars.get();
try {
@ -991,6 +1019,18 @@ public class BoundingSphere extends BoundingVolume {
}
}
@Override public int collideWith(Collidable other) {
if (other instanceof Ray) {
Ray ray = (Ray) other;
return collideWithRay(ray);
} else if (other instanceof Triangle){
return super.collideWith(other);
} else {
throw new UnsupportedCollisionException();
}
}
@Override
public boolean contains(Vector3f point) {
return center.distanceSquared(point) < (getRadius() * getRadius());

@ -32,10 +32,12 @@
package com.jme3.bounding;
import com.jme3.collision.Collidable;
import com.jme3.collision.CollisionResults;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.Savable;
import com.jme3.math.*;
import com.jme3.util.TempVars;
import java.io.IOException;
import java.nio.FloatBuffer;
@ -322,6 +324,15 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
public void read(JmeImporter e) throws IOException {
center = (Vector3f) e.getCapsule(this).readSavable("center", Vector3f.ZERO.clone());
}
public int collideWith(Collidable other) {
TempVars tempVars = TempVars.get();
CollisionResults tempResults = tempVars.collisionResults;
tempResults.clear();
int retval = collideWith(other, tempResults);
tempVars.release();
return retval;
}
}

@ -39,6 +39,7 @@ import com.jme3.export.JmeImporter;
import com.jme3.export.Savable;
import com.jme3.material.Material;
import com.jme3.util.SafeArrayList;
import com.jme3.util.TempVars;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@ -565,6 +566,18 @@ public class Node extends Spatial implements Savable {
public int collideWith(Collidable other, CollisionResults results){
int total = 0;
// optimization: try collideWith BoundingVolume to avoid possibly redundant tests on children
// number 4 in condition is somewhat arbitrary. When there is only one child, the boundingVolume test is redundant at all.
// The idea is when there are few children, it can be too expensive to test boundingVolume first.
if (children.size() > 4)
{
BoundingVolume bv = this.getWorldBound();
if (bv==null) return 0;
// collideWith without CollisionResults parameter used to avoid allocation when possible
if (bv.collideWith(other) == 0) return 0;
}
for (Spatial child : children.getArray()){
total += child.collideWith(other, results);
}

Loading…
Cancel
Save