package electrosphere.collision; import static org.ode4j.ode.OdeConstants.dContactBounce; import static org.ode4j.ode.OdeConstants.dContactSoftCFM; import static org.ode4j.ode.OdeConstants.dInfinity; import static org.ode4j.ode.OdeHelper.areConnectedExcluding; import java.util.List; import java.util.Map; import org.joml.Vector3d; import org.ode4j.ode.DBody; import org.ode4j.ode.DContact; import org.ode4j.ode.DContactBuffer; import org.ode4j.ode.DContactJoint; import org.ode4j.ode.DGeom; import org.ode4j.ode.DGeom.DNearCallback; import org.ode4j.ode.DRay; import org.ode4j.ode.OdeHelper; import electrosphere.collision.collidable.Collidable; import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.logger.LoggerInterface; public class RayCastCallback implements DNearCallback { /** * Maximum number of contacts allowed */ static final int MAX_CONTACTS = 5; /** * Really far away from the ray origin point */ static final double REALLY_LONG_DISTANCE = 1000000; /** * // Check ray collision against a space void RayCallback(void *Data, dGeomID Geometry1, dGeomID Geometry2) { dReal *HitPosition = (dReal *)Data; // Check collisions dContact Contacts[MAX_CONTACTS]; int Count = dCollide(Geometry1, Geometry2, MAX_CONTACTS, &Contacts[0].geom, sizeof(dContact)); for(int i = 0; i < Count; i++) { // Check depth against current closest hit if(Contacts[i].geom.depth < HitPosition[3]) { dCopyVector3(HitPosition, Contacts[i].geom.pos); HitPosition[3] = Contacts[i].geom.depth; } } } */ //For the current execution, this stores the shortest length that has currently been encountered. //This is used to keep track of the closest body so that there doesn't need to be contact join creation. //This should be reset every time a ray cast is called in collision engine by calling setLength in this object. double shortestLength = REALLY_LONG_DISTANCE; @Override public void call(Object data, DGeom o1, DGeom o2) { // if (o1->body && o2->body) return; RayCastCallbackData rayCastData = (RayCastCallbackData)data; //null out potentially previous results // rayCastData.collisionPosition = null; // rayCastData.collidedEntity = null; // exit without doing anything if the two bodies are connected by a joint DBody b1 = o1.getBody(); DBody b2 = o2.getBody(); if (b1!=null && b2!=null && areConnectedExcluding (b1,b2,DContactJoint.class)) return; //creates a buffer to store potential collisions DContactBuffer contacts = new DContactBuffer(MAX_CONTACTS); // up to MAX_CONTACTS contacts per box-box for (int i=0; i collidable Map bodyEntityMap; //The mask of collidable types to filter collisions by. Can be null. List collidableTypeMask; //The entity that the ray cast collided with. If null, no entity was collided with. Entity collidedEntity = null; //The position in world space that the collision happened Vector3d collisionPosition = null; /** * Constructor * @param bodyEntityMap The map of ode DBody -> collidable * @param collidableTypeMask The mask of collidable types to filter collisions by. Can be null. */ public RayCastCallbackData(Map bodyEntityMap,List collidableTypeMask){ this.bodyEntityMap = bodyEntityMap; this.collidableTypeMask = collidableTypeMask; } } }