This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

I created a plugin for getting Box2D collision data into Impact (Note: This is for Box2d v2.0.2). It's a work in progress. Github link is here.

* Update *

Version 2.1 released! Big thanks to Joncom, Xatruch and pixelpusher, as I incorporated their code and formulated the version! This plugin is now as much theirs as it is mine. You can find both the new version and the previous version on my Github.
To use the plugin, override collideEntity() within your Box2DEntity to grab info about the colliding Entity - this is comparable to Impact's collideWith(). To grab tile info, override collideTile() - this is comparable to handleMovementTrace().
Since Box2D/Impact info is so scant, let me share with you some of my research and breakdown my collision plugin.

First, all Box2D collision per frame are broken down in an array of ContactEdges. This is what the for loops is cycling through:

```for (var edge = this.body.m_contactList; edge; edge = edge.next)
```

For every edge of contact, Box2D creates a normal force vector, which is a perpendicular unit vector pointing away from the surface of contact. The plugin grabs the normal and uses this to calculate the point of contact & to determine if the Entity is standing. You can break the normal force down on both axes like so:

```if( normal.x > 0 ){
//vector points right
}
else if( normal.x < 0 ){
//vector points left
}
else{
//point.x = 0 and thus, no horizontal collision
}

if( normal.y > 0 ){
//vector points down
}
else if( normal.y < 0 ){
//vector points up
}
else{
//point.y = 0 and thus, no vertical collision
}
```

The final tricky bit is this:

```var f1 = this.shape.m_filter, f2 = ent.shape.m_filter;
if (f1.groupIndex != f2.groupIndex || f1.groupIndex > 0 || f1.categoryBits == f2.maskBits) {
this.collideEntity(ent, point, normal);
}
```

Each Shape has a filter that it uses to filter out collisions with other Shapes. It does this in two ways: groupIndices & mask bits.

Filtering the groupIndex is a two-step process: first it checks to see if each Shape's groupIndex is equal, if so it then tests to see if it's positive or negative. If it's positive, those two Shapes will always collide; if it's negative, those two Shapes will never collide. Thus, if you have a bicycle with an Entity for each part (wheels, pedals, frame, etc.), you'll want to set the groupIndex for each to something like -8 so that the bicycle never collides with itself.

Filtering by mask bits is done by setting the categoryBits of the first Shape equal to the mask bits of the second. If those two match, the Shapes will collide. Box2D allows for 16 different categories for this type of filtering. You can read more here.

groupIndex testing gets precedence over mask bits. Thus, if a groupIndex is defined, Box2D will use it over the mask bits.
i was playing around with the plugin, but couldn't get it to work

i'm applying it to dominic's jetpack physics example (with Impact 1.18a)

```

// step 2: this goes into EntityCrate

collideEntity:function(other,point,normal){
this.parent();

if( normal.x > 0 ){
console.log("vector points right");
}
else if( normal.x < 0 ){
console.log("vector points left");
}
else{
console.log("point.x = 0 and thus, no horizontal collision");
}

if( normal.y > 0 ){
console.log("vector points down");
}
else if( normal.y < 0 ){
console.log("vector points up");
}
else{
console.log("point.y = 0 and thus, no vertical collision");
}
}

```

anything i'm missing? Probably bcos it's 3 am now , lol
seems like collideTile works, but collideEntity doesn't

```
EntityCrate = ig.Box2DEntity.extend({
size: {x: 8, y: 8},

type: ig.Entity.TYPE.B,
checkAgainst: ig.Entity.TYPE.NONE,
collides: ig.Entity.COLLIDES.NEVER,

animSheet: new ig.AnimationSheet( 'media/crate.png', 8, 8 ),

init: function( x, y, settings ) {
this.parent( x, y, settings );
},

// doesn't work
collideEntity:function(other,point,normal){
this.parent();
console.log(other,point,normal);
},

// works, because the crates touch the tiles
collideTile:function(tile,point,normal){
this.parent();
console.log(tile,point,normal);
}

});

```
Did you include the plugin in main.js? Are you getting some sort of error?

