优化碰撞算法
This commit is contained in:
5
source/bin/framework.d.ts
vendored
5
source/bin/framework.d.ts
vendored
@@ -2722,10 +2722,7 @@ declare module es {
|
|||||||
* @param min
|
* @param min
|
||||||
* @param max
|
* @param max
|
||||||
*/
|
*/
|
||||||
static getInterval(axis: Vector2, polygon: Polygon, min: number, max: number): {
|
static getInterval(axis: Vector2, polygon: Polygon, min: Ref<number>, max: Ref<number>): void;
|
||||||
min: number;
|
|
||||||
max: number;
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param circle
|
* @param circle
|
||||||
|
|||||||
@@ -5471,7 +5471,7 @@ var es;
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
Collisions.lineToLineIntersection = function (a1, a2, b1, b2) {
|
Collisions.lineToLineIntersection = function (a1, a2, b1, b2) {
|
||||||
var intersection = new es.Vector2(0, 0);
|
var intersection = es.Vector2.zero;
|
||||||
var b = es.Vector2.subtract(a2, a1);
|
var b = es.Vector2.subtract(a2, a1);
|
||||||
var d = es.Vector2.subtract(b2, b1);
|
var d = es.Vector2.subtract(b2, b1);
|
||||||
var bDotDPerp = b.x * d.y - b.y * d.x;
|
var bDotDPerp = b.x * d.y - b.y * d.x;
|
||||||
@@ -5507,8 +5507,8 @@ var es;
|
|||||||
Collisions.rectToCircle = function (rect, cPosition, cRadius) {
|
Collisions.rectToCircle = function (rect, cPosition, cRadius) {
|
||||||
if (this.rectToPoint(rect.x, rect.y, rect.width, rect.height, cPosition))
|
if (this.rectToPoint(rect.x, rect.y, rect.width, rect.height, cPosition))
|
||||||
return true;
|
return true;
|
||||||
var edgeFrom = es.Vector2.zero;
|
var edgeFrom;
|
||||||
var edgeTo = es.Vector2.zero;
|
var edgeTo;
|
||||||
var sector = this.getSector(rect.x, rect.y, rect.width, rect.height, cPosition);
|
var sector = this.getSector(rect.x, rect.y, rect.width, rect.height, cPosition);
|
||||||
if ((sector & PointSectors.top) != 0) {
|
if ((sector & PointSectors.top) != 0) {
|
||||||
edgeFrom = new es.Vector2(rect.x, rect.y);
|
edgeFrom = new es.Vector2(rect.x, rect.y);
|
||||||
@@ -5523,6 +5523,12 @@ var es;
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((sector & PointSectors.left) != 0) {
|
if ((sector & PointSectors.left) != 0) {
|
||||||
|
edgeFrom = new es.Vector2(rect.x, rect.y);
|
||||||
|
edgeTo = new es.Vector2(rect.x, rect.y + rect.height);
|
||||||
|
if (this.circleToLine(cPosition, cRadius, edgeFrom, edgeTo))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ((sector & PointSectors.right) != 0) {
|
||||||
edgeFrom = new es.Vector2(rect.x + rect.width, rect.y);
|
edgeFrom = new es.Vector2(rect.x + rect.width, rect.y);
|
||||||
edgeTo = new es.Vector2(rect.x + rect.width, rect.y + rect.height);
|
edgeTo = new es.Vector2(rect.x + rect.width, rect.y + rect.height);
|
||||||
if (this.circleToLine(cPosition, cRadius, edgeFrom, edgeTo))
|
if (this.circleToLine(cPosition, cRadius, edgeFrom, edgeTo))
|
||||||
@@ -5957,25 +5963,25 @@ var es;
|
|||||||
* @param layerMask
|
* @param layerMask
|
||||||
*/
|
*/
|
||||||
SpatialHash.prototype.overlapCircle = function (circleCenter, radius, results, layerMask) {
|
SpatialHash.prototype.overlapCircle = function (circleCenter, radius, results, layerMask) {
|
||||||
|
var _this = this;
|
||||||
var bounds = new es.Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2);
|
var bounds = new es.Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2);
|
||||||
this._overlapTestCircle.radius = radius;
|
this._overlapTestCircle.radius = radius;
|
||||||
this._overlapTestCircle.position = circleCenter;
|
this._overlapTestCircle.position = circleCenter;
|
||||||
var resultCounter = 0;
|
var resultCounter = 0;
|
||||||
var potentials = this.aabbBroadphase(bounds, null, layerMask);
|
var potentials = this.aabbBroadphase(bounds, null, layerMask);
|
||||||
for (var i = 0; i < potentials.size; i++) {
|
potentials.forEach(function (collider) {
|
||||||
var collider = potentials[i];
|
|
||||||
if (collider instanceof es.BoxCollider) {
|
if (collider instanceof es.BoxCollider) {
|
||||||
results[resultCounter] = collider;
|
results[resultCounter] = collider;
|
||||||
resultCounter++;
|
resultCounter++;
|
||||||
}
|
}
|
||||||
else if (collider instanceof es.CircleCollider) {
|
else if (collider instanceof es.CircleCollider) {
|
||||||
if (collider.shape.overlaps(this._overlapTestCircle)) {
|
if (collider.shape.overlaps(_this._overlapTestCircle)) {
|
||||||
results[resultCounter] = collider;
|
results[resultCounter] = collider;
|
||||||
resultCounter++;
|
resultCounter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (collider instanceof es.PolygonCollider) {
|
else if (collider instanceof es.PolygonCollider) {
|
||||||
if (collider.shape.overlaps(this._overlapTestCircle)) {
|
if (collider.shape.overlaps(_this._overlapTestCircle)) {
|
||||||
results[resultCounter] = collider;
|
results[resultCounter] = collider;
|
||||||
resultCounter++;
|
resultCounter++;
|
||||||
}
|
}
|
||||||
@@ -5986,7 +5992,7 @@ var es;
|
|||||||
// 如果我们所有的结果数据有了则返回
|
// 如果我们所有的结果数据有了则返回
|
||||||
if (resultCounter == results.length)
|
if (resultCounter == results.length)
|
||||||
return resultCounter;
|
return resultCounter;
|
||||||
}
|
});
|
||||||
return resultCounter;
|
return resultCounter;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
@@ -6277,7 +6283,7 @@ var es;
|
|||||||
distanceSquared.value = Number.MAX_VALUE;
|
distanceSquared.value = Number.MAX_VALUE;
|
||||||
edgeNormal.x = 0;
|
edgeNormal.x = 0;
|
||||||
edgeNormal.y = 0;
|
edgeNormal.y = 0;
|
||||||
var closestPoint = new es.Vector2(0, 0);
|
var closestPoint = es.Vector2.zero;
|
||||||
var tempDistanceSquared = 0;
|
var tempDistanceSquared = 0;
|
||||||
for (var i = 0; i < points.length; i++) {
|
for (var i = 0; i < points.length; i++) {
|
||||||
var j = i + 1;
|
var j = i + 1;
|
||||||
@@ -6677,23 +6683,19 @@ var es;
|
|||||||
axis = secondEdges[edgeIndex - firstEdges.length];
|
axis = secondEdges[edgeIndex - firstEdges.length];
|
||||||
}
|
}
|
||||||
// 求多边形在当前轴上的投影
|
// 求多边形在当前轴上的投影
|
||||||
var minA = 0;
|
var minA = new es.Ref(0);
|
||||||
var minB = 0;
|
var minB = new es.Ref(0);
|
||||||
var maxA = 0;
|
var maxA = new es.Ref(0);
|
||||||
var maxB = 0;
|
var maxB = new es.Ref(0);
|
||||||
var intervalDist = 0;
|
var intervalDist = 0;
|
||||||
var ta = this.getInterval(axis, first, minA, maxA);
|
this.getInterval(axis, first, minA, maxA);
|
||||||
minA = ta.min;
|
this.getInterval(axis, second, minB, maxB);
|
||||||
minB = ta.max;
|
|
||||||
var tb = this.getInterval(axis, second, minB, maxB);
|
|
||||||
minB = tb.min;
|
|
||||||
maxB = tb.max;
|
|
||||||
// 将区间设为第二个多边形的空间。由轴上投影的位置差偏移。
|
// 将区间设为第二个多边形的空间。由轴上投影的位置差偏移。
|
||||||
var relativeIntervalOffset = es.Vector2.dot(polygonOffset, axis);
|
var relativeIntervalOffset = es.Vector2.dot(polygonOffset, axis);
|
||||||
minA += relativeIntervalOffset;
|
minA.value += relativeIntervalOffset;
|
||||||
maxA += relativeIntervalOffset;
|
maxA.value += relativeIntervalOffset;
|
||||||
// 检查多边形投影是否正在相交
|
// 检查多边形投影是否正在相交
|
||||||
intervalDist = this.intervalDistance(minA, maxA, minB, maxB);
|
intervalDist = this.intervalDistance(minA.value, maxA.value, minB.value, maxB.value);
|
||||||
if (intervalDist > 0)
|
if (intervalDist > 0)
|
||||||
isIntersecting = false;
|
isIntersecting = false;
|
||||||
// 对于多对多数据类型转换,添加一个Vector2?参数称为deltaMovement。为了提高速度,我们这里不使用它
|
// 对于多对多数据类型转换,添加一个Vector2?参数称为deltaMovement。为了提高速度,我们这里不使用它
|
||||||
@@ -6707,12 +6709,12 @@ var es;
|
|||||||
minIntervalDistance = intervalDist;
|
minIntervalDistance = intervalDist;
|
||||||
translationAxis = axis;
|
translationAxis = axis;
|
||||||
if (es.Vector2.dot(translationAxis, polygonOffset) < 0)
|
if (es.Vector2.dot(translationAxis, polygonOffset) < 0)
|
||||||
translationAxis = new es.Vector2(-translationAxis);
|
translationAxis = new es.Vector2(-translationAxis.x, -translationAxis.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 利用最小平移向量对多边形进行推入。
|
// 利用最小平移向量对多边形进行推入。
|
||||||
result.normal = translationAxis;
|
result.normal = translationAxis;
|
||||||
result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(-translationAxis.x, -translationAxis.y), new es.Vector2(minIntervalDistance));
|
result.minimumTranslationVector = new es.Vector2(-translationAxis.x * minIntervalDistance, -translationAxis.y * minIntervalDistance);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
@@ -6736,17 +6738,16 @@ var es;
|
|||||||
*/
|
*/
|
||||||
ShapeCollisions.getInterval = function (axis, polygon, min, max) {
|
ShapeCollisions.getInterval = function (axis, polygon, min, max) {
|
||||||
var dot = es.Vector2.dot(polygon.points[0], axis);
|
var dot = es.Vector2.dot(polygon.points[0], axis);
|
||||||
min = max = dot;
|
min.value = max.value = dot;
|
||||||
for (var i = 1; i < polygon.points.length; i++) {
|
for (var i = 1; i < polygon.points.length; i++) {
|
||||||
dot = es.Vector2.dot(polygon.points[i], axis);
|
dot = es.Vector2.dot(polygon.points[i], axis);
|
||||||
if (dot < min) {
|
if (dot < min.value) {
|
||||||
min = dot;
|
min.value = dot;
|
||||||
}
|
}
|
||||||
else if (dot > max) {
|
else if (dot > max.value) {
|
||||||
max = dot;
|
max.value = dot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { min: min, max: max };
|
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -6755,23 +6756,31 @@ var es;
|
|||||||
* @param result
|
* @param result
|
||||||
*/
|
*/
|
||||||
ShapeCollisions.circleToPolygon = function (circle, polygon, result) {
|
ShapeCollisions.circleToPolygon = function (circle, polygon, result) {
|
||||||
|
// 圆圈在多边形中的位置坐标
|
||||||
var poly2Circle = es.Vector2.subtract(circle.position, polygon.position);
|
var poly2Circle = es.Vector2.subtract(circle.position, polygon.position);
|
||||||
|
// 首先,我们需要找到从圆到多边形的最近距离
|
||||||
var distanceSquared = new es.Ref(0);
|
var distanceSquared = new es.Ref(0);
|
||||||
var closestPoint = es.Polygon.getClosestPointOnPolygonToPoint(polygon.points, poly2Circle, distanceSquared, result.normal);
|
var closestPoint = es.Polygon.getClosestPointOnPolygonToPoint(polygon.points, poly2Circle, distanceSquared, result.normal);
|
||||||
|
// 确保距离的平方小于半径的平方,否则我们不会相撞。
|
||||||
|
// 请注意,如果圆完全包含在多边形中,距离可能大于半径。
|
||||||
|
// 正因为如此,我们还要确保圆的位置不在多边形内。
|
||||||
var circleCenterInsidePoly = polygon.containsPoint(circle.position);
|
var circleCenterInsidePoly = polygon.containsPoint(circle.position);
|
||||||
if (distanceSquared.value > circle.radius * circle.radius && !circleCenterInsidePoly)
|
if (distanceSquared.value > circle.radius * circle.radius && !circleCenterInsidePoly)
|
||||||
return false;
|
return false;
|
||||||
|
// 算出MTV。我们要注意处理完全包含在多边形中的圆或包含其中心的圆
|
||||||
var mtv;
|
var mtv;
|
||||||
if (circleCenterInsidePoly) {
|
if (circleCenterInsidePoly) {
|
||||||
mtv = es.Vector2.multiply(result.normal, new es.Vector2(Math.sqrt(distanceSquared.value) - circle.radius));
|
mtv = es.Vector2.multiply(result.normal, new es.Vector2(Math.sqrt(distanceSquared.value) - circle.radius));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// 如果我们没有距离,这意味着圆心在多边形的边缘上。只需根据它的半径移动它
|
||||||
if (distanceSquared.value == 0) {
|
if (distanceSquared.value == 0) {
|
||||||
mtv = es.Vector2.multiply(result.normal, new es.Vector2(circle.radius));
|
mtv = new es.Vector2(result.normal.x * circle.radius, result.normal.y * circle.radius);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var distance = Math.sqrt(distanceSquared.value);
|
var distance = Math.sqrt(distanceSquared.value);
|
||||||
mtv = es.Vector2.multiply(new es.Vector2(-es.Vector2.subtract(poly2Circle, closestPoint)), new es.Vector2((circle.radius - distanceSquared.value) / distance));
|
mtv = new es.Vector2(-poly2Circle.x + closestPoint.x, -poly2Circle.y + closestPoint.y)
|
||||||
|
.multiply(new es.Vector2((circle.radius - distance) / distance));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.minimumTranslationVector = mtv;
|
result.minimumTranslationVector = mtv;
|
||||||
|
|||||||
2
source/bin/framework.min.js
vendored
2
source/bin/framework.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -34,7 +34,7 @@ module es {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static lineToLineIntersection(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): Vector2 {
|
public static lineToLineIntersection(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): Vector2 {
|
||||||
let intersection = new Vector2(0, 0);
|
let intersection = Vector2.zero;
|
||||||
|
|
||||||
let b = Vector2.subtract(a2, a1);
|
let b = Vector2.subtract(a2, a1);
|
||||||
let d = Vector2.subtract(b2, b1);
|
let d = Vector2.subtract(b2, b1);
|
||||||
@@ -83,8 +83,8 @@ module es {
|
|||||||
if (this.rectToPoint(rect.x, rect.y, rect.width, rect.height, cPosition))
|
if (this.rectToPoint(rect.x, rect.y, rect.width, rect.height, cPosition))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
let edgeFrom: Vector2 = Vector2.zero;
|
let edgeFrom: Vector2;
|
||||||
let edgeTo: Vector2 = Vector2.zero;
|
let edgeTo: Vector2;
|
||||||
let sector = this.getSector(rect.x, rect.y, rect.width, rect.height, cPosition);
|
let sector = this.getSector(rect.x, rect.y, rect.width, rect.height, cPosition);
|
||||||
|
|
||||||
if ((sector & PointSectors.top) != 0){
|
if ((sector & PointSectors.top) != 0){
|
||||||
@@ -102,6 +102,13 @@ module es {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((sector & PointSectors.left) != 0){
|
if ((sector & PointSectors.left) != 0){
|
||||||
|
edgeFrom = new Vector2(rect.x, rect.y);
|
||||||
|
edgeTo = new Vector2(rect.x, rect.y + rect.height);
|
||||||
|
if (this.circleToLine(cPosition, cRadius, edgeFrom, edgeTo))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((sector & PointSectors.right) != 0) {
|
||||||
edgeFrom = new Vector2(rect.x + rect.width, rect.y);
|
edgeFrom = new Vector2(rect.x + rect.width, rect.y);
|
||||||
edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height);
|
edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height);
|
||||||
if (this.circleToLine(cPosition, cRadius, edgeFrom, edgeTo))
|
if (this.circleToLine(cPosition, cRadius, edgeFrom, edgeTo))
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ module es {
|
|||||||
distanceSquared.value = Number.MAX_VALUE;
|
distanceSquared.value = Number.MAX_VALUE;
|
||||||
edgeNormal.x = 0;
|
edgeNormal.x = 0;
|
||||||
edgeNormal.y = 0;
|
edgeNormal.y = 0;
|
||||||
let closestPoint = new Vector2(0, 0);
|
let closestPoint = Vector2.zero;
|
||||||
|
|
||||||
let tempDistanceSquared = 0;
|
let tempDistanceSquared = 0;
|
||||||
for (let i = 0; i < points.length; i++) {
|
for (let i = 0; i < points.length; i++) {
|
||||||
|
|||||||
@@ -32,25 +32,21 @@ module es {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 求多边形在当前轴上的投影
|
// 求多边形在当前轴上的投影
|
||||||
let minA = 0;
|
let minA = new Ref(0);
|
||||||
let minB = 0;
|
let minB = new Ref(0);
|
||||||
let maxA = 0;
|
let maxA = new Ref(0);
|
||||||
let maxB = 0;
|
let maxB = new Ref(0);
|
||||||
let intervalDist = 0;
|
let intervalDist = 0;
|
||||||
let ta = this.getInterval(axis, first, minA, maxA);
|
this.getInterval(axis, first, minA, maxA);
|
||||||
minA = ta.min;
|
this.getInterval(axis, second, minB, maxB);
|
||||||
minB = ta.max;
|
|
||||||
let tb = this.getInterval(axis, second, minB, maxB);
|
|
||||||
minB = tb.min;
|
|
||||||
maxB = tb.max;
|
|
||||||
|
|
||||||
// 将区间设为第二个多边形的空间。由轴上投影的位置差偏移。
|
// 将区间设为第二个多边形的空间。由轴上投影的位置差偏移。
|
||||||
let relativeIntervalOffset = Vector2.dot(polygonOffset, axis);
|
let relativeIntervalOffset = Vector2.dot(polygonOffset, axis);
|
||||||
minA += relativeIntervalOffset;
|
minA.value += relativeIntervalOffset;
|
||||||
maxA += relativeIntervalOffset;
|
maxA.value += relativeIntervalOffset;
|
||||||
|
|
||||||
// 检查多边形投影是否正在相交
|
// 检查多边形投影是否正在相交
|
||||||
intervalDist = this.intervalDistance(minA, maxA, minB, maxB);
|
intervalDist = this.intervalDistance(minA.value, maxA.value, minB.value, maxB.value);
|
||||||
if (intervalDist > 0)
|
if (intervalDist > 0)
|
||||||
isIntersecting = false;
|
isIntersecting = false;
|
||||||
|
|
||||||
@@ -68,13 +64,13 @@ module es {
|
|||||||
translationAxis = axis;
|
translationAxis = axis;
|
||||||
|
|
||||||
if (Vector2.dot(translationAxis, polygonOffset) < 0)
|
if (Vector2.dot(translationAxis, polygonOffset) < 0)
|
||||||
translationAxis = new Vector2(-translationAxis);
|
translationAxis = new Vector2(-translationAxis.x, -translationAxis.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 利用最小平移向量对多边形进行推入。
|
// 利用最小平移向量对多边形进行推入。
|
||||||
result.normal = translationAxis;
|
result.normal = translationAxis;
|
||||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(-translationAxis.x, -translationAxis.y), new Vector2(minIntervalDistance));
|
result.minimumTranslationVector = new Vector2(-translationAxis.x * minIntervalDistance, -translationAxis.y * minIntervalDistance);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -100,20 +96,18 @@ module es {
|
|||||||
* @param min
|
* @param min
|
||||||
* @param max
|
* @param max
|
||||||
*/
|
*/
|
||||||
public static getInterval(axis: Vector2, polygon: Polygon, min: number, max: number) {
|
public static getInterval(axis: Vector2, polygon: Polygon, min: Ref<number>, max: Ref<number>) {
|
||||||
let dot = Vector2.dot(polygon.points[0], axis);
|
let dot = Vector2.dot(polygon.points[0], axis);
|
||||||
min = max = dot;
|
min.value = max.value = dot;
|
||||||
|
|
||||||
for (let i = 1; i < polygon.points.length; i++) {
|
for (let i = 1; i < polygon.points.length; i++) {
|
||||||
dot = Vector2.dot(polygon.points[i], axis);
|
dot = Vector2.dot(polygon.points[i], axis);
|
||||||
if (dot < min) {
|
if (dot < min.value ) {
|
||||||
min = dot;
|
min.value = dot;
|
||||||
} else if (dot > max) {
|
} else if (dot > max.value) {
|
||||||
max = dot;
|
max.value = dot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {min: min, max: max};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -123,24 +117,32 @@ module es {
|
|||||||
* @param result
|
* @param result
|
||||||
*/
|
*/
|
||||||
public static circleToPolygon(circle: Circle, polygon: Polygon, result: CollisionResult): boolean {
|
public static circleToPolygon(circle: Circle, polygon: Polygon, result: CollisionResult): boolean {
|
||||||
|
// 圆圈在多边形中的位置坐标
|
||||||
let poly2Circle = Vector2.subtract(circle.position, polygon.position);
|
let poly2Circle = Vector2.subtract(circle.position, polygon.position);
|
||||||
|
|
||||||
|
// 首先,我们需要找到从圆到多边形的最近距离
|
||||||
let distanceSquared = new Ref(0);
|
let distanceSquared = new Ref(0);
|
||||||
let closestPoint = Polygon.getClosestPointOnPolygonToPoint(polygon.points, poly2Circle, distanceSquared, result.normal);
|
let closestPoint = Polygon.getClosestPointOnPolygonToPoint(polygon.points, poly2Circle, distanceSquared, result.normal);
|
||||||
|
|
||||||
|
// 确保距离的平方小于半径的平方,否则我们不会相撞。
|
||||||
|
// 请注意,如果圆完全包含在多边形中,距离可能大于半径。
|
||||||
|
// 正因为如此,我们还要确保圆的位置不在多边形内。
|
||||||
let circleCenterInsidePoly = polygon.containsPoint(circle.position);
|
let circleCenterInsidePoly = polygon.containsPoint(circle.position);
|
||||||
if (distanceSquared.value > circle.radius * circle.radius && !circleCenterInsidePoly)
|
if (distanceSquared.value > circle.radius * circle.radius && !circleCenterInsidePoly)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// 算出MTV。我们要注意处理完全包含在多边形中的圆或包含其中心的圆
|
||||||
let mtv: Vector2;
|
let mtv: Vector2;
|
||||||
if (circleCenterInsidePoly) {
|
if (circleCenterInsidePoly) {
|
||||||
mtv = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared.value) - circle.radius));
|
mtv = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared.value) - circle.radius));
|
||||||
} else {
|
} else {
|
||||||
|
// 如果我们没有距离,这意味着圆心在多边形的边缘上。只需根据它的半径移动它
|
||||||
if (distanceSquared.value == 0) {
|
if (distanceSquared.value == 0) {
|
||||||
mtv = Vector2.multiply(result.normal, new Vector2(circle.radius));
|
mtv = new Vector2(result.normal.x * circle.radius, result.normal.y * circle.radius);
|
||||||
} else {
|
} else {
|
||||||
let distance = Math.sqrt(distanceSquared.value);
|
let distance = Math.sqrt(distanceSquared.value);
|
||||||
mtv = Vector2.multiply(new Vector2(-Vector2.subtract(poly2Circle, closestPoint)), new Vector2((circle.radius - distanceSquared.value) / distance));
|
mtv = new Vector2(-poly2Circle.x + closestPoint.x, -poly2Circle.y + closestPoint.y)
|
||||||
|
.multiply(new Vector2((circle.radius - distance) / distance));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -209,8 +209,7 @@ module es {
|
|||||||
|
|
||||||
let resultCounter = 0;
|
let resultCounter = 0;
|
||||||
let potentials = this.aabbBroadphase(bounds, null, layerMask);
|
let potentials = this.aabbBroadphase(bounds, null, layerMask);
|
||||||
for (let i = 0; i < potentials.size; i++) {
|
potentials.forEach(collider => {
|
||||||
let collider = potentials[i];
|
|
||||||
if (collider instanceof BoxCollider) {
|
if (collider instanceof BoxCollider) {
|
||||||
results[resultCounter] = collider;
|
results[resultCounter] = collider;
|
||||||
resultCounter++;
|
resultCounter++;
|
||||||
@@ -231,7 +230,7 @@ module es {
|
|||||||
// 如果我们所有的结果数据有了则返回
|
// 如果我们所有的结果数据有了则返回
|
||||||
if (resultCounter == results.length)
|
if (resultCounter == results.length)
|
||||||
return resultCounter;
|
return resultCounter;
|
||||||
}
|
});
|
||||||
|
|
||||||
return resultCounter;
|
return resultCounter;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user