mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Avoid extra mapping of searched items.
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
namespace gdjs {
|
||||
declare var rbush: any;
|
||||
|
||||
export class LightObstaclesManager {
|
||||
_obstacleRBush: any;
|
||||
_obstacleRBush: RBush<LightObstacleRuntimeBehavior>;
|
||||
|
||||
constructor(instanceContainer: gdjs.RuntimeInstanceContainer) {
|
||||
this._obstacleRBush = new rbush();
|
||||
this._obstacleRBush = new RBush<LightObstacleRuntimeBehavior>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,6 +39,9 @@ namespace gdjs {
|
||||
* added before.
|
||||
*/
|
||||
removeObstacle(obstacle: gdjs.LightObstacleRuntimeBehavior) {
|
||||
if (!obstacle.currentRBushAABB) {
|
||||
return;
|
||||
}
|
||||
this._obstacleRBush.remove(obstacle.currentRBushAABB);
|
||||
}
|
||||
|
||||
@@ -59,9 +60,9 @@ namespace gdjs {
|
||||
// is not necessarily in the middle of the object (for sprites for example).
|
||||
const x = object.getX();
|
||||
const y = object.getY();
|
||||
const searchArea = gdjs.staticObject(
|
||||
const searchArea: SearchArea = gdjs.staticObject(
|
||||
LightObstaclesManager.prototype.getAllObstaclesAround
|
||||
);
|
||||
) as SearchArea;
|
||||
// @ts-ignore
|
||||
searchArea.minX = x - radius;
|
||||
// @ts-ignore
|
||||
@@ -70,13 +71,8 @@ namespace gdjs {
|
||||
searchArea.maxX = x + radius;
|
||||
// @ts-ignore
|
||||
searchArea.maxY = y + radius;
|
||||
const nearbyObstacles: gdjs.BehaviorRBushAABB<
|
||||
gdjs.LightObstacleRuntimeBehavior
|
||||
>[] = this._obstacleRBush.search(searchArea);
|
||||
result.length = 0;
|
||||
nearbyObstacles.forEach((nearbyObstacle) =>
|
||||
result.push(nearbyObstacle.behavior)
|
||||
);
|
||||
this._obstacleRBush.search(searchArea, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -7,7 +7,6 @@ namespace gdjs {
|
||||
export interface RuntimeInstanceContainer {
|
||||
pathfindingObstaclesManager: gdjs.PathfindingObstaclesManager;
|
||||
}
|
||||
declare var rbush: any;
|
||||
|
||||
/**
|
||||
* PathfindingObstaclesManager manages the common objects shared by objects
|
||||
@@ -18,10 +17,10 @@ namespace gdjs {
|
||||
* `gdjs.PathfindingRuntimeBehavior.obstaclesManagers`).
|
||||
*/
|
||||
export class PathfindingObstaclesManager {
|
||||
_obstaclesRBush: any;
|
||||
_obstaclesRBush: RBush<PathfindingObstacleRuntimeBehavior>;
|
||||
|
||||
constructor(instanceContainer: gdjs.RuntimeInstanceContainer) {
|
||||
this._obstaclesRBush = new rbush();
|
||||
this._obstaclesRBush = new RBush<PathfindingObstacleRuntimeBehavior>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,6 +59,9 @@ namespace gdjs {
|
||||
removeObstacle(
|
||||
pathfindingObstacleBehavior: PathfindingObstacleRuntimeBehavior
|
||||
) {
|
||||
if (!pathfindingObstacleBehavior.currentRBushAABB) {
|
||||
return;
|
||||
}
|
||||
this._obstaclesRBush.remove(pathfindingObstacleBehavior.currentRBushAABB);
|
||||
}
|
||||
|
||||
@@ -74,9 +76,9 @@ namespace gdjs {
|
||||
radius: float,
|
||||
result: gdjs.PathfindingObstacleRuntimeBehavior[]
|
||||
): void {
|
||||
const searchArea = gdjs.staticObject(
|
||||
const searchArea: SearchArea = gdjs.staticObject(
|
||||
PathfindingObstaclesManager.prototype.getAllObstaclesAround
|
||||
);
|
||||
) as SearchArea;
|
||||
// @ts-ignore
|
||||
searchArea.minX = x - radius;
|
||||
// @ts-ignore
|
||||
@@ -85,13 +87,8 @@ namespace gdjs {
|
||||
searchArea.maxX = x + radius;
|
||||
// @ts-ignore
|
||||
searchArea.maxY = y + radius;
|
||||
const nearbyObstacles: gdjs.BehaviorRBushAABB<
|
||||
gdjs.PathfindingObstacleRuntimeBehavior
|
||||
>[] = this._obstaclesRBush.search(searchArea);
|
||||
result.length = 0;
|
||||
nearbyObstacles.forEach((nearbyObstacle) =>
|
||||
result.push(nearbyObstacle.behavior)
|
||||
);
|
||||
this._obstaclesRBush.search(searchArea, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -3,7 +3,6 @@ GDevelop - Platform Behavior Extension
|
||||
Copyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
*/
|
||||
namespace gdjs {
|
||||
declare var rbush: any;
|
||||
type SearchArea = { minX: float; minY: float; maxX: float; maxY: float };
|
||||
|
||||
/**
|
||||
@@ -13,11 +12,11 @@ namespace gdjs {
|
||||
* of their associated container (see PlatformRuntimeBehavior.getManager).
|
||||
*/
|
||||
export class PlatformObjectsManager {
|
||||
private _platformRBush: any;
|
||||
private _platformRBush: RBush<PlatformRuntimeBehavior>;
|
||||
private movedPlatforms: Array<gdjs.PlatformRuntimeBehavior>;
|
||||
|
||||
constructor(instanceContainer: gdjs.RuntimeInstanceContainer) {
|
||||
this._platformRBush = new rbush();
|
||||
this._platformRBush = new RBush<PlatformRuntimeBehavior>();
|
||||
this.movedPlatforms = [];
|
||||
gdjs.registerRuntimeScenePreEventsCallback(() => this.doStepPreEvents());
|
||||
}
|
||||
@@ -30,8 +29,9 @@ namespace gdjs {
|
||||
if (!instanceContainer.platformsObjectsManager) {
|
||||
//Create the shared manager if necessary.
|
||||
// @ts-ignore
|
||||
instanceContainer.platformsObjectsManager =
|
||||
new gdjs.PlatformObjectsManager(instanceContainer);
|
||||
instanceContainer.platformsObjectsManager = new gdjs.PlatformObjectsManager(
|
||||
instanceContainer
|
||||
);
|
||||
}
|
||||
// @ts-ignore
|
||||
return instanceContainer.platformsObjectsManager;
|
||||
@@ -55,6 +55,9 @@ namespace gdjs {
|
||||
* added before.
|
||||
*/
|
||||
removePlatform(platformBehavior: gdjs.PlatformRuntimeBehavior) {
|
||||
if (!platformBehavior.currentRBushAABB) {
|
||||
return;
|
||||
}
|
||||
this._platformRBush.remove(platformBehavior.currentRBushAABB);
|
||||
}
|
||||
|
||||
@@ -93,24 +96,19 @@ namespace gdjs {
|
||||
const searchArea: SearchArea = gdjs.staticObject(
|
||||
PlatformObjectsManager.prototype.getAllPlatformsAround
|
||||
) as SearchArea;
|
||||
const nearbyPlatforms: Array<BehaviorRBushAABB<PlatformRuntimeBehavior>> =
|
||||
gdjs.staticArray(
|
||||
PlatformObjectsManager.prototype.getAllPlatformsAround
|
||||
);
|
||||
nearbyPlatforms.length = 0;
|
||||
result.length = 0;
|
||||
searchArea.minX = x - ow / 2 - maxMovementLength;
|
||||
searchArea.minY = y - oh / 2 - maxMovementLength;
|
||||
searchArea.maxX = x + ow / 2 + maxMovementLength;
|
||||
searchArea.maxY = y + oh / 2 + maxMovementLength;
|
||||
this._platformRBush.search(searchArea, nearbyPlatforms);
|
||||
|
||||
result.length = 0;
|
||||
this._platformRBush.search(searchArea, result);
|
||||
|
||||
// Extra check on the platform owner AABB
|
||||
// TODO: PR https://github.com/4ian/GDevelop/pull/2602 should remove the need
|
||||
// for this extra check once merged.
|
||||
for (let i = 0; i < nearbyPlatforms.length; i++) {
|
||||
const platform = nearbyPlatforms[i].behavior;
|
||||
let writtenIndex = 0;
|
||||
for (let readIndex = 0; readIndex < result.length; readIndex++) {
|
||||
const platform = result[readIndex];
|
||||
const platformAABB = platform.owner.getAABB();
|
||||
const platformIsStillAround =
|
||||
platformAABB.min[0] <= searchArea.maxX &&
|
||||
@@ -121,10 +119,11 @@ namespace gdjs {
|
||||
// This can happen because platforms are not updated in the RBush before that
|
||||
// characters movement are being processed.
|
||||
if (platformIsStillAround) {
|
||||
result.push(platform);
|
||||
result[writtenIndex] = platform;
|
||||
writtenIndex++;
|
||||
}
|
||||
}
|
||||
nearbyPlatforms.length = 0;
|
||||
result.length = writtenIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,8 +143,9 @@ namespace gdjs {
|
||||
_oldWidth: float = 0;
|
||||
_oldHeight: float = 0;
|
||||
_oldAngle: float = 0;
|
||||
currentRBushAABB: gdjs.BehaviorRBushAABB<PlatformRuntimeBehavior> | null =
|
||||
null;
|
||||
currentRBushAABB: gdjs.BehaviorRBushAABB<
|
||||
PlatformRuntimeBehavior
|
||||
> | null = null;
|
||||
_manager: gdjs.PlatformObjectsManager;
|
||||
_registeredInManager: boolean = false;
|
||||
_isAABBInvalidated = false;
|
||||
|
@@ -1,22 +1,19 @@
|
||||
namespace gdjs {
|
||||
declare var rbush: any;
|
||||
type SearchArea = { minX: float; minY: float; maxX: float; maxY: float };
|
||||
|
||||
// TODO Do something like BehaviorRBushAABB
|
||||
// TODO Allow to use getVisibilityAABB or getAABB
|
||||
export class ObjectManager {
|
||||
private _allInstances: Array<RuntimeObject> = [];
|
||||
private _awakeInstances: Array<RuntimeObject> = [];
|
||||
private _rbush: any;
|
||||
private _rbush: RBush<RuntimeObject>;
|
||||
|
||||
constructor() {
|
||||
this._rbush = new rbush();
|
||||
this._rbush = new RBush<RuntimeObject>();
|
||||
}
|
||||
|
||||
_destroy(): void {
|
||||
this._allInstances = [];
|
||||
this._awakeInstances = [];
|
||||
this._rbush = null;
|
||||
this._rbush.clear();
|
||||
}
|
||||
|
||||
search(
|
||||
@@ -35,7 +32,7 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
private _onWakingUp(object: RuntimeObject): void {
|
||||
this._rbush.remove(object);
|
||||
this._rbush.remove(object._rtreeAABB);
|
||||
this._awakeInstances.push(object);
|
||||
}
|
||||
|
||||
@@ -45,11 +42,11 @@ namespace gdjs {
|
||||
(object: RuntimeObject) => object.getSpatialSearchSleepState(),
|
||||
(object: RuntimeObject) => {
|
||||
const objectAABB = object.getAABB();
|
||||
object.minX = objectAABB.min[0];
|
||||
object.minY = objectAABB.min[1];
|
||||
object.maxX = objectAABB.max[0];
|
||||
object.maxY = objectAABB.max[1];
|
||||
this._rbush.insert(object);
|
||||
object._rtreeAABB.minX = objectAABB.min[0];
|
||||
object._rtreeAABB.minY = objectAABB.min[1];
|
||||
object._rtreeAABB.maxX = objectAABB.max[0];
|
||||
object._rtreeAABB.maxY = objectAABB.max[1];
|
||||
this._rbush.insert(object._rtreeAABB);
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -98,7 +95,7 @@ namespace gdjs {
|
||||
}
|
||||
}
|
||||
if (!isAwake) {
|
||||
this._rbush.remove(object);
|
||||
this._rbush.remove(object._rtreeAABB);
|
||||
}
|
||||
return isObjectDeleted;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -16,18 +16,18 @@ namespace gdjs {
|
||||
minY: float = 0;
|
||||
maxX: float = 0;
|
||||
maxY: float = 0;
|
||||
behavior: T;
|
||||
source: T;
|
||||
|
||||
constructor(behavior: T) {
|
||||
this.behavior = behavior;
|
||||
this.source = behavior;
|
||||
this.updateAABBFromOwner();
|
||||
}
|
||||
|
||||
updateAABBFromOwner() {
|
||||
this.minX = this.behavior.owner.getAABB().min[0];
|
||||
this.minY = this.behavior.owner.getAABB().min[1];
|
||||
this.maxX = this.behavior.owner.getAABB().max[0];
|
||||
this.maxY = this.behavior.owner.getAABB().max[1];
|
||||
this.minX = this.source.owner.getAABB().min[0];
|
||||
this.minY = this.source.owner.getAABB().min[1];
|
||||
this.maxX = this.source.owner.getAABB().max[0];
|
||||
this.maxY = this.source.owner.getAABB().max[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -195,12 +195,7 @@ namespace gdjs {
|
||||
protected hitBoxesDirty: boolean = true;
|
||||
// TODO use a different AABB for collision mask and rendered image.
|
||||
protected aabb: AABB = { min: [0, 0], max: [0, 0] };
|
||||
|
||||
// TODO
|
||||
minX = 0;
|
||||
minY = 0;
|
||||
maxX = 0;
|
||||
maxY = 0;
|
||||
_rtreeAABB: SearchedItem<RuntimeObject>;
|
||||
|
||||
protected _isIncludedInParentCollisionMask = true;
|
||||
|
||||
@@ -261,6 +256,13 @@ namespace gdjs {
|
||||
this._lifecycleSleepState = new gdjs.ObjectSleepState(this, () =>
|
||||
this.isNeedingLifecycleFunctions()
|
||||
);
|
||||
this._rtreeAABB = {
|
||||
source: this,
|
||||
minX: 0,
|
||||
minY: 0,
|
||||
maxX: 0,
|
||||
maxY: 0,
|
||||
};
|
||||
this._spatialSearchSleepState = new gdjs.ObjectSleepState(
|
||||
this,
|
||||
() => false
|
||||
|
19
GDJS/Runtime/types/rbush.d.ts
vendored
Normal file
19
GDJS/Runtime/types/rbush.d.ts
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
type SearchArea = { minX: float; minY: float; maxX: float; maxY: float };
|
||||
type SearchedItem<T> = {
|
||||
source: T;
|
||||
minX: float;
|
||||
minY: float;
|
||||
maxX: float;
|
||||
maxY: float;
|
||||
};
|
||||
|
||||
declare class RBush<T> {
|
||||
constructor(maxEntries?: number);
|
||||
search(bbox: SearchArea, result?: Array<T>): Array<T>;
|
||||
insert(item: SearchedItem<T>): RBush<T>;
|
||||
clear(): RBush<T>;
|
||||
remove(
|
||||
item: SearchedItem<T>,
|
||||
equalsFn?: (item: SearchedItem<T>, otherItem: SearchedItem<T>) => boolean
|
||||
): RBush<T>;
|
||||
}
|
Reference in New Issue
Block a user