ClementRomac's picture
ClementRomac HF staff
Added interactive demo with some policies
09a6f7f
/**
* @classdesc Class that derives from b2.ContactListener and that handles both water and climbing collisions.
* @param env {Object}
* @constructor
*/
function ContactDetector (env){
b2.ContactListener.call(this);
this.water_contact_detector = new WaterContactDetector();
this.climbing_contact_detector = new ClimbingContactDetector();
this.env = env;
}
ContactDetector.prototype = Object.create(b2.ContactListener.prototype);
ContactDetector.prototype.constructor = ContactDetector;
ContactDetector.prototype.BeginContact = function (contact){
let bodies = [contact.GetFixtureA().GetBody(), contact.GetFixtureB().GetBody()];
const anyWater = (body) => body.GetUserData().object_type == CustomUserDataObjectTypes.WATER;
const anySensor = (body) => body.GetUserData().object_type == CustomUserDataObjectTypes.BODY_SENSOR;
if(bodies.some(anyWater)){
this.water_contact_detector.BeginContact(contact);
}
else if(bodies.some(anySensor)){
this.climbing_contact_detector.BeginContact(contact);
}
else{
if(contact.GetFixtureA().IsSensor() || contact.GetFixtureB().IsSensor()){
return;
}
for(let i = 0; i < bodies.length; i++){
let body = bodies[i];
if(body.GetUserData().object_type == CustomUserDataObjectTypes.BODY_OBJECT && body.GetUserData().check_contact){
body.GetUserData().has_contact = true;
}
}
}
};
ContactDetector.prototype.EndContact = function (contact){
let bodies = [contact.GetFixtureA().GetBody(), contact.GetFixtureB().GetBody()];
const anyWater = (body) => body.GetUserData().object_type == CustomUserDataObjectTypes.WATER;
const anySensor = (body) => body.GetUserData().object_type == CustomUserDataObjectTypes.BODY_SENSOR;
if(bodies.some(anyWater)){
this.water_contact_detector.EndContact(contact);
}
else if(bodies.some(anySensor)){
this.climbing_contact_detector.EndContact(contact);
}
else {
for(let body of bodies){
if(body.GetUserData().object_type == CustomUserDataObjectTypes.BODY_OBJECT && body.GetUserData().check_contact){
body.GetUserData().has_contact = false;
}
}
}
};
ContactDetector.prototype.Reset = function (){
this.water_contact_detector.Reset();
this.climbing_contact_detector.Reset();
}
/**
* @classdesc Class that derives from b2.RayCastCallback and that handles lidars raycasts.
* @param agent_mask_filter
* @constructor
*/
function LidarCallback(agent_mask_filter){
b2.RayCastCallback.call(this);
this.agent_mask_filter = agent_mask_filter;
this.fixture = null;
this.is_water_detected = false;
this.is_creeper_detected = false;
};
LidarCallback.prototype = Object.create(b2.RayCastCallback.prototype);
LidarCallback.prototype.constructor = LidarCallback;
LidarCallback.prototype.ReportFixture = function (fixture, point, normal, fraction){
if((fixture.GetFilterData().categoryBits & this.agent_mask_filter) == 0){
return -1;
}
this.p2 = point;
this.fraction = fraction;
this.is_water_detected = fixture.GetBody().GetUserData().object_type == CustomUserDataObjectTypes.WATER;
this.is_creeper_detected = fixture.GetBody().GetUserData().object_type == CustomUserDataObjectTypes.SENSOR_GRIP_TERRAIN;
return fraction;
}