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