fix: visibleBoundingBox optimizations
This commit is contained in:
parent
1b35fc4215
commit
570054c610
|
@ -31,8 +31,7 @@ export class Listed extends Trait {
|
|||
if (!list) {
|
||||
return;
|
||||
}
|
||||
const quadTree = list.quadTree;
|
||||
if (!('visibleBoundingBox' in this.entity)) {
|
||||
if (!this.entity.is('visible')) {
|
||||
return;
|
||||
}
|
||||
const aabb = this.entity.visibleBoundingBox;
|
||||
|
@ -45,6 +44,7 @@ export class Listed extends Trait {
|
|||
const points = Rectangle.toPoints(expandedAabb);
|
||||
this.quadTreeNodes = points.map((point) => [...point, this.entity]);
|
||||
// Add points to quad tree.
|
||||
const quadTree = list.quadTree;
|
||||
for (const node of this.quadTreeNodes) {
|
||||
quadTree.add(node);
|
||||
}
|
||||
|
@ -84,11 +84,7 @@ export class Listed extends Trait {
|
|||
listeners() {
|
||||
return {
|
||||
|
||||
visibleBoundingBoxesUpdated: () => {
|
||||
this.resetQuadTreeNodes();
|
||||
},
|
||||
|
||||
positionChanged: () => {
|
||||
visibleBoundingBoxChanged: () => {
|
||||
this.resetQuadTreeNodes();
|
||||
},
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ const decorate = compose(
|
|||
}),
|
||||
);
|
||||
|
||||
class PicturedBase extends Trait {
|
||||
export class Pictured extends decorate(Trait) {
|
||||
|
||||
static defaultParams() {
|
||||
return {
|
||||
|
@ -28,8 +28,6 @@ class PicturedBase extends Trait {
|
|||
initialize() {
|
||||
this._images = this.params.get('images').toJS();
|
||||
this.sprites = undefined;
|
||||
// Bounding box update.
|
||||
this.entity.emit('visibleBoundingBoxesUpdated');
|
||||
}
|
||||
|
||||
destroy() {
|
||||
|
@ -61,10 +59,11 @@ class PicturedBase extends Trait {
|
|||
return;
|
||||
}
|
||||
// Load all images.
|
||||
const imagePromises = [];
|
||||
this.sprites = {};
|
||||
for (const key in this._images) {
|
||||
const {uri} = this._images[key];
|
||||
Image.load(uri).then((image) => {
|
||||
const imagePromise = Image.load(uri).then((image) => {
|
||||
const sprite = this.sprites[key] = new Sprite(image);
|
||||
// Calculate any offset.
|
||||
sprite.position = this.viewPositionFor(key);
|
||||
|
@ -74,7 +73,12 @@ class PicturedBase extends Trait {
|
|||
this.showImage(key);
|
||||
}
|
||||
});
|
||||
imagePromises.push(imagePromise);
|
||||
}
|
||||
Promise.all(imagePromises).then((images) => {
|
||||
// Bounding box update.
|
||||
this.entity.updateVisibleBoundingBox();
|
||||
});
|
||||
}
|
||||
|
||||
offsetFor(key) {
|
||||
|
@ -133,7 +137,7 @@ class PicturedBase extends Trait {
|
|||
return {
|
||||
currentImageChanged: (oldKey) => {
|
||||
// Bounding box update.
|
||||
this.entity.emit('visibleBoundingBoxesUpdated');
|
||||
this.entity.updateVisibleBoundingBox();
|
||||
// Only client/graphics.
|
||||
if (!this.sprites) {
|
||||
return;
|
||||
|
@ -155,5 +159,3 @@ class PicturedBase extends Trait {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
export class Pictured extends decorate(PicturedBase) {}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {compose} from '@avocado/core';
|
||||
import {StateProperty, Trait} from '@avocado/entity';
|
||||
import {Rectangle, Vector} from '@avocado/math';
|
||||
import {Property} from '@avocado/mixins';
|
||||
|
||||
import {Container} from '../container';
|
||||
import {hasGraphics} from '../has-graphics';
|
||||
|
@ -9,6 +10,13 @@ const decorate = compose(
|
|||
StateProperty('isVisible', {
|
||||
track: true,
|
||||
}),
|
||||
Property('visibleBoundingBox', {
|
||||
default: [0, 0, 0, 0],
|
||||
emit: function (...args) {
|
||||
this.entity.emit(...args);
|
||||
},
|
||||
track: true,
|
||||
})
|
||||
);
|
||||
|
||||
export class Visible extends decorate(Trait) {
|
||||
|
@ -30,8 +38,8 @@ export class Visible extends decorate(Trait) {
|
|||
this._container = new Container();
|
||||
this._container.isVisible = this.entity.isVisible;
|
||||
}
|
||||
this.scheduledBoundingBoxUpdate = true;
|
||||
this.trackPosition = this.params.get('trackPosition');
|
||||
this._visibleBoundingBox = [0, 0, 0, 0];
|
||||
}
|
||||
|
||||
destroy() {
|
||||
|
@ -44,27 +52,6 @@ export class Visible extends decorate(Trait) {
|
|||
return this._container;
|
||||
}
|
||||
|
||||
get visibleBoundingBox() {
|
||||
if (Rectangle.isNull(this._visibleBoundingBox)) {
|
||||
// Collect all bounding boxes.
|
||||
const visibleBoundingBoxes = this.entity.invokeHookFlat(
|
||||
'visibleBoundingBoxes'
|
||||
);
|
||||
if (0 === visibleBoundingBoxes.length) {
|
||||
return [0, 0, 0, 0];
|
||||
}
|
||||
let unifiedBoundingBox = [0, 0, 0, 0];
|
||||
for (const visibleBoundingBox of visibleBoundingBoxes) {
|
||||
unifiedBoundingBox = Rectangle.united(
|
||||
unifiedBoundingBox,
|
||||
visibleBoundingBox,
|
||||
);
|
||||
}
|
||||
this._visibleBoundingBox = unifiedBoundingBox;
|
||||
}
|
||||
return this._visibleBoundingBox;
|
||||
}
|
||||
|
||||
shouldSynchronizePosition() {
|
||||
return this._container && this.trackPosition;
|
||||
}
|
||||
|
@ -84,9 +71,9 @@ export class Visible extends decorate(Trait) {
|
|||
this.entity.container.visible = this.entity.isVisible;
|
||||
},
|
||||
|
||||
visibleBoundingBoxesUpdated: () => {
|
||||
this._visibleBoundingBox = [0, 0, 0, 0];
|
||||
}
|
||||
positionChanged: () => {
|
||||
this.scheduledBoundingBoxUpdate = true;
|
||||
},
|
||||
|
||||
};
|
||||
if (this.shouldSynchronizePosition()) {
|
||||
|
@ -103,10 +90,40 @@ export class Visible extends decorate(Trait) {
|
|||
return listeners;
|
||||
}
|
||||
|
||||
methods() {
|
||||
return {
|
||||
|
||||
updateVisibleBoundingBox: () => {
|
||||
this.scheduledBoundingBoxUpdate = true;
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
tick(elapsed) {
|
||||
if (this.shouldSynchronizePosition()) {
|
||||
this.synchronizePosition();
|
||||
}
|
||||
if (this.scheduledBoundingBoxUpdate) {
|
||||
// Collect all bounding boxes.
|
||||
const visibleBoundingBoxes = this.entity.invokeHookFlat(
|
||||
'visibleBoundingBoxes'
|
||||
);
|
||||
if (0 === visibleBoundingBoxes.length) {
|
||||
this.visibleBoundingBox = [0, 0, 0, 0];
|
||||
}
|
||||
else {
|
||||
let unifiedBoundingBox = [0, 0, 0, 0];
|
||||
for (const visibleBoundingBox of visibleBoundingBoxes) {
|
||||
unifiedBoundingBox = Rectangle.united(
|
||||
unifiedBoundingBox,
|
||||
visibleBoundingBox,
|
||||
);
|
||||
}
|
||||
this.visibleBoundingBox = unifiedBoundingBox;
|
||||
this.scheduledBoundingBoxUpdate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ class AnimatedBase extends Trait {
|
|||
animation.direction = this.entity.direction;
|
||||
});
|
||||
// Bounding box update.
|
||||
this.entity.emit('visibleBoundingBoxesUpdated');
|
||||
this.entity.updateVisibleBoundingBox();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -167,7 +167,7 @@ class AnimatedBase extends Trait {
|
|||
oldAnimation.reset();
|
||||
}
|
||||
// Bounding box update.
|
||||
this.entity.emit('visibleBoundingBoxesUpdated');
|
||||
this.entity.updateVisibleBoundingBox();
|
||||
// Only client/graphics.
|
||||
if (!this.animationViews) {
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue
Block a user