use of com.bulletphysics.util.Stack in project bdx by GoranM.
the class CollisionWorld method convexSweepTest.
/**
* convexTest performs a swept convex cast on all objects in the {@link CollisionWorld}, and calls the resultCallback
* This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback.
*/
public void convexSweepTest(ConvexShape castShape, Transform convexFromWorld, Transform convexToWorld, ConvexResultCallback resultCallback) {
Stack stack = Stack.enter();
Transform convexFromTrans = stack.allocTransform();
Transform convexToTrans = stack.allocTransform();
convexFromTrans.set(convexFromWorld);
convexToTrans.set(convexToWorld);
Vector3f castShapeAabbMin = stack.allocVector3f();
Vector3f castShapeAabbMax = stack.allocVector3f();
// Compute AABB that encompasses angular movement
{
Vector3f linVel = stack.allocVector3f();
Vector3f angVel = stack.allocVector3f();
TransformUtil.calculateVelocity(convexFromTrans, convexToTrans, 1f, linVel, angVel);
Transform R = stack.allocTransform();
R.setIdentity();
R.setRotation(convexFromTrans.getRotation(stack.allocQuat4f()));
castShape.calculateTemporalAabb(R, linVel, angVel, 1f, castShapeAabbMin, castShapeAabbMax);
}
Transform tmpTrans = stack.allocTransform();
Vector3f collisionObjectAabbMin = stack.allocVector3f();
Vector3f collisionObjectAabbMax = stack.allocVector3f();
float[] hitLambda = new float[1];
// do a ray-shape query using convexCaster (CCD)
for (int i = 0; i < collisionObjects.size(); i++) {
CollisionObject collisionObject = collisionObjects.getQuick(i);
// only perform raycast if filterMask matches
if (resultCallback.needsCollision(collisionObject.getBroadphaseHandle())) {
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
collisionObject.getWorldTransform(tmpTrans);
collisionObject.getCollisionShape().getAabb(tmpTrans, collisionObjectAabbMin, collisionObjectAabbMax);
AabbUtil2.aabbExpand(collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
// could use resultCallback.closestHitFraction, but needs testing
hitLambda[0] = 1f;
Vector3f hitNormal = stack.allocVector3f();
if (AabbUtil2.rayAabb(convexFromWorld.origin, convexToWorld.origin, collisionObjectAabbMin, collisionObjectAabbMax, hitLambda, hitNormal)) {
objectQuerySingle(castShape, convexFromTrans, convexToTrans, collisionObject, collisionObject.getCollisionShape(), tmpTrans, resultCallback, getDispatchInfo().allowedCcdPenetration);
}
}
}
stack.leave();
}
use of com.bulletphysics.util.Stack in project bdx by GoranM.
the class CollisionWorld method rayTest.
/**
* rayTest performs a raycast on all objects in the CollisionWorld, and calls the resultCallback.
* This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
*/
public void rayTest(Vector3f rayFromWorld, Vector3f rayToWorld, RayResultCallback resultCallback) {
Stack stack = Stack.enter();
Transform rayFromTrans = stack.allocTransform(), rayToTrans = stack.allocTransform();
rayFromTrans.setIdentity();
rayFromTrans.origin.set(rayFromWorld);
rayToTrans.setIdentity();
rayToTrans.origin.set(rayToWorld);
// go over all objects, and if the ray intersects their aabb, do a ray-shape query using convexCaster (CCD)
Vector3f collisionObjectAabbMin = stack.allocVector3f(), collisionObjectAabbMax = stack.allocVector3f();
float[] hitLambda = new float[1];
Transform tmpTrans = stack.allocTransform();
for (int i = 0; i < collisionObjects.size(); i++) {
// terminate further ray tests, once the closestHitFraction reached zero
if (resultCallback.closestHitFraction == 0f) {
break;
}
CollisionObject collisionObject = collisionObjects.getQuick(i);
// only perform raycast if filterMask matches
if (resultCallback.needsCollision(collisionObject.getBroadphaseHandle())) {
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
collisionObject.getCollisionShape().getAabb(collisionObject.getWorldTransform(tmpTrans), collisionObjectAabbMin, collisionObjectAabbMax);
hitLambda[0] = resultCallback.closestHitFraction;
Vector3f hitNormal = stack.allocVector3f();
if (AabbUtil2.rayAabb(rayFromWorld, rayToWorld, collisionObjectAabbMin, collisionObjectAabbMax, hitLambda, hitNormal)) {
rayTestSingle(rayFromTrans, rayToTrans, collisionObject, collisionObject.getCollisionShape(), collisionObject.getWorldTransform(tmpTrans), resultCallback);
}
}
}
stack.leave();
}
use of com.bulletphysics.util.Stack in project bdx by GoranM.
the class CollisionWorld method objectQuerySingle.
/**
* objectQuerySingle performs a collision detection query and calls the resultCallback. It is used internally by rayTest.
*/
public static void objectQuerySingle(ConvexShape castShape, Transform convexFromTrans, Transform convexToTrans, CollisionObject collisionObject, CollisionShape collisionShape, Transform colObjWorldTransform, ConvexResultCallback resultCallback, float allowedPenetration) {
Stack stack = Stack.enter();
if (collisionShape.isConvex()) {
CastResult castResult = new CastResult();
castResult.allowedPenetration = allowedPenetration;
// ??
castResult.fraction = 1f;
ConvexShape convexShape = (ConvexShape) collisionShape;
VoronoiSimplexSolver simplexSolver = new VoronoiSimplexSolver();
GjkEpaPenetrationDepthSolver gjkEpaPenetrationSolver = new GjkEpaPenetrationDepthSolver();
// JAVA TODO: should be convexCaster1
//ContinuousConvexCollision convexCaster1(castShape,convexShape,&simplexSolver,&gjkEpaPenetrationSolver);
GjkConvexCast convexCaster2 = new GjkConvexCast(castShape, convexShape, simplexSolver);
//btSubsimplexConvexCast convexCaster3(castShape,convexShape,&simplexSolver);
ConvexCast castPtr = convexCaster2;
if (castPtr.calcTimeOfImpact(convexFromTrans, convexToTrans, colObjWorldTransform, colObjWorldTransform, castResult)) {
// add hit
if (castResult.normal.lengthSquared() > 0.0001f) {
if (castResult.fraction < resultCallback.closestHitFraction) {
castResult.normal.normalize();
LocalConvexResult localConvexResult = new LocalConvexResult(collisionObject, null, castResult.normal, castResult.hitPoint, castResult.fraction);
boolean normalInWorldSpace = true;
resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
}
}
}
} else {
if (collisionShape.isConcave()) {
if (collisionShape.getShapeType() == BroadphaseNativeType.TRIANGLE_MESH_SHAPE_PROXYTYPE) {
BvhTriangleMeshShape triangleMesh = (BvhTriangleMeshShape) collisionShape;
Transform worldTocollisionObject = stack.allocTransform();
worldTocollisionObject.inverse(colObjWorldTransform);
Vector3f convexFromLocal = stack.allocVector3f();
convexFromLocal.set(convexFromTrans.origin);
worldTocollisionObject.transform(convexFromLocal);
Vector3f convexToLocal = stack.allocVector3f();
convexToLocal.set(convexToTrans.origin);
worldTocollisionObject.transform(convexToLocal);
// rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
Transform rotationXform = stack.allocTransform();
Matrix3f tmpMat = stack.allocMatrix3f();
tmpMat.mul(worldTocollisionObject.basis, convexToTrans.basis);
rotationXform.set(tmpMat);
BridgeTriangleConvexcastCallback tccb = new BridgeTriangleConvexcastCallback(castShape, convexFromTrans, convexToTrans, resultCallback, collisionObject, triangleMesh, colObjWorldTransform);
tccb.hitFraction = resultCallback.closestHitFraction;
tccb.normalInWorldSpace = true;
Vector3f boxMinLocal = stack.allocVector3f();
Vector3f boxMaxLocal = stack.allocVector3f();
castShape.getAabb(rotationXform, boxMinLocal, boxMaxLocal);
triangleMesh.performConvexcast(tccb, convexFromLocal, convexToLocal, boxMinLocal, boxMaxLocal);
} else {
BvhTriangleMeshShape triangleMesh = (BvhTriangleMeshShape) collisionShape;
Transform worldTocollisionObject = stack.allocTransform();
worldTocollisionObject.inverse(colObjWorldTransform);
Vector3f convexFromLocal = stack.allocVector3f();
convexFromLocal.set(convexFromTrans.origin);
worldTocollisionObject.transform(convexFromLocal);
Vector3f convexToLocal = stack.allocVector3f();
convexToLocal.set(convexToTrans.origin);
worldTocollisionObject.transform(convexToLocal);
// rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
Transform rotationXform = stack.allocTransform();
Matrix3f tmpMat = stack.allocMatrix3f();
tmpMat.mul(worldTocollisionObject.basis, convexToTrans.basis);
rotationXform.set(tmpMat);
BridgeTriangleConvexcastCallback tccb = new BridgeTriangleConvexcastCallback(castShape, convexFromTrans, convexToTrans, resultCallback, collisionObject, triangleMesh, colObjWorldTransform);
tccb.hitFraction = resultCallback.closestHitFraction;
tccb.normalInWorldSpace = false;
Vector3f boxMinLocal = stack.allocVector3f();
Vector3f boxMaxLocal = stack.allocVector3f();
castShape.getAabb(rotationXform, boxMinLocal, boxMaxLocal);
Vector3f rayAabbMinLocal = stack.alloc(convexFromLocal);
VectorUtil.setMin(rayAabbMinLocal, convexToLocal);
Vector3f rayAabbMaxLocal = stack.alloc(convexFromLocal);
VectorUtil.setMax(rayAabbMaxLocal, convexToLocal);
rayAabbMinLocal.add(boxMinLocal);
rayAabbMaxLocal.add(boxMaxLocal);
triangleMesh.processAllTriangles(tccb, rayAabbMinLocal, rayAabbMaxLocal);
}
} else {
// todo: use AABB tree or other BVH acceleration structure!
if (collisionShape.isCompound()) {
CompoundShape compoundShape = (CompoundShape) collisionShape;
for (int i = 0; i < compoundShape.getNumChildShapes(); i++) {
Transform childTrans = compoundShape.getChildTransform(i, stack.allocTransform());
CollisionShape childCollisionShape = compoundShape.getChildShape(i);
Transform childWorldTrans = stack.allocTransform();
childWorldTrans.mul(colObjWorldTransform, childTrans);
// replace collision shape so that callback can determine the triangle
CollisionShape saveCollisionShape = collisionObject.getCollisionShape();
collisionObject.internalSetTemporaryCollisionShape(childCollisionShape);
objectQuerySingle(castShape, convexFromTrans, convexToTrans, collisionObject, childCollisionShape, childWorldTrans, resultCallback, allowedPenetration);
// restore
collisionObject.internalSetTemporaryCollisionShape(saveCollisionShape);
}
}
}
}
stack.leave();
}
use of com.bulletphysics.util.Stack in project bdx by GoranM.
the class CollisionWorld method addCollisionObject.
public void addCollisionObject(CollisionObject collisionObject, short collisionFilterGroup, short collisionFilterMask) {
// check that the object isn't already added
assert (!collisionObjects.contains(collisionObject));
Stack stack = Stack.enter();
collisionObjects.add(collisionObject);
// calculate new AABB
// TODO: check if it's overwritten or not
Transform trans = collisionObject.getWorldTransform(stack.allocTransform());
Vector3f minAabb = stack.allocVector3f();
Vector3f maxAabb = stack.allocVector3f();
collisionObject.getCollisionShape().getAabb(trans, minAabb, maxAabb);
BroadphaseNativeType type = collisionObject.getCollisionShape().getShapeType();
collisionObject.setBroadphaseHandle(getBroadphase().createProxy(minAabb, maxAabb, type, collisionObject, collisionFilterGroup, collisionFilterMask, dispatcher1, null));
stack.leave();
}
use of com.bulletphysics.util.Stack in project bdx by GoranM.
the class CompoundCollisionAlgorithm method processCollision.
@Override
public void processCollision(CollisionObject body0, CollisionObject body1, DispatcherInfo dispatchInfo, ManifoldResult resultOut) {
Stack stack = Stack.enter();
CollisionObject colObj = isSwapped ? body1 : body0;
CollisionObject otherObj = isSwapped ? body0 : body1;
assert (colObj.getCollisionShape().isCompound());
CompoundShape compoundShape = (CompoundShape) colObj.getCollisionShape();
// We will use the OptimizedBVH, AABB tree to cull potential child-overlaps
// If both proxies are Compound, we will deal with that directly, by performing sequential/parallel tree traversals
// given Proxy0 and Proxy1, if both have a tree, Tree0 and Tree1, this means:
// determine overlapping nodes of Proxy1 using Proxy0 AABB against Tree1
// then use each overlapping node AABB against Tree0
// and vise versa.
Transform tmpTrans = stack.allocTransform();
Transform orgTrans = stack.allocTransform();
Transform childTrans = stack.allocTransform();
Transform orgInterpolationTrans = stack.allocTransform();
Transform newChildWorldTrans = stack.allocTransform();
int numChildren = childCollisionAlgorithms.size();
int i;
for (i = 0; i < numChildren; i++) {
// temporarily exchange parent btCollisionShape with childShape, and recurse
CollisionShape childShape = compoundShape.getChildShape(i);
// backup
colObj.getWorldTransform(orgTrans);
colObj.getInterpolationWorldTransform(orgInterpolationTrans);
compoundShape.getChildTransform(i, childTrans);
newChildWorldTrans.mul(orgTrans, childTrans);
colObj.setWorldTransform(newChildWorldTrans);
colObj.setInterpolationWorldTransform(newChildWorldTrans);
// the contactpoint is still projected back using the original inverted worldtrans
CollisionShape tmpShape = colObj.getCollisionShape();
colObj.internalSetTemporaryCollisionShape(childShape);
childCollisionAlgorithms.getQuick(i).processCollision(colObj, otherObj, dispatchInfo, resultOut);
// revert back
colObj.internalSetTemporaryCollisionShape(tmpShape);
colObj.setWorldTransform(orgTrans);
colObj.setInterpolationWorldTransform(orgInterpolationTrans);
}
stack.leave();
}
Aggregations