use of com.jme3.collision.CollisionResult 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.collision.CollisionResult in project jmonkeyengine by jMonkeyEngine.
the class BIHNode method intersectWhere.
public final int intersectWhere(Ray r, Matrix4f worldMatrix, BIHTree tree, float sceneMin, float sceneMax, CollisionResults results) {
TempVars vars = TempVars.get();
ArrayList<BIHStackData> stack = vars.bihStack;
stack.clear();
// float tHit = Float.POSITIVE_INFINITY;
Vector3f o = vars.vect1.set(r.getOrigin());
Vector3f d = vars.vect2.set(r.getDirection());
Matrix4f inv = vars.tempMat4.set(worldMatrix).invertLocal();
inv.mult(r.getOrigin(), r.getOrigin());
// Fixes rotation collision bug
inv.multNormal(r.getDirection(), r.getDirection());
// inv.multNormalAcross(r.getDirection(), r.getDirection());
float[] origins = { r.getOrigin().x, r.getOrigin().y, r.getOrigin().z };
float[] invDirections = { 1f / r.getDirection().x, 1f / r.getDirection().y, 1f / r.getDirection().z };
r.getDirection().normalizeLocal();
Vector3f v1 = vars.vect3, v2 = vars.vect4, v3 = vars.vect5;
int cols = 0;
stack.add(new BIHStackData(this, sceneMin, sceneMax));
stackloop: while (stack.size() > 0) {
BIHStackData data = stack.remove(stack.size() - 1);
BIHNode node = data.node;
float tMin = data.min, tMax = data.max;
if (tMax < tMin) {
continue;
}
leafloop: while (node.axis != 3) {
// while node is not a leaf
int a = node.axis;
// find the origin and direction value for the given axis
float origin = origins[a];
float invDirection = invDirections[a];
float tNearSplit, tFarSplit;
BIHNode nearNode, farNode;
tNearSplit = (node.leftPlane - origin) * invDirection;
tFarSplit = (node.rightPlane - origin) * invDirection;
nearNode = node.left;
farNode = node.right;
if (invDirection < 0) {
float tmpSplit = tNearSplit;
tNearSplit = tFarSplit;
tFarSplit = tmpSplit;
BIHNode tmpNode = nearNode;
nearNode = farNode;
farNode = tmpNode;
}
if (tMin > tNearSplit && tMax < tFarSplit) {
continue stackloop;
}
if (tMin > tNearSplit) {
tMin = max(tMin, tFarSplit);
node = farNode;
} else if (tMax < tFarSplit) {
tMax = min(tMax, tNearSplit);
node = nearNode;
} else {
stack.add(new BIHStackData(farNode, max(tMin, tFarSplit), tMax));
tMax = min(tMax, tNearSplit);
node = nearNode;
}
}
// a leaf
for (int i = node.leftIndex; i <= node.rightIndex; i++) {
tree.getTriangle(i, v1, v2, v3);
float t = r.intersects(v1, v2, v3);
if (!Float.isInfinite(t)) {
if (worldMatrix != null) {
worldMatrix.mult(v1, v1);
worldMatrix.mult(v2, v2);
worldMatrix.mult(v3, v3);
float t_world = new Ray(o, d).intersects(v1, v2, v3);
t = t_world;
}
Vector3f contactNormal = Triangle.computeTriangleNormal(v1, v2, v3, null);
Vector3f contactPoint = new Vector3f(d).multLocal(t).addLocal(o);
float worldSpaceDist = o.distance(contactPoint);
CollisionResult cr = new CollisionResult(contactPoint, worldSpaceDist);
cr.setContactNormal(contactNormal);
cr.setTriangleIndex(tree.getTriangleIndex(i));
results.addCollision(cr);
cols++;
}
}
}
vars.release();
r.setOrigin(o);
r.setDirection(d);
return cols;
}
use of com.jme3.collision.CollisionResult in project jmonkeyengine by jMonkeyEngine.
the class BIHNode method intersectBrute.
public final int intersectBrute(Ray r, Matrix4f worldMatrix, BIHTree tree, float sceneMin, float sceneMax, CollisionResults results) {
float tHit = Float.POSITIVE_INFINITY;
TempVars vars = TempVars.get();
Vector3f v1 = vars.vect1, v2 = vars.vect2, v3 = vars.vect3;
int cols = 0;
ArrayList<BIHStackData> stack = vars.bihStack;
stack.clear();
stack.add(new BIHStackData(this, 0, 0));
stackloop: while (stack.size() > 0) {
BIHStackData data = stack.remove(stack.size() - 1);
BIHNode node = data.node;
leafloop: while (node.axis != 3) {
// while node is not a leaf
BIHNode nearNode, farNode;
nearNode = node.left;
farNode = node.right;
stack.add(new BIHStackData(farNode, 0, 0));
node = nearNode;
}
// a leaf
for (int i = node.leftIndex; i <= node.rightIndex; i++) {
tree.getTriangle(i, v1, v2, v3);
if (worldMatrix != null) {
worldMatrix.mult(v1, v1);
worldMatrix.mult(v2, v2);
worldMatrix.mult(v3, v3);
}
float t = r.intersects(v1, v2, v3);
if (t < tHit) {
tHit = t;
Vector3f contactPoint = new Vector3f(r.direction).multLocal(tHit).addLocal(r.origin);
CollisionResult cr = new CollisionResult(contactPoint, tHit);
cr.setTriangleIndex(tree.getTriangleIndex(i));
results.addCollision(cr);
cols++;
}
}
}
vars.release();
return cols;
}
use of com.jme3.collision.CollisionResult in project jmonkeyengine by jMonkeyEngine.
the class BoundingBox method collideWith.
@Override
public int collideWith(Collidable other, CollisionResults results) {
if (other instanceof Ray) {
Ray ray = (Ray) other;
return collideWithRay(ray, results);
} else if (other instanceof Triangle) {
Triangle t = (Triangle) other;
if (intersects(t.get1(), t.get2(), t.get3())) {
CollisionResult r = new CollisionResult();
results.addCollision(r);
return 1;
}
return 0;
} else if (other instanceof BoundingVolume) {
if (intersects((BoundingVolume) other)) {
CollisionResult r = new CollisionResult();
results.addCollision(r);
return 1;
}
return 0;
} else if (other instanceof Spatial) {
return ((Spatial) other).collideWith(this, results);
} else {
throw new UnsupportedCollisionException("With: " + other.getClass().getSimpleName());
}
}
use of com.jme3.collision.CollisionResult in project jmonkeyengine by jMonkeyEngine.
the class TestJoystick method pickGamePad.
private void pickGamePad(Vector2f mouseLoc) {
if (lastButton != null) {
CollisionResults cresults = pick(cam, mouseLoc, gamepad);
for (CollisionResult cr : cresults) {
Node n = cr.getGeometry().getParent();
if (n != null && (n instanceof ButtonView)) {
String b = ((ButtonView) n).getName().substring("Button:".length());
String name = lastButton.getJoystick().getName().replaceAll(" ", "\\\\ ");
String id = lastButton.getLogicalId().replaceAll(" ", "\\\\ ");
System.out.println(name + "." + id + "=" + b);
return;
}
}
}
}
Aggregations