修复normalized
This commit is contained in:
@@ -26,7 +26,7 @@ module es {
|
||||
let collider = colliders[i];
|
||||
|
||||
let neighbors = Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers);
|
||||
for (let j = 0; j < neighbors.size; j++) {
|
||||
for (let j = 0; j < neighbors.length; j++) {
|
||||
let neighbor = neighbors[j];
|
||||
// 我们至少需要一个碰撞器作为触发器
|
||||
if (!collider.isTrigger && !neighbor.isTrigger)
|
||||
|
||||
@@ -54,7 +54,10 @@ module es {
|
||||
this.points = points;
|
||||
this.recalculateCenterAndEdgeNormals();
|
||||
|
||||
this._originalPoints = this.points.slice();
|
||||
this._originalPoints = [];
|
||||
this.points.forEach(p => {
|
||||
this._originalPoints.push(p.clone());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -301,7 +304,7 @@ module es {
|
||||
*/
|
||||
public containsPoint(point: Vector2) {
|
||||
// 将点归一化到多边形坐标空间中
|
||||
point.subtract(this.position);
|
||||
point.sub(this.position);
|
||||
|
||||
let isInside = false;
|
||||
for (let i = 0, j = this.points.length - 1; i < this.points.length; j = i++) {
|
||||
|
||||
@@ -9,8 +9,8 @@ module es {
|
||||
public static polygonToPolygon(first: Polygon, second: Polygon, result: CollisionResult): boolean {
|
||||
let isIntersecting = true;
|
||||
|
||||
let firstEdges = first.edgeNormals.slice();
|
||||
let secondEdges = second.edgeNormals.slice();
|
||||
const firstEdges = first.edgeNormals;
|
||||
const secondEdges = second.edgeNormals;
|
||||
let minIntervalDistance = Number.POSITIVE_INFINITY;
|
||||
let translationAxis = es.Vector2.zero;
|
||||
let polygonOffset = Vector2.subtract(first.position, second.position);
|
||||
@@ -20,28 +20,20 @@ module es {
|
||||
for (let edgeIndex = 0; edgeIndex < firstEdges.length + secondEdges.length; edgeIndex++) {
|
||||
// 1. 找出当前多边形是否相交
|
||||
// 多边形的归一化轴垂直于缓存给我们的当前边
|
||||
if (edgeIndex < firstEdges.length) {
|
||||
axis = firstEdges[edgeIndex];
|
||||
} else {
|
||||
axis = secondEdges[edgeIndex - firstEdges.length];
|
||||
}
|
||||
axis = edgeIndex < firstEdges.length ? firstEdges[edgeIndex] : secondEdges[edgeIndex - firstEdges.length];
|
||||
|
||||
// 求多边形在当前轴上的投影
|
||||
let minA = new Ref(0);
|
||||
let minB = new Ref(0);
|
||||
let maxA = new Ref(0);
|
||||
let maxB = new Ref(0);
|
||||
let intervalDist = 0;
|
||||
this.getInterval(axis, first, minA, maxA);
|
||||
this.getInterval(axis, second, minB, maxB);
|
||||
let {min: minA, max: maxA} = this.getInterval(axis, first);
|
||||
const {min: minB, max: maxB} = this.getInterval(axis, second);
|
||||
|
||||
// 将区间设为第二个多边形的空间。由轴上投影的位置差偏移。
|
||||
let relativeIntervalOffset = Vector2.dot(polygonOffset, axis);
|
||||
minA.value += relativeIntervalOffset;
|
||||
maxA.value += relativeIntervalOffset;
|
||||
minA += relativeIntervalOffset;
|
||||
maxA += relativeIntervalOffset;
|
||||
|
||||
// 检查多边形投影是否正在相交
|
||||
intervalDist = this.intervalDistance(minA.value, maxA.value, minB.value, maxB.value);
|
||||
intervalDist = this.intervalDistance(minA, maxA, minB, maxB);
|
||||
if (intervalDist > 0)
|
||||
isIntersecting = false;
|
||||
|
||||
@@ -56,16 +48,16 @@ module es {
|
||||
intervalDist = Math.abs(intervalDist);
|
||||
if (intervalDist < minIntervalDistance) {
|
||||
minIntervalDistance = intervalDist;
|
||||
translationAxis = axis;
|
||||
translationAxis.setTo(axis.x, axis.y);
|
||||
|
||||
if (Vector2.dot(translationAxis, polygonOffset) < 0)
|
||||
translationAxis = new Vector2(-translationAxis.x, -translationAxis.y);
|
||||
translationAxis = translationAxis.scale(-1);
|
||||
}
|
||||
}
|
||||
|
||||
// 利用最小平移向量对多边形进行推入。
|
||||
result.normal = translationAxis;
|
||||
result.minimumTranslationVector = new Vector2(-translationAxis.x * minIntervalDistance, -translationAxis.y * minIntervalDistance);
|
||||
result.minimumTranslationVector = translationAxis.scale(minIntervalDistance * -1);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -77,18 +69,21 @@ module es {
|
||||
* @param min
|
||||
* @param max
|
||||
*/
|
||||
public static getInterval(axis: Vector2, polygon: Polygon, min: Ref<number>, max: Ref<number>) {
|
||||
let dot = Vector2.dot(polygon.points[0], axis);
|
||||
min.value = max.value = dot;
|
||||
|
||||
public static getInterval(axis: Vector2, polygon: Polygon): {min: number, max: number} {
|
||||
const res = {min: 0, max: 0};
|
||||
let dot: number;
|
||||
dot = Vector2.dot( polygon.points[0], axis);
|
||||
res.max = dot;
|
||||
res.min = dot;
|
||||
for (let i = 1; i < polygon.points.length; i++) {
|
||||
dot = Vector2.dot(polygon.points[i], axis);
|
||||
if (dot < min.value) {
|
||||
min.value = dot;
|
||||
} else if (dot > max.value) {
|
||||
max.value = dot;
|
||||
if (dot < res.min) {
|
||||
res.min = dot;
|
||||
} else if (dot > res.max) {
|
||||
res.max = dot;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,7 +93,7 @@ module es {
|
||||
* @param minB
|
||||
* @param maxB
|
||||
*/
|
||||
public static intervalDistance(minA: number, maxA: number, minB: number, maxB) {
|
||||
public static intervalDistance(minA: number, maxA: number, minB: number, maxB: number) {
|
||||
if (minA < minB)
|
||||
return minB - maxA;
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ module es {
|
||||
* @param excludeCollider
|
||||
* @param layerMask
|
||||
*/
|
||||
public aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number): Set<Collider> {
|
||||
public aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number): Collider[] {
|
||||
this._tempHashSet.clear();
|
||||
|
||||
let p1 = this.cellCoords(bounds.x, bounds.y);
|
||||
@@ -124,12 +124,12 @@ module es {
|
||||
for (let x = p1.x; x <= p2.x; x++) {
|
||||
for (let y = p1.y; y <= p2.y; y++) {
|
||||
let cell = this.cellAtPosition(x, y);
|
||||
if (cell == null)
|
||||
if (!cell)
|
||||
continue;
|
||||
|
||||
// 当cell不为空。循环并取回所有碰撞器
|
||||
for (let i = 0; i < cell.length; i++) {
|
||||
let collider = cell[i];
|
||||
const collider = cell[i];
|
||||
|
||||
// 如果它是自身或者如果它不匹配我们的层掩码 跳过这个碰撞器
|
||||
if (collider == excludeCollider || !Flags.isFlagSet(layerMask, collider.physicsLayer.value))
|
||||
@@ -142,7 +142,7 @@ module es {
|
||||
}
|
||||
}
|
||||
|
||||
return this._tempHashSet;
|
||||
return Array.from(this._tempHashSet);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -365,7 +365,7 @@ module es {
|
||||
* @param y
|
||||
*/
|
||||
public cellCoords(x: number, y: number): Vector2 {
|
||||
return new Vector2(MathHelper.floorToInt(x * this._inverseCellSize), MathHelper.floorToInt(y * this._inverseCellSize));
|
||||
return new Vector2(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user