Make sure crate is calling its parent update(). You don't need to call this.parent() in collideEntity().

I take it you're testing the collision between the projectile & crate?

Hmm...also, do a console.log on the crate.init(). See what the default groupIndex is.
Change line 45 of plugin to this:

```if (!f1.groupIndex || f1.groupIndex != f2.groupIndex || f1.groupIndex > 0 || f1.categoryBits == f2.maskBits) {
this.collideEntity(ent, point, normal);
}
```

Need to test for groupIndex being undefined.
ok got it,

i needed to set the groupIndex for each entity type differently.

```        // for each entity type : Eg: player get's groupIndex of 1, crate gets 2, bullet gets 3
createBody: function() {
var bodyDef = new b2.BodyDef();
bodyDef.position.Set(
(this.pos.x + this.size.x / 2) * b2.SCALE,
(this.pos.y + this.size.y / 2) * b2.SCALE
);

this.body = ig.world.CreateBody(bodyDef);

var shapeDef = new b2.PolygonDef();
shapeDef.SetAsBox(
this.size.x / 2 * b2.SCALE,
this.size.y / 2 * b2.SCALE
);

shapeDef.density = 1;
shapeDef.restitution = 0;
shapeDef.friction = 1;

// collision detection setup
shapeDef.filter.groupIndex = 1;

this.body.CreateShape(shapeDef);
this.body.SetMassFromShapes();
},

```
That'll work, though you'll run into issues later with everything having the same groupIndex. I'd advise adding the additional undefined test to line 45 of the plugin. I updated both the OP and Github. Enjoy!
small fix line 43 :

```  // double dots after 'this'
var f1 = this..shape.m_filter,

```
Fixed. Thx.
Thanks so much quidmonkey for this plugin ^^
Hi, I started using the ImpactJS framework with Box2d Plugin and Collision plugin, everything works perfects thanks. But I run into an issue, when I have a rotated entity the collideTile method fails,it's detecting the collision before the actual object touch a tile. I already use the box2d debug draw to see if the body object was wrong, but no, Box2d is handling correctly the collision, but the collision plugin is calling the collideTile method before the collision. The problem only happens when I rotate the player Body.
Any advice would be really appreciated. Thanks so much for your time.
Paul, could you post your code where this is happening?
Hi thanks for the answer. The code is based on the ImpactJS Box2D demo. I have a simple player that can go up like the jetpack example with a force applied. The player also can rotate left or right, but when he rotate the collision plugin tells a collisionTile when the player is close to a tile, but without touching it

Without rotation, everything works perfect.

Here is part of my entity class, the rest is almost the same that the examples.

```currentAngle: 0,

collideTile:function(tile,point,normal){
console.log(tile,point,normal);
},
update: function(){
// space key pressed
if( ig.input.state('space_pressed) ) {
// Apply a force in the direction of the player's head
// 1.578 =  PI/2
this.body.ApplyForce(
new b2.Vec2(-100*Math.cos(this.currentAngle+1.5708)
,100*Math.sin(this.currentAngle-1.5708)),
this.body.GetPosition() );
}

// right arrow key pressed, rotate the player clockwise.
if(ig.input.state('right')){
if(this.currentAngle > 6.2832){
this.currentAngle = 0;
}
this.currentAngle+=0.1;
}

//left arrow key pressed, rotate the player counter clockwise
if(ig.input.state('left')){
if(this.currentAngle < -6.2832){
this.currentAngle = 0;
}
this.currentAngle-=0.1;
}

// Apply the rotation to the entity body
this.body.SetXForm(this.body.GetPosition(), this.currentAngle);
this.parent();
}

```

Thanks.
Paul-

I believe it's a question of timing. Here's the Entity update loop from my code:
```update: function () {
this.parent();
this.collision();
}
```

