新增Ref类型
This commit is contained in:
@@ -163,8 +163,8 @@ module es {
|
||||
* @param distanceSquared
|
||||
* @param edgeNormal
|
||||
*/
|
||||
public static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2, distanceSquared: Number, edgeNormal: Vector2): Vector2 {
|
||||
distanceSquared = Number.MAX_VALUE;
|
||||
public static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2, distanceSquared: Ref<number>, edgeNormal: Vector2): Vector2 {
|
||||
distanceSquared.value = Number.MAX_VALUE;
|
||||
edgeNormal.x = 0;
|
||||
edgeNormal.y = 0;
|
||||
let closestPoint = new Vector2(0, 0);
|
||||
@@ -178,8 +178,8 @@ module es {
|
||||
let closest = ShapeCollisions.closestPointOnLine(points[i], points[j], point);
|
||||
tempDistanceSquared = Vector2.distanceSquared(point, closest);
|
||||
|
||||
if (tempDistanceSquared < distanceSquared) {
|
||||
distanceSquared = tempDistanceSquared;
|
||||
if (tempDistanceSquared < distanceSquared.value) {
|
||||
distanceSquared.value = tempDistanceSquared;
|
||||
closestPoint = closest;
|
||||
|
||||
// 求直线的法线
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
module es {
|
||||
export class RealtimeCollisions {
|
||||
public static intersectMovingCircleToBox(s: Circle, b: Box, movement: Vector2): number {
|
||||
public static intersectMovingCircleBox(s: Circle, b: Box, movement: Vector2, time: Ref<number>): boolean {
|
||||
// 计算用球面半径r inflate b得到的AABB
|
||||
let e = b.bounds;
|
||||
e.inflate(s.radius, s.radius);
|
||||
|
||||
// 射线与展开矩形e相交。如果射线错过了e,则退出不相交,否则得到相交点p和时间t
|
||||
let ray = new Ray2D(Vector2.subtract(s.position, movement), s.position);
|
||||
let time = e.rayIntersects(ray);
|
||||
if (time > 1)
|
||||
return time;
|
||||
if (!e.rayIntersects(ray, time) && time.value > 1)
|
||||
return false;
|
||||
|
||||
// 求交点
|
||||
let point = Vector2.add(ray.start, Vector2.add(ray.direction, new Vector2(time)));
|
||||
let point = Vector2.add(ray.start, Vector2.add(ray.direction, new Vector2(time.value)));
|
||||
|
||||
// 计算b的最小面和最大面p的交点在哪个面之外。注意,u和v不能有相同的位集,它们之间必须至少有一个位集。
|
||||
let u, v = 0;
|
||||
@@ -38,11 +37,11 @@ module es {
|
||||
// 如果m中只设置了一个位,那么点在一个面区域
|
||||
if ((m & (m - 1)) == 0){
|
||||
// 什么也不做。从扩展矩形交集的时间是正确的时间
|
||||
return time;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 点在边缘区域上。与边缘相交。
|
||||
return time;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,22 +125,22 @@ module es {
|
||||
public static circleToPolygon(circle: Circle, polygon: Polygon, result: CollisionResult): boolean {
|
||||
let poly2Circle = Vector2.subtract(circle.position, polygon.position);
|
||||
|
||||
let distanceSquared = 0;
|
||||
let distanceSquared = new Ref(0);
|
||||
let closestPoint = Polygon.getClosestPointOnPolygonToPoint(polygon.points, poly2Circle, distanceSquared, result.normal);
|
||||
|
||||
let circleCenterInsidePoly = polygon.containsPoint(circle.position);
|
||||
if (distanceSquared > circle.radius * circle.radius && !circleCenterInsidePoly)
|
||||
if (distanceSquared.value > circle.radius * circle.radius && !circleCenterInsidePoly)
|
||||
return false;
|
||||
|
||||
let mtv: Vector2;
|
||||
if (circleCenterInsidePoly) {
|
||||
mtv = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared) - circle.radius));
|
||||
mtv = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared.value) - circle.radius));
|
||||
} else {
|
||||
if (distanceSquared == 0) {
|
||||
if (distanceSquared.value == 0) {
|
||||
mtv = Vector2.multiply(result.normal, new Vector2(circle.radius));
|
||||
} else {
|
||||
let distance = Math.sqrt(distanceSquared);
|
||||
mtv = Vector2.multiply(new Vector2(-Vector2.subtract(poly2Circle, closestPoint)), new Vector2((circle.radius - distanceSquared) / distance));
|
||||
let distance = Math.sqrt(distanceSquared.value);
|
||||
mtv = Vector2.multiply(new Vector2(-Vector2.subtract(poly2Circle, closestPoint)), new Vector2((circle.radius - distanceSquared.value) / distance));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,10 +245,10 @@ module es {
|
||||
*/
|
||||
public static pointToPoly(point: Vector2, poly: Polygon, result: CollisionResult): boolean {
|
||||
if (poly.containsPoint(point)) {
|
||||
let distanceSquared: number = 0;
|
||||
let distanceSquared = new Ref(0);
|
||||
let closestPoint = Polygon.getClosestPointOnPolygonToPoint(poly.points, Vector2.subtract(point, poly.position), distanceSquared, result.normal);
|
||||
|
||||
result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared), Math.sqrt(distanceSquared)));
|
||||
result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared.value), Math.sqrt(distanceSquared.value)));
|
||||
result.point = Vector2.add(closestPoint, poly.position);
|
||||
|
||||
return true;
|
||||
@@ -295,7 +295,7 @@ module es {
|
||||
return false;
|
||||
|
||||
result.normal = new Vector2(-result.minimumTranslationVector.x, -result.minimumTranslationVector.y);
|
||||
result.normal = result.normal.normalize();
|
||||
result.normal.normalize();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -342,7 +342,7 @@ module es {
|
||||
}
|
||||
|
||||
if (hasIntersection){
|
||||
normal = normal.normalize();
|
||||
normal.normalize();
|
||||
let distance = Vector2.distance(start, intersectionPoint);
|
||||
hit.setValuesNonCollider(fraction, distance, intersectionPoint, normal);
|
||||
return true;
|
||||
@@ -423,7 +423,7 @@ module es {
|
||||
return false;
|
||||
|
||||
hit.normal = new Vector2(-mtv.x);
|
||||
hit.normal = hit.normal.normalize();
|
||||
hit.normal.normalize();
|
||||
hit.distance = 0;
|
||||
hit.fraction = 0;
|
||||
|
||||
@@ -431,13 +431,13 @@ module es {
|
||||
}else{
|
||||
// 射线投射移动矢量
|
||||
let ray = new Ray2D(Vector2.zero, new Vector2(-movement.x));
|
||||
let fraction: number = minkowskiDiff.rayIntersects(ray);
|
||||
if (fraction <= 1){
|
||||
hit.fraction = fraction;
|
||||
hit.distance = movement.length() * fraction;
|
||||
hit.normal = new Vector2(-movement.x);
|
||||
hit.normal = hit.normal.normalize();
|
||||
hit.centroid = Vector2.add(first.bounds.center, Vector2.multiply(movement, new Vector2(fraction)));
|
||||
let fraction = new Ref(0);
|
||||
if (minkowskiDiff.rayIntersects(ray, fraction) && fraction.value <= 1){
|
||||
hit.fraction = fraction.value;
|
||||
hit.distance = movement.length() * fraction.value;
|
||||
hit.normal = new Vector2(-movement.x, -movement.y);
|
||||
hit.normal.normalize();
|
||||
hit.centroid = Vector2.add(first.bounds.center, Vector2.multiply(movement, new Vector2(fraction.value)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user