新增Ref类型
This commit is contained in:
@@ -4,6 +4,9 @@ module es {
|
||||
public static renderableBounds = 0xffff00;
|
||||
public static renderableCenter = 0x9932CC;
|
||||
public static colliderBounds = 0x555555;
|
||||
public static colliderEdge = 0x8B0000;
|
||||
public static colliderPosition = 0xFFFF00;
|
||||
public static colliderCenter = 0xFF0000;
|
||||
}
|
||||
|
||||
export class Size {
|
||||
|
||||
@@ -97,7 +97,7 @@ module es {
|
||||
}
|
||||
|
||||
public debugRender() {
|
||||
let poly = this.shape;
|
||||
let poly = this.shape as Polygon;
|
||||
if (!this.hollowShape.parent)
|
||||
this.debugDisplayObject.addChild(this.hollowShape);
|
||||
|
||||
@@ -115,6 +115,29 @@ module es {
|
||||
this.hollowShape.graphics.lineStyle(Size.lineSizeMultiplier, Colors.colliderBounds);
|
||||
this.hollowShape.graphics.drawRect(this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height);
|
||||
this.hollowShape.graphics.endFill();
|
||||
|
||||
this.polygonShape.graphics.clear();
|
||||
if (poly.points.length >= 2){
|
||||
this.polygonShape.graphics.beginFill(Colors.colliderEdge, 0);
|
||||
this.polygonShape.graphics.lineStyle(Size.lineSizeMultiplier, Colors.colliderEdge);
|
||||
for (let i = 1; i < poly.points.length; i ++)
|
||||
this.polygonShape.graphics.lineTo(poly.position.x + poly.points[i].x, poly.position.y + poly.points[i].y);
|
||||
this.polygonShape.graphics.lineTo(poly.position.x + poly.points[poly.points.length - 1].x, poly.position.y + poly.points[0].y);
|
||||
this.polygonShape.graphics.endFill();
|
||||
}
|
||||
|
||||
this.pixelShape1.graphics.clear();
|
||||
this.pixelShape1.graphics.beginFill(Colors.colliderPosition, 0);
|
||||
this.pixelShape1.graphics.lineStyle(4 * Size.lineSizeMultiplier, Colors.colliderPosition);
|
||||
this.pixelShape1.graphics.lineTo(this.entity.transform.position.x, this.entity.transform.position.y);
|
||||
this.pixelShape1.graphics.endFill();
|
||||
|
||||
this.pixelShape2.graphics.clear();
|
||||
this.pixelShape2.graphics.beginFill(Colors.colliderCenter, 0);
|
||||
this.pixelShape2.graphics.lineStyle(2 * Size.lineSizeMultiplier, Colors.colliderCenter);
|
||||
this.pixelShape2.graphics.lineTo(this.entity.transform.position.x + this.shape.center.x,
|
||||
this.entity.transform.position.y + this.shape.center.y);
|
||||
this.pixelShape2.graphics.endFill();
|
||||
}
|
||||
|
||||
public toString() {
|
||||
|
||||
@@ -35,9 +35,9 @@ module es {
|
||||
* 值将自动从本地和父矩阵重新计算。
|
||||
*/
|
||||
public _worldTransform = Matrix2D.create().identity();
|
||||
public _rotationMatrix: Matrix2D = Matrix2D.create();
|
||||
public _translationMatrix: Matrix2D = Matrix2D.create();
|
||||
public _scaleMatrix: Matrix2D = Matrix2D.create();
|
||||
public _rotationMatrix: Matrix2D = Matrix2D.create().identity();
|
||||
public _translationMatrix: Matrix2D = Matrix2D.create().identity();
|
||||
public _scaleMatrix: Matrix2D = Matrix2D.create().identity();
|
||||
public _children: Transform[];
|
||||
|
||||
constructor(entity: Entity) {
|
||||
|
||||
@@ -81,13 +81,13 @@ module es {
|
||||
this.top < value.bottom;
|
||||
}
|
||||
|
||||
public rayIntersects(ray: Ray2D): number{
|
||||
let distance = 0;
|
||||
public rayIntersects(ray: Ray2D, distance: Ref<number>): boolean{
|
||||
distance.value = 0;
|
||||
let maxValue = Number.MAX_VALUE;
|
||||
|
||||
if (Math.abs(ray.direction.x) < 1E-06){
|
||||
if ((ray.start.x < this.x) || (ray.start.x > this.x + this.width))
|
||||
return distance;
|
||||
return false;
|
||||
}else{
|
||||
let num11 = 1 / ray.direction.x;
|
||||
let num8 = (this.x - ray.start.x) * num11;
|
||||
@@ -98,15 +98,15 @@ module es {
|
||||
num7 = num14;
|
||||
}
|
||||
|
||||
distance = Math.max(num8, distance);
|
||||
distance.value = Math.max(num8, distance.value);
|
||||
maxValue = Math.min(num7, maxValue);
|
||||
if (distance > maxValue)
|
||||
return distance;
|
||||
if (distance.value > maxValue)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Math.abs(ray.direction.y) < 1E-06){
|
||||
if ((ray.start.y < this.y) || (ray.start.y > this.y + this.height))
|
||||
return distance;
|
||||
return false;
|
||||
}else{
|
||||
let num10 = 1 / ray.direction.y;
|
||||
let num6 = (this.y - ray.start.y) * num10;
|
||||
@@ -117,13 +117,13 @@ module es {
|
||||
num5 = num13;
|
||||
}
|
||||
|
||||
distance = Math.max(num6, distance);
|
||||
distance.value = Math.max(num6, distance.value);
|
||||
maxValue = Math.max(num5, maxValue);
|
||||
if (distance > maxValue)
|
||||
return distance;
|
||||
if (distance.value > maxValue)
|
||||
return false;
|
||||
}
|
||||
|
||||
return distance;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -223,7 +223,6 @@ module es {
|
||||
let val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y));
|
||||
this.x *= val;
|
||||
this.y *= val;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** 返回它的长度 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -355,7 +355,7 @@ module es {
|
||||
* @param cell
|
||||
*/
|
||||
public checkRayIntersection(cellX: number, cellY: number, cell: Collider[]): boolean {
|
||||
let fraction: number = 0;
|
||||
let fraction: Ref<number> = new Ref(0);
|
||||
for (let i = 0; i < cell.length; i++) {
|
||||
let potential = cell[i];
|
||||
|
||||
@@ -376,8 +376,7 @@ module es {
|
||||
// TODO: 如果边界检查返回更多数据,我们就不需要为BoxCollider检查做任何事情
|
||||
// 在做形状测试之前先做一个边界检查
|
||||
let colliderBounds = potential.bounds;
|
||||
let fraction = colliderBounds.rayIntersects(this._ray);
|
||||
if (fraction <= 1) {
|
||||
if (colliderBounds.rayIntersects(this._ray, fraction) && fraction.value <= 1){
|
||||
if (potential.shape.collidesWithLine(this._ray.start, this._ray.end, this._tempHit)) {
|
||||
// 检查一下,我们应该排除这些射线,射线cast是否在碰撞器中开始
|
||||
if (!Physics.raycastsStartInColliders && potential.shape.containsPoint(this._ray.start))
|
||||
|
||||
9
source/src/Utils/Ref.ts
Normal file
9
source/src/Utils/Ref.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
module es {
|
||||
export class Ref<T> {
|
||||
public value: T;
|
||||
|
||||
constructor(value: T){
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user