CollideWith optimization with CollisionResult allocation avoided
This commit is contained in:
parent
b46973f33f
commit
75a801f0f7
jme3-core/src/main/java/com/jme3
@ -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;
|
||||
@ -778,6 +807,22 @@ public class BoundingBox extends BoundingVolume {
|
||||
}
|
||||
}
|
||||
|
||||
@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">
|
||||
* http://www.cs.lth.se/home/Tomas_Akenine_Moller/code/tribox3.txt</a>
|
||||
|
@ -793,6 +793,34 @@ public class BoundingSphere extends BoundingVolume {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -323,5 +325,14 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2014 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package com.jme3.collision;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <code>DummyCollisionResults</code> is an empty "dummy" collection returned as a result of a
|
||||
* collision detection operation done by {@link Collidable}.
|
||||
* Its purpose is to avoid allocation of CollisionResults and its content,
|
||||
* when collisionResults are out of our interest.
|
||||
* Using the same API Collidable.collideWith() instead of possibly some new countCollideWith() implementation
|
||||
* is chosen to keep the collision detection code "DRY", @see <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">Don't repeat yourself</a>
|
||||
*
|
||||
* @author Bebul
|
||||
*/
|
||||
public class DummyCollisionResults extends CollisionResults {
|
||||
// the singleton for DummyCollisionResults is sufficient
|
||||
private static DummyCollisionResults instance = null;
|
||||
|
||||
// exists only to defeat instantiation
|
||||
protected DummyCollisionResults() {}
|
||||
|
||||
// classic singleton instance
|
||||
public static DummyCollisionResults getInstance() {
|
||||
if ( instance == null ) {
|
||||
instance = new DummyCollisionResults();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
// Dummy implementation of CollisionResults
|
||||
// All methods can be dummy except for iterator
|
||||
@Override public void clear(){}
|
||||
// even dummy iterator should return valid iterator
|
||||
@Override public Iterator<CollisionResult> iterator() {
|
||||
List<CollisionResult> dumbCompiler = Collections.emptyList();
|
||||
return dumbCompiler.iterator();
|
||||
}
|
||||
@Override public void addCollision(CollisionResult result){}
|
||||
@Override public int size(){ return 0; }
|
||||
@Override public CollisionResult getClosestCollision(){ return null; }
|
||||
@Override public CollisionResult getFarthestCollision(){ return null; }
|
||||
@Override public CollisionResult getCollision(int index){ return null; }
|
||||
@Override public CollisionResult getCollisionDirect(int index){ return null; }
|
||||
}
|
@ -34,12 +34,12 @@ package com.jme3.scene;
|
||||
import com.jme3.bounding.BoundingVolume;
|
||||
import com.jme3.collision.Collidable;
|
||||
import com.jme3.collision.CollisionResults;
|
||||
import com.jme3.collision.DummyCollisionResults;
|
||||
import com.jme3.export.JmeExporter;
|
||||
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;
|
||||
@ -499,10 +499,8 @@ public class Node extends Spatial implements Savable {
|
||||
BoundingVolume bv = this.getWorldBound();
|
||||
if (bv==null) return 0;
|
||||
|
||||
// use DummyCollisionResults to avoid allocation while making the call to any BoundingVolume.collideWith possible
|
||||
// moreover, the DummyCollisionResults operations are empty, so faster
|
||||
DummyCollisionResults dummyColRes = DummyCollisionResults.getInstance();
|
||||
if (bv.collideWith(other, dummyColRes) == 0) 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