Notice that collision detection happens after the `.update()` loop. Try exchanging the method calls so that collision detection happens before the `.update()` loop:
```update: function () {
this.collision();
this.parent();
}
```
And try placing the call to `this.parent()` at the top of your Entity&`039;s #.update()`:
```update: function(){
this.parent();

//change angle code

// Apply the rotation to the entity body
this.body.SetXForm( this.body.GetPosition(), this.currentAngle );
}
```
Hi thanks for your answer, I just tried that code but no luck, the problem is still the same.
Don't know if anyone had this problem ever :S.
Unfortunately, I no longer have an active build to test this with, but try replacing:
```//calculate point of contact
var x = this.pos.x + normal.x.map(1, -1, 0, 1) * this.size.x;
var y = this.pos.y + normal.y.map(1, -1, 0, 1) * this.size.y;
var point = {
x: x,
y: y
};
```

With this:
```var point = edge.contact.m_manifold.points[0],
x = point.x,
y = point.y;
```
Hi!, sorry for the absence. I test the adjustement you gave me but it's not working either. The collision is reported way before it actually happens, only when the body had been rotated.
I had to go with Impactjs without box2d because of time but I'll try to do more tests to this issue.
Thanks.
Hi paul, I had the same problem. The way quidmonkey does its collision detection is by AABB rectangles similar to impacts. After some investigation, i found this on the web:

A very important point to note if you do this, is that the existence of a contact in these lists does not mean that the two fixtures of the contact are actually touching - it only means their AABBs are touching. If you want to know if the fixtures themselves are really touching you can use IsTouching() to check. Moron that later.

- http://www.iforce2d.net/b2dtut/collision-anatomy

So this is the way I do to make collision detection:

```init: function(x, y, settings) {
this.parent(x, y, settings);
if(!ig.global.wm) {
this.body.m_userData = 'player';
this.body.entity = this;
}
}
```

on lib\plugins\box2d\game.js
``` addContactListener: function() {
var listener = new b2.ContactListener();
var body1 = point.shape1.GetBody();
var body2 = point.shape2.GetBody();

// player vs enemy
if(
(body1.m_userData == 'player' || body2.m_userData == 'player') &&
(body1.m_userData == 'enemy' || body2.m_userData == 'enemy')
) {
// diferenciando los entities
var eA = body1.m_userData == 'player' ? body1.entity : body2.entity;
var eB = body1.m_userData == 'enemy' ? body1.entity : body2.entity;

eA.hit(5, eB);
}

//listener.Remove = function(point) {
//console.log('Remove Contact');
//}
//listener.Persist = function(point) {
//	console.log('Persist Contact');
//}
//listener.Result = function(point) {
//	console.log('Result Contact');
//}

ig.world.SetContactListener(listener);
},

```

then run it on the loadLevel function:

```loadLevel: function( data ) {

// Find the collision layer and create the box2d world from it
for( var i = 0; i < data.layer.length; i++ ) {
var ld = data.layer[i];
if( ld.name == 'collision' ) {
ig.world = this.createWorldFromMap( ld.data, ld.width, ld.height, ld.tilesize );
break;
}
}

this.parent( data );
},
```

Hope this is useful.
Hi Xatruch !, thank you very much for the help. That works for me!. Now I'm able to handle the collisions the way I needed.

Thanks!.
Great stuff, Xatruch. You should create a plugin yourself, since your method is superior. I may retire mine.
Hi quidmonkey thanks for the words. I really don't know how I can make this as a plugin?
I'll appreciate if you or anybody could help me?
even better, you can simply override Impact's built-in collision detection with Box2D using this method. As above, in lib\plugins\box2d\game.js:

```addContactListener: function() {
var listener = new b2.ContactListener();
var body1 = point.shape1.GetBody();
var body2 = point.shape2.GetBody();

//console.log(body1);

// if just background collision, ignore
if (body1.entity == null || body2.entity == null)
return;

//console.log(body1.entity.checkAgainst, body2.entity.type);

// Skip entities that don't check, don't get checked and don't collide
if (
body1.entity.type == ig.Entity.TYPE.NONE &&
body1.entity.checkAgainst == ig.Entity.TYPE.NONE &&
body1.entity.collides == ig.Entity.COLLIDES.NEVER
)
return;

ig.Entity.checkPair( body1.entity, body2.entity );

//listener.Remove = function(point) {
//console.log('Remove Contact');
//}
//listener.Persist = function(point) {
//    console.log('Persist Contact');
//}
//listener.Result = function(point) {
//    console.log('Result Contact');
//}
}
ig.world.SetContactListener(listener);
}
```

