Created
July 5, 2012 15:43
-
-
Save kirbysayshi/3054439 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ig.module( | |
'plugins.collision-map-intersect' | |
) | |
.requires( | |
'impact.collision-map' | |
,'plugins.math' | |
) | |
.defines(function(){ | |
// Injects: | |
// res.collision.snx: surface normal x | |
// res.collision.sny: surface normal y | |
// res.collision.initial = { x, y }: the point at which the projected velocity line collides with a tile | |
ig.CollisionMap.inject({ | |
_traceStep: function( res, x, y, vx, vy, width, height, rvx, rvy, step ) { | |
this.parent.apply(this, arguments); | |
var pxTileX, pxTileY, iRes = {} | |
,a1x = x + width / 2 | |
,a1y = y + height / 2 | |
,a2x = a1x + vx | |
,a2y = a1y + vy | |
// if vx or vy is 0, that means it's already been handled | |
if( res.collision.x && vx !== 0 ){ | |
pxTileX = res.pos.x | |
+ (vx > 0 ? width : 0) // correct for "pxOffsetX" | |
//- (vx > 0 ? this.tilesize : 0 ); // correct for tileOffsetX | |
// perform intersection test with velocity line and vertical tile line. | |
// the 0/100 is arbitrary, to extend the vertical line a "visible" amount. | |
// this assumes the velocity vector is projected out from the center | |
// when in actuallity the initial check was projected from the upper left corner | |
ig.math.intersectLineLine( | |
a1x, a1y, a2x, a2y, | |
pxTileX, 0, pxTileX, 100, | |
iRes | |
); | |
res.collision.snx = vx > 0 ? -1 : 1; | |
res.collision.sny = 0; | |
} | |
if( res.collision.y && vy !== 0 ){ | |
pxTileY = res.pos.y | |
+ (vy > 0 ? height : 0) // correct for "pxOffsetX" | |
//+ (vy > 0 ? this.tilesize : 0); // correct for tileOffsetX | |
// perform intersection test with velocity line and horizontal tile line. | |
// the 100s are arbitrary, to extend the horizontal line a "visible" amount. | |
// this assumes the velocity vector is projected out from the center | |
// when in actuallity the initial check was projected from the upper left corner | |
ig.math.intersectLineLine( | |
a1x, a1y, a2x, a2y, | |
0, pxTileY, 100, pxTileY, | |
iRes | |
); | |
res.collision.snx = 0; | |
res.collision.sny = vy > 0 ? -1 : 1; | |
} | |
if( res.collision.slope ){ | |
res.collision.snx = res.collision.slope.nx; | |
res.collision.sny = res.collision.slope.ny; | |
} | |
if( iRes.line ){ | |
res.collision.initial = { x: iRes.line.x, y: iRes.line.y }; | |
} | |
} | |
,_checkTileDef: function( res, t, x, y, vx, vy, width, height, tileX, tileY ) { | |
var def = this.tiledef[t]; | |
if( !def ) { return false; } | |
var result = this.parent.apply(this, arguments) | |
,slope = res.collision.slope | |
,a1x | |
,a1y | |
,a2x | |
,a2y | |
,b1x | |
,b1y | |
,b2x | |
,b2y | |
,iRes = {}; | |
if( result && slope ){ | |
// lx/ly appears to ALWAYS be the absolute pixel coords of the lower right | |
// corner of the collided tile. | |
// This point + the normal can define a parametric plane (really | |
// a line because this is 2D) which can be used to determine where | |
// the plane and the velocity vector (x,y -> x+vx,y+vy) cross. | |
slope.lx = (tileX + def[0]) * this.tilesize | |
slope.ly = (tileY + def[1]) * this.tilesize | |
a1x = (tileX + def[0]) * this.tilesize | |
a1y = (tileY + def[1]) * this.tilesize | |
a2x = (tileX + def[2]) * this.tilesize | |
a2y = (tileY + def[3]) * this.tilesize | |
// this assumes the velocity vector is projected out from the center | |
// when in actuallity the initial check was projected from the upper left corner | |
b1x = x + (width / 2) | |
b1y = y + (height / 2) | |
b2x = b1x + vx | |
b2y = b1y + vy | |
ig.math.intersectLineLine( a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y, iRes ); | |
if( iRes.line ){ | |
res.collision.initial = { x: iRes.line.x, y: iRes.line.y }; | |
} | |
} | |
return result; | |
} | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ig.module( | |
'plugins.math' | |
) | |
.requires() | |
.defines(function(){ | |
ig.math = ig.math || {}; | |
ig.math.angleTo = function( v1x, v1y, v2x, v2y ){ | |
var v1atan = Math.atan2( v1y, v1x ) | |
v2atan = 0; | |
if( v2x != null && v2y != null ){ | |
v2atan = Math.atan2( v2y, v2x ) | |
} | |
return v1atan - v2atan; | |
} | |
// adapted/ported from: http://paulbourke.net/geometry/lineline2d/Helpers.cs | |
ig.math.intersectLineLine = function(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y, res){ | |
res = res || {}; | |
res.parallel = false; | |
res.coincidental = false; | |
res.line = false; | |
res.segment = false; | |
var denom = (b2y - b1y) * (a2x - a1x) - (b2x - b1x) * (a2y - a1y) | |
,n_a = (b2x - b1x) * (a1y - b1y) - (b2y - b1y) * (a1x - b1x) | |
,n_b = (a2x - a1x) * (a1y - b1y) - (a2y - a1y) * (a1x - b1x); | |
// check for lines being parallel (or possibly coincidental) | |
if( denom == 0 ){ | |
res.parallel = true; | |
if( n_a === 0 && n_b === 0 ){ | |
res.coincidental = true; | |
} | |
return false | |
} | |
// calculate the scalar (fractional) that determines where each line | |
// could intersect (t in many versions) | |
var ua = n_a / denom | |
,ub = n_b / denom; | |
res.line = { | |
x: a1x + ( ua * (a2x - a1x) ) | |
,y: a1y + ( ua * (a2y - a1y) ) | |
}; | |
// test if segments intersect. 0 >= ua <= 1 implies intersection of | |
// the given segments, while 0 > ua > 1 implies that only the defined | |
// lines intersect | |
if( ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1 ){ | |
res.segment = res.line; | |
} | |
return true; | |
} | |
ig.math.exportV3 = function(){ | |
ig.global.v3 = ov3; | |
} | |
ig.math.v3 = ov3; | |
var ov3 = function(x, y, z){ | |
return { | |
x: x || 0, | |
y: y || 0, | |
z: z || 0 | |
} | |
}; | |
ov3.asArray = function( v1, target ){ | |
if( !target ){ | |
target = [ v1.x, v1.y, v1.z || 0 ] | |
} else { | |
target[0] = v1.x; | |
target[1] = v1.y; | |
target[2] = v1.z || 0; | |
} | |
return target; | |
} | |
ov3.fromArray = function( v1arr, target ){ | |
target = target || ov3(); | |
target.x = v1arr[0]; | |
target.y = v1arr[1]; | |
target.z = v1arr[2] || 0; | |
return target; | |
} | |
ov3.add = function(v1, v2, target){ | |
if(!target) target = v1; | |
target.x = v1.x + v2.x; | |
target.y = v1.y + v2.y; | |
target.z = v1.z + v2.z || 0; | |
return target; | |
} | |
ov3.sub = function(v1, v2, target){ | |
if(!target) target = v1; | |
target.x = v1.x - v2.x; | |
target.y = v1.y - v2.y; | |
target.z = v1.z - v2.z || 0; | |
return target; | |
} | |
ov3.scale = function(v1, x, target){ | |
if(!target) target = v1; | |
target.x = v1.x * x; | |
target.y = v1.y * x; | |
target.z = v1.z * x || 0; | |
return target; | |
} | |
ov3.normalize = function(v1, target){ | |
if(!target) target = v1; | |
var x = v1.x | |
,y = v1.y | |
,z = v1.z || 0 | |
,len = 1 / Math.sqrt(x*x + y*y + z*z); | |
target.x = x * len; | |
target.y = x * len; | |
target.z = x * len; | |
return target; | |
} | |
ov3.length = function(v1){ | |
var x = v1.x + v2.x | |
,y = v1.y + v2.y | |
,z = v1.z + v2.z || 0 | |
return Math.sqrt(x*x + y*y + z*z); | |
} | |
ov3.dot = function( v1, v2 ){ | |
return v1.x*v2.x + v1.y*v2.y + (v1.z || 0)*(v2.z || 0); | |
} | |
ov3.direction = function( v1, v2, target ){ | |
target = target || v1; | |
var x = v2.x - v1.x | |
,y = v2.y - v1.y | |
,z = v2.z - v1.z || 0 | |
,len = Math.sqrt(x*x + y*y + z*z); | |
if (!len) { | |
target.x = 0; | |
target.y = 0; | |
target.z = 0; | |
return target; | |
} | |
len = 1 / len; | |
target.x = x * len; | |
target.y = y * len; | |
target.z = z * len; | |
return target; | |
} | |
ov3.angleTo = function( v1, v2 ){ | |
var v1atan = Math.atan2( v1.y, v1.x ) | |
v2atan = 0; | |
if( v2 ){ | |
v2atan = Math.atan2( v2.y, v2.x ) | |
} | |
return v1atan - v2atan; | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment