Merge pull request #196 from Bebul/collideWithOptimization
Collide with optimization
This commit is contained in:
commit
5508dc05f5
@ -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…
x
Reference in New Issue
Block a user