feat(canvas): Create SpatialIndex as rbush wrapper for viewport culling and hit testing
This commit is contained in:
@@ -0,0 +1,60 @@
|
|||||||
|
import RBush from 'rbush';
|
||||||
|
|
||||||
|
type BBox = {
|
||||||
|
minX: number;
|
||||||
|
minY: number;
|
||||||
|
maxX: number;
|
||||||
|
maxY: number;
|
||||||
|
id?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type SpatialItem = {
|
||||||
|
id: string;
|
||||||
|
minX: number;
|
||||||
|
minY: number;
|
||||||
|
maxX: number;
|
||||||
|
maxY: number;
|
||||||
|
[key: string]: any; // Allow additional properties
|
||||||
|
};
|
||||||
|
|
||||||
|
export class SpatialIndex {
|
||||||
|
private rbush: RBush<SpatialItem>;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.rbush = new RBush<SpatialItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public insert(item: BBox & { id: string }): void {
|
||||||
|
this.rbush.insert(item as SpatialItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public remove(item: BBox & { id: string }): void {
|
||||||
|
// RBush requires the exact same object for removal
|
||||||
|
// In practice, you might need to search for the item first
|
||||||
|
this.rbush.remove(item as SpatialItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public search(bbox: BBox): SpatialItem[] {
|
||||||
|
return this.rbush.search(bbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
public load(items: (BBox & { id: string })[]): void {
|
||||||
|
this.rbush.load(items as SpatialItem[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public clear(): void {
|
||||||
|
this.rbush.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public all(): SpatialItem[] {
|
||||||
|
return this.rbush.all();
|
||||||
|
}
|
||||||
|
|
||||||
|
public toJSON(): any {
|
||||||
|
return this.rbush.toJSON();
|
||||||
|
}
|
||||||
|
|
||||||
|
public fromJSON(data: any): void {
|
||||||
|
this.rbush.fromJSON(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user