and then in /lib/impact/game.js, simply comment out all the code inside
##
checkEntities: function() {

}
##

. Now you can still use the collisions types, entity types, and check() function!
Also, I found that objects weren't being destroyed properly, so I edited the update() function of the /lib/impact/game.js file as follows:

```// remove all killed entities
for( var i = 0; i < this._deferredKill.length; i++ ) {
if (this._deferredKill[i] instanceof ig.Box2DEntity)
{
if (this._deferredKill[i].body != null)
ig.world.DestroyBody(this._deferredKill[i].body);
console.log('pop');
}
this.entities.erase( this._deferredKill[i] );
}
this._deferredKill = [];
```
Xatruch & pixelpusher:
```ig.module(
'plugins.box2d.collision'
)
.requires(
'plugins.box2d.entity',
'plugins.box2d.game'
)
.defines(function(){

ig.Box2DEntity.inject({

init: function (x, y, settings) {
this.parent(x, y, settings);
if (!ig.global.wm) {
this.body.entity = this;
}
}

});

ig.Box2DGame.inject({

// remove impact's collision detection
// for performance
checkEntities: function () {},

this.parent(data);

// create impact collision listener
var listener = new b2.ContactListener();
var a = point.shape1.GetBody().entity,
b = point.shape2.GetBody().entity;

// is this an entity collision?
if (!a || !b) {
return;
}

// preserve impact's entity checks even
// though these are unnecessary
if (a.checkAgainst & b.type) {
a.check(b);
}

if (b.checkAgainst & a.type) {
b.check(a);
}

// call impact
if (point.normal.y) {
a.collideWith(b, 'y');
b.collideWith(a, 'y');
}
else {
a.collideWith(b, 'x');
b.collideWith(a, 'x');
}
};

// attach to box2d world
ig.world.SetContactListener(listener);
}

});

});
```

This is an elegant solution. Good job!

This way will allow you to use Impact&`039;s #check` and `collideWith` functions and will make box2d more modular.
New version of the plugin released! OP has been updated with the details. Once again, a big thanks to Xatruch and pixelpusher! Hopefully this will now unlock the black box that is Box2d for Impact.
Thanks for all the work guys. This is just what I was looking for, but when I used it I wasn't getting events for collisions with the environment (handleMovementTrace). In collision.js I changed the body to the below code.

I didn't call handleMovementTrace itself because I'm not passing a res object and it was causing exceptions in code that was expecting a valid res. However, I think with some more work the res object could be rebuilt from the information available and the correct function call could be made.

```//is this a tile collision?
if (!a || !b)
{
if(a) { if(a.collideTile) { a.collideTile(); } } //jpe - fix this? i.e. pass res object? http://impactjs.com/documentation/class-reference/collisionmap#trace
if(b) { if(b.collideTile) { b.collideTile(); } }
}
// is this an entity collision?
else
{
// preserve impact's entity checks even
// though these are unnecessary
if (a.checkAgainst & b.type) {
a.check(b);
}

if (b.checkAgainst & a.type) {
b.check(a);
}

// call impact
if (point.normal.y) {
a.collideWith(b, 'y');
b.collideWith(a, 'y');
}
else {
a.collideWith(b, 'x');
b.collideWith(a, 'x');
}
}
```
Hi,
I am a newbie to impactjs. I looked at the Box2d physics sample that Dom put out. I was trying to combine box2d entities and regular impactjs entities. Is this possible? Can I use the plugin mentioned here? Also I started with Dom's physics Box2d sample - I believe the version is 1.18. How/where can I get Box2d v2.0.2 for impactjs?