use of com.jme3.scene.shape.Sphere in project jmonkeyengine by jMonkeyEngine.
the class BoundingSphere method collideWithRay.
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;
}
use of com.jme3.scene.shape.Sphere in project jmonkeyengine by jMonkeyEngine.
the class BoundingSphere method collideWithRay.
/*
* (non-Javadoc)
*
* @see com.jme.bounding.BoundingVolume#intersectsWhere(com.jme.math.Ray)
*/
private int collideWithRay(Ray ray, CollisionResults results) {
TempVars vars = TempVars.get();
Vector3f diff = vars.vect1.set(ray.getOrigin()).subtractLocal(center);
float a = diff.dot(diff) - (getRadius() * getRadius());
float a1, discr, root;
if (a <= 0.0) {
// inside sphere
a1 = ray.direction.dot(diff);
discr = (a1 * a1) - a;
root = FastMath.sqrt(discr);
float distance = root - a1;
Vector3f point = new Vector3f(ray.direction).multLocal(distance).addLocal(ray.origin);
CollisionResult result = new CollisionResult(point, distance);
results.addCollision(result);
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) {
root = FastMath.sqrt(discr);
float dist = -a1 - root;
Vector3f point = new Vector3f(ray.direction).multLocal(dist).addLocal(ray.origin);
results.addCollision(new CollisionResult(point, dist));
dist = -a1 + root;
point = new Vector3f(ray.direction).multLocal(dist).addLocal(ray.origin);
results.addCollision(new CollisionResult(point, dist));
return 2;
} else {
float dist = -a1;
Vector3f point = new Vector3f(ray.direction).multLocal(dist).addLocal(ray.origin);
results.addCollision(new CollisionResult(point, dist));
return 1;
}
}
use of com.jme3.scene.shape.Sphere in project jmonkeyengine by jMonkeyEngine.
the class BoundingSphere method collideWithTri.
private int collideWithTri(Triangle tri, CollisionResults results) {
TempVars tvars = TempVars.get();
try {
// Much of this is based on adaptation from this algorithm:
// http://realtimecollisiondetection.net/blog/?p=103
// ...mostly the stuff about eliminating sqrts wherever
// possible.
// Math is done in center-relative space.
Vector3f a = tri.get1().subtract(center, tvars.vect1);
Vector3f b = tri.get2().subtract(center, tvars.vect2);
Vector3f c = tri.get3().subtract(center, tvars.vect3);
Vector3f ab = b.subtract(a, tvars.vect4);
Vector3f ac = c.subtract(a, tvars.vect5);
// Check the plane... if it doesn't intersect the plane
// then it doesn't intersect the triangle.
Vector3f n = ab.cross(ac, tvars.vect6);
float d = a.dot(n);
float e = n.dot(n);
if (d * d > radius * radius * e) {
// Can't possibly intersect
return 0;
}
// We intersect the verts, or the edges, or the face...
// First check against the face since it's the most
// specific.
// Calculate the barycentric coordinates of the
// sphere center
Vector3f v0 = ac;
Vector3f v1 = ab;
// a was P relative, so p.subtract(a) is just -a
// instead of wasting a vector we'll just negate the
// dot products below... it's all v2 is used for.
Vector3f v2 = a;
float dot00 = v0.dot(v0);
float dot01 = v0.dot(v1);
float dot02 = -v0.dot(v2);
float dot11 = v1.dot(v1);
float dot12 = -v1.dot(v2);
float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
if (u >= 0 && v >= 0 && (u + v) <= 1) {
// We intersect... and we even know where
Vector3f part1 = ac;
Vector3f part2 = ab;
Vector3f p = center.add(a.add(part1.mult(u)).addLocal(part2.mult(v)));
CollisionResult r = new CollisionResult();
Vector3f normal = n.normalize();
// a is center relative, so -a points to center
float dist = -normal.dot(a);
dist = dist - radius;
r.setDistance(dist);
r.setContactNormal(normal);
r.setContactPoint(p);
results.addCollision(r);
return 1;
}
// Check the edges looking for the nearest point
// that is also less than the radius. We don't care
// about points that are farther away than that.
Vector3f nearestPt = null;
float nearestDist = radius * radius;
Vector3f base;
Vector3f edge;
float t;
// Edge AB
base = a;
edge = ab;
t = -edge.dot(base) / edge.dot(edge);
if (t >= 0 && t <= 1) {
Vector3f Q = base.add(edge.mult(t, tvars.vect7), tvars.vect8);
// distance squared to origin
float distSq = Q.dot(Q);
if (distSq < nearestDist) {
nearestPt = Q;
nearestDist = distSq;
}
}
// Edge AC
base = a;
edge = ac;
t = -edge.dot(base) / edge.dot(edge);
if (t >= 0 && t <= 1) {
Vector3f Q = base.add(edge.mult(t, tvars.vect7), tvars.vect9);
// distance squared to origin
float distSq = Q.dot(Q);
if (distSq < nearestDist) {
nearestPt = Q;
nearestDist = distSq;
}
}
// Edge BC
base = b;
Vector3f bc = c.subtract(b);
edge = bc;
t = -edge.dot(base) / edge.dot(edge);
if (t >= 0 && t <= 1) {
Vector3f Q = base.add(edge.mult(t, tvars.vect7), tvars.vect10);
// distance squared to origin
float distSq = Q.dot(Q);
if (distSq < nearestDist) {
nearestPt = Q;
nearestDist = distSq;
}
}
// done.
if (nearestPt != null) {
// We have a hit
float dist = FastMath.sqrt(nearestDist);
Vector3f cn = nearestPt.divide(-dist);
CollisionResult r = new CollisionResult();
r.setDistance(dist - radius);
r.setContactNormal(cn);
r.setContactPoint(nearestPt.add(center));
results.addCollision(r);
return 1;
}
// Finally check each of the triangle corners
// Vert A
base = a;
// distance squared to origin
t = base.dot(base);
if (t < nearestDist) {
nearestDist = t;
nearestPt = base;
}
// Vert B
base = b;
// distance squared to origin
t = base.dot(base);
if (t < nearestDist) {
nearestDist = t;
nearestPt = base;
}
// Vert C
base = c;
// distance squared to origin
t = base.dot(base);
if (t < nearestDist) {
nearestDist = t;
nearestPt = base;
}
if (nearestPt != null) {
// We have a hit
float dist = FastMath.sqrt(nearestDist);
Vector3f cn = nearestPt.divide(-dist);
CollisionResult r = new CollisionResult();
r.setDistance(dist - radius);
r.setContactNormal(cn);
r.setContactPoint(nearestPt.add(center));
results.addCollision(r);
return 1;
}
// Nothing hit... oh, well
return 0;
} finally {
tvars.release();
}
}
use of com.jme3.scene.shape.Sphere in project jmonkeyengine by jMonkeyEngine.
the class BoundingCollisionTest method testBoxSphereCollision.
@Test
public void testBoxSphereCollision() {
BoundingBox box1 = new BoundingBox(Vector3f.ZERO, 1, 1, 1);
BoundingSphere sphere2 = new BoundingSphere(1, Vector3f.ZERO);
checkCollision(box1, sphere2, 1);
// Put it at the very edge - for sphere vs. box, it will not intersect
sphere2.setCenter(new Vector3f(2f, 0f, 0f));
checkCollision(box1, sphere2, 0);
// Put it a wee bit closer - should intersect.
sphere2.setCenter(new Vector3f(2f - FastMath.ZERO_TOLERANCE, 0, 0));
checkCollision(box1, sphere2, 1);
// Test if the algorithm converts the sphere
// to a box before testing the collision (incorrect)
float sqrt3 = FastMath.sqrt(3);
sphere2.setCenter(Vector3f.UNIT_XYZ.mult(2));
sphere2.setRadius(sqrt3);
checkCollision(box1, sphere2, 0);
// Make it a wee bit larger.
sphere2.setRadius(sqrt3 + FastMath.ZERO_TOLERANCE);
checkCollision(box1, sphere2, 1);
}
use of com.jme3.scene.shape.Sphere in project jmonkeyengine by jMonkeyEngine.
the class LightFilterTest method testSpotFiltering.
@Test
public void testSpotFiltering() {
SpotLight sl = new SpotLight(Vector3f.ZERO, Vector3f.UNIT_Z);
sl.setSpotRange(0);
geom.addLight(sl);
// Infinite spot lights are only filtered
checkFilteredLights(1);
// if the geometry is outside the infinite cone.
TempVars vars = TempVars.get();
try {
// The spot is not touching the near plane of the camera yet,
// should still be culled.
sl.setSpotRange(1f - FastMath.ZERO_TOLERANCE);
assert !sl.intersectsFrustum(cam, vars);
// should be culled from the geometry's PoV
checkFilteredLights(0);
// Now it touches the near plane.
sl.setSpotRange(1f);
// still culled from the geometry's PoV
checkFilteredLights(0);
assert sl.intersectsFrustum(cam, vars);
} finally {
vars.release();
}
// make it barely reach the geometry
sl.setSpotRange(9f);
checkFilteredLights(0);
// make it reach the geometry (touching its bound)
sl.setSpotRange(9f + FastMath.ZERO_TOLERANCE);
checkFilteredLights(1);
// rotate the cone a bit so it no longer faces the geom
sl.setDirection(new Vector3f(0.316f, 0, 0.948f).normalizeLocal());
checkFilteredLights(0);
// extent the range much farther
sl.setSpotRange(20);
checkFilteredLights(0);
// Create box of size X=10 (double the extent)
// now, the spot will touch the box.
geom.setMesh(new Box(5, 1, 1));
checkFilteredLights(1);
// ==================================
// Tests for bounding sphere, with a radius of 1f (in the box geom)
sl.setPosition(Vector3f.ZERO);
sl.setDirection(Vector3f.UNIT_Z);
geom.setLocalTranslation(Vector3f.ZERO);
geom.setModelBound(new BoundingSphere(1f, Vector3f.ZERO));
// Infinit spot lights are only filtered
// if the geometry is outside the infinite cone.
sl.setSpotRange(0);
checkFilteredLights(1);
//the geommetry is outside the infinit cone (cone direction going away from the geom)
sl.setPosition(Vector3f.UNIT_Z.mult(1 + FastMath.ZERO_TOLERANCE));
checkFilteredLights(0);
//place the spote ligth in the corner of the box geom, (in order to test bounding sphere)
sl.setDirection(new Vector3f(1, 1, 0).normalizeLocal());
geom.setLocalTranslation(0, 0, 10);
sl.setPosition(sl.getDirection().mult(-2f).add(geom.getLocalTranslation()));
// make it barely reach the sphere, incorect with a box
sl.setSpotRange(1f - FastMath.ZERO_TOLERANCE);
checkFilteredLights(0);
// make it reach the sphere
sl.setSpotRange(1f + FastMath.ZERO_TOLERANCE);
checkFilteredLights(1);
// extent the range
sl.setPosition(Vector3f.ZERO);
sl.setDirection(Vector3f.UNIT_Z);
sl.setSpotRange(20);
checkFilteredLights(1);
// rotate the cone a bit so it no longer faces the geom
sl.setDirection(new Vector3f(0, 0.3f, 0.7f).normalizeLocal());
checkFilteredLights(0);
// Create sphere of size X=10 (double the radius)
// now, the spot will touch the sphere.
geom.setModelBound(new BoundingSphere(5f, Vector3f.ZERO));
checkFilteredLights(1);
}
Aggregations