性能优化

This commit is contained in:
YHH
2022-03-07 16:00:48 +08:00
parent 3f7ef284fc
commit e207952786
9 changed files with 366 additions and 393 deletions

View File

@@ -157,29 +157,33 @@ module es {
// 捞取我们在新的位置上可能会碰撞到的任何东西
let neighbors = Physics.boxcastBroadphaseExcludingSelf(this._collider, this._collider.bounds, this._collider.collidesWithLayers.value);
for (const neighbor of neighbors) {
if (!neighbor)
continue;
// 如果邻近的对撞机是同一个实体,则忽略它
if (neighbor.entity.equals(this.entity)) {
continue;
}
if (this._collider.collidesWithNonMotion(neighbor, collisionResult)) {
// 如果附近有一个ArcadeRigidbody我们就会处理完整的碰撞响应。如果没有我们会根据附近是不可移动的来计算事情
let neighborRigidbody = neighbor.entity.getComponent(ArcadeRigidbody);
if (neighborRigidbody != null) {
this.processOverlap(neighborRigidbody, collisionResult.minimumTranslationVector);
this.processCollision(neighborRigidbody, collisionResult.minimumTranslationVector);
} else {
// 没有ArcadeRigidbody所以我们假设它是不动的只移动我们自己的
this.entity.position = this.entity.position.sub(collisionResult.minimumTranslationVector);
const relativeVelocity = this.calculateResponseVelocity(this.velocity, collisionResult.minimumTranslationVector);
this.velocity.addEqual(relativeVelocity);
if (neighbors.length > 0) {
for (let i = 0; i < neighbors.length; i ++) {
const neighbor = neighbors[i];
if (!neighbor)
continue;
// 如果邻近的对撞机是同一个实体,则忽略它
if (neighbor.entity.equals(this.entity)) {
continue;
}
if (this._collider.collidesWithNonMotion(neighbor, collisionResult)) {
// 如果附近有一个ArcadeRigidbody我们就会处理完整的碰撞响应。如果没有我们会根据附近是不可移动的来计算事情
let neighborRigidbody = neighbor.entity.getComponent(ArcadeRigidbody);
if (neighborRigidbody != null) {
this.processOverlap(neighborRigidbody, collisionResult.minimumTranslationVector);
this.processCollision(neighborRigidbody, collisionResult.minimumTranslationVector);
} else {
// 没有ArcadeRigidbody所以我们假设它是不动的只移动我们自己的
this.entity.position = this.entity.position.sub(collisionResult.minimumTranslationVector);
const relativeVelocity = this.calculateResponseVelocity(this.velocity, collisionResult.minimumTranslationVector);
this.velocity.addEqual(relativeVelocity);
}
}
}
}
}
/**

View File

@@ -228,23 +228,26 @@ module es {
let neighbors = Physics.boxcastBroadphaseExcludingSelf(this, colliderBounds, this.collidesWithLayers.value);
// 更改形状位置,使其处于移动后的位置,以便我们检查是否有重叠
let oldPosition = this.shape.position.clone();
let oldPosition = this.shape.position;
this.shape.position = Vector2.add(this.shape.position, motion);
let didCollide = false;
for (let neighbor of neighbors) {
if (neighbor.isTrigger)
continue;
if (this.collidesWithNonMotion(neighbor, result)) {
motion = motion.sub(result.minimumTranslationVector);
this.shape.position = this.shape.position.sub(result.minimumTranslationVector);
didCollide = true;
if (neighbors.length > 0) {
for (let i = 0; i < neighbors.length; i ++ ){
const neighbor = neighbors[i];
if (neighbor.isTrigger)
continue;
if (this.collidesWithNonMotion(neighbor, result)) {
motion = motion.sub(result.minimumTranslationVector);
this.shape.position = this.shape.position.sub(result.minimumTranslationVector);
didCollide = true;
}
}
}
// 将形状位置返回到检查之前的位置
this.shape.position = oldPosition.clone();
this.shape.position = oldPosition;
return didCollide;
}

View File

@@ -23,9 +23,12 @@ module es {
export class TriggerListenerHelper {
public static getITriggerListener(entity: Entity, components: ITriggerListener[]){
for (let component of entity.components._components) {
if (isITriggerListener(component)) {
components.push(component);
if (entity.components._components.length > 0) {
for (let i = 0; i < entity.components._components.length; i ++) {
const component = entity.components._components[i];
if (isITriggerListener(component)) {
components.push(component);
}
}
}

View File

@@ -20,58 +20,66 @@ module es {
*/
public calculateMovement(motion: Vector2, collisionResult: CollisionResult): boolean {
let collider = null;
for (let i = 0; i < this.entity.components.buffer.length; i++) {
let component = this.entity.components.buffer[i];
if (component instanceof Collider) {
collider = component;
break;
if (this.entity.components.buffer.length > 0)
for (let i = 0; i < this.entity.components.buffer.length; i++) {
let component = this.entity.components.buffer[i];
if (component instanceof Collider) {
collider = component;
break;
}
}
}
if (collider == null || this._triggerHelper == null) {
return false;
}
// 移动所有的非触发碰撞器并获得最近的碰撞
let colliders: Collider[] = [];
for (let i = 0; i < this.entity.components.buffer.length; i ++) {
let component = this.entity.components.buffer[i];
if (component instanceof Collider) {
colliders.push(component);
if (this.entity.components.buffer.length > 0)
for (let i = 0; i < this.entity.components.buffer.length; i ++) {
let component = this.entity.components.buffer[i];
if (component instanceof Collider) {
colliders.push(component);
}
}
}
for (let i = 0; i < colliders.length; i++) {
let collider = colliders[i];
// 不检测触发器 在我们移动后会重新访问它
if (collider.isTrigger)
continue;
// 获取我们在新位置可能发生碰撞的任何东西
let bounds = collider.bounds.clone();
bounds.x += motion.x;
bounds.y += motion.y;
let neighbors = Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers.value);
for (let neighbor of neighbors) {
// 不检测触发器
if (neighbor.isTrigger)
return;
let _internalcollisionResult: CollisionResult = new CollisionResult();
if (collider.collidesWith(neighbor, motion, _internalcollisionResult)) {
// 如果碰撞 则退回之前的移动量
motion.subEqual(_internalcollisionResult.minimumTranslationVector);
// 如果我们碰到多个对象,为了简单起见,只取第一个。
if (_internalcollisionResult.collider != null) {
collisionResult.collider = _internalcollisionResult.collider;
collisionResult.minimumTranslationVector = _internalcollisionResult.minimumTranslationVector;
collisionResult.normal = _internalcollisionResult.normal;
collisionResult.point = _internalcollisionResult.point;
if (colliders.length > 0) {
for (let i = 0; i < colliders.length; i++) {
let collider = colliders[i];
// 不检测触发器 在我们移动后会重新访问它
if (collider.isTrigger)
continue;
// 获取我们在新位置可能发生碰撞的任何东西
let bounds = collider.bounds;
bounds.x += motion.x;
bounds.y += motion.y;
let neighbors = Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers.value);
if (neighbors.length > 0) {
for (let i = 0; i < neighbors.length; i ++) {
const neighbor = neighbors[i];
// 不检测触发器
if (neighbor.isTrigger)
return;
let _internalcollisionResult: CollisionResult = new CollisionResult();
if (collider.collidesWith(neighbor, motion, _internalcollisionResult)) {
// 如果碰撞 则退回之前的移动量
motion.subEqual(_internalcollisionResult.minimumTranslationVector);
// 如果我们碰到多个对象,为了简单起见,只取第一个。
if (_internalcollisionResult.collider != null) {
collisionResult.collider = _internalcollisionResult.collider;
collisionResult.minimumTranslationVector = _internalcollisionResult.minimumTranslationVector;
collisionResult.normal = _internalcollisionResult.normal;
collisionResult.point = _internalcollisionResult.point;
}
}
}
}
}
}
ListPool.free(Collider, colliders);
return collisionResult.collider != null;

View File

@@ -23,38 +23,44 @@ module es {
// 对所有实体.colliders进行重叠检查这些实体.colliders是触发器与所有宽相碰撞器无论是否触发器。
// 任何重叠都会导致触发事件
let colliders: Collider[] = this.getColliders();
for (let i = 0; i < colliders.length; i++) {
let collider = colliders[i];
let neighbors = Physics.boxcastBroadphaseExcludingSelf(collider, collider.bounds, collider.collidesWithLayers.value);
for (let j = 0; j < neighbors.length; j++) {
let neighbor = neighbors[j];
// 我们至少需要一个碰撞器作为触发器
if (!collider.isTrigger && !neighbor.isTrigger)
continue;
if (collider.overlaps(neighbor)) {
const pair = new Pair<Collider>(collider, neighbor);
// 如果我们的某一个集合中已经有了这个对子(前一个或当前的触发交叉点),就不要调用输入事件了
const shouldReportTriggerEvent = !this._activeTriggerIntersections.has(pair) &&
!this._previousTriggerIntersections.has(pair);
if (shouldReportTriggerEvent) {
if (neighbor.castSortOrder >= Collider.lateSortOrder) {
lateColliders.push(pair);
} else {
this.notifyTriggerListeners(pair, true);
if (colliders.length > 0) {
for (let i = 0; i < colliders.length; i++) {
let collider = colliders[i];
let neighbors = Physics.boxcastBroadphaseExcludingSelf(collider, collider.bounds, collider.collidesWithLayers.value);
for (let j = 0; j < neighbors.length; j++) {
let neighbor = neighbors[j];
// 我们至少需要一个碰撞器作为触发器
if (!collider.isTrigger && !neighbor.isTrigger)
continue;
if (collider.overlaps(neighbor)) {
const pair = new Pair<Collider>(collider, neighbor);
// 如果我们的某一个集合中已经有了这个对子(前一个或当前的触发交叉点),就不要调用输入事件了
const shouldReportTriggerEvent = !this._activeTriggerIntersections.has(pair) &&
!this._previousTriggerIntersections.has(pair);
if (shouldReportTriggerEvent) {
if (neighbor.castSortOrder >= Collider.lateSortOrder) {
lateColliders.push(pair);
} else {
this.notifyTriggerListeners(pair, true);
}
}
}
this._activeTriggerIntersections.add(pair);
this._activeTriggerIntersections.add(pair);
}
}
}
}
for (const pair of lateColliders) {
this.notifyTriggerListeners(pair, true);
if (lateColliders.length > 0) {
for (let i = 0; i < lateColliders.length; i ++) {
const pair = lateColliders[i];
this.notifyTriggerListeners(pair, true);
}
}
this.checkForExitedColliders();
@@ -62,12 +68,13 @@ module es {
private getColliders() {
const colliders: Collider[] = [];
for (let i = 0; i < this._entity.components.buffer.length; i ++) {
const component = this._entity.components.buffer[i];
if (component instanceof Collider) {
colliders.push(component);
if (this._entity.components.buffer.length > 0)
for (let i = 0; i < this._entity.components.buffer.length; i ++) {
const component = this._entity.components.buffer[i];
if (component instanceof Collider) {
colliders.push(component);
}
}
}
return colliders;
}
@@ -91,28 +98,32 @@ module es {
private notifyTriggerListeners(collisionPair: Pair<Collider>, isEntering: boolean) {
TriggerListenerHelper.getITriggerListener(collisionPair.first.entity, this._tempTriggerList);
for (let i = 0; i < this._tempTriggerList.length; i++) {
if (isEntering) {
this._tempTriggerList[i].onTriggerEnter(collisionPair.second, collisionPair.first);
} else {
this._tempTriggerList[i].onTriggerExit(collisionPair.second, collisionPair.first);
}
this._tempTriggerList.length = 0;
if (collisionPair.second.entity) {
TriggerListenerHelper.getITriggerListener(collisionPair.second.entity, this._tempTriggerList);
for (let i = 0; i < this._tempTriggerList.length; i++) {
if (isEntering) {
this._tempTriggerList[i].onTriggerEnter(collisionPair.first, collisionPair.second);
} else {
this._tempTriggerList[i].onTriggerExit(collisionPair.first, collisionPair.second);
}
if (this._tempTriggerList.length > 0)
for (let i = 0; i < this._tempTriggerList.length; i++) {
const trigger = this._tempTriggerList[i];
if (isEntering) {
trigger.onTriggerEnter(collisionPair.second, collisionPair.first);
} else {
trigger.onTriggerExit(collisionPair.second, collisionPair.first);
}
this._tempTriggerList.length = 0;
if (collisionPair.second.entity) {
TriggerListenerHelper.getITriggerListener(collisionPair.second.entity, this._tempTriggerList);
if (this._tempTriggerList.length > 0)
for (let i = 0; i < this._tempTriggerList.length; i++) {
const trigger = this._tempTriggerList[i];
if (isEntering) {
trigger.onTriggerEnter(collisionPair.first, collisionPair.second);
} else {
trigger.onTriggerExit(collisionPair.first, collisionPair.second);
}
}
this._tempTriggerList.length = 0;
}
}
}
}
}
}

View File

@@ -113,15 +113,17 @@ module es {
continue;
// 当cell不为空。循环并取回所有碰撞器
for (let i = 0; i < cell.length; i++) {
const collider = cell[i];
// 如果它是自身或者如果它不匹配我们的层掩码 跳过这个碰撞器
if (collider == excludeCollider || !Flags.isFlagSet(layerMask, collider.physicsLayer.value))
continue;
if (bounds.intersects(collider.bounds)) {
this._tempHashSet.add(collider);
if (cell.length > 0) {
for (let i = 0; i < cell.length; i++) {
const collider = cell[i];
// 如果它是自身或者如果它不匹配我们的层掩码 跳过这个碰撞器
if (collider == excludeCollider || !Flags.isFlagSet(layerMask, collider.physicsLayer.value))
continue;
if (bounds.intersects(collider.bounds)) {
this._tempHashSet.add(collider);
}
}
}
}
@@ -215,7 +217,9 @@ module es {
let resultCounter = 0;
let potentials = this.aabbBroadphase(rect, null, layerMask);
for (let collider of potentials) {
for (let i = 0; i < potentials.length; i ++) {
const collider = potentials[i];
if (collider instanceof BoxCollider) {
results[resultCounter] = collider;
resultCounter++;
@@ -255,7 +259,8 @@ module es {
let resultCounter = 0;
const potentials = this.aabbBroadphase(bounds, null, layerMask);
for (let collider of potentials) {
for (let i = 0; i < potentials.length; i ++) {
const collider = potentials[i];
if (collider instanceof BoxCollider) {
if (collider.shape.overlaps(this._overlapTestCircle)) {
results[resultCounter] = collider;
@@ -324,9 +329,8 @@ module es {
*/
public remove(obj: T) {
this._store.forEach(list => {
let linqList = new es.List(list);
if (linqList.contains(obj))
linqList.remove(obj);
let index = list.indexOf(obj);
list.splice(index, 1);
})
}
@@ -383,7 +387,7 @@ module es {
const potential = cell[i];
// 管理我们已经处理过的碰撞器
if (new es.List(this._checkedColliders).contains(potential))
if (this._checkedColliders.indexOf(potential) != -1)
continue;
this._checkedColliders.push(potential);

View File

@@ -31,14 +31,20 @@ module es {
public union(other: PairSet<T>) {
const otherAll = other.all;
for (const elem of otherAll) {
this.add(elem);
}
if (otherAll.length > 0)
for (let i = 0; i < otherAll.length; i ++) {
const elem = otherAll[i];
this.add(elem);
}
}
public except(other: PairSet<T>) {
const otherAll = other.all;
for (const elem of otherAll) {
if (otherAll.length > 0)
for (let i = 0; i < otherAll.length; i ++) {
const elem = otherAll[i];
this.remove(elem);
}
}