67 lines
1.8 KiB
TypeScript
67 lines
1.8 KiB
TypeScript
import type * as THREE from "three";
|
|
|
|
export interface ColonyStatsData {
|
|
foragerRatio: number; // fraction of ants currently carrying food
|
|
totalAnts: number; // total ant count
|
|
}
|
|
|
|
export default class ColonyStats {
|
|
private buffer: Float32Array;
|
|
private statsData: ColonyStatsData = {
|
|
foragerRatio: 0,
|
|
totalAnts: 0,
|
|
};
|
|
|
|
constructor() {
|
|
this.buffer = new Float32Array(0);
|
|
}
|
|
|
|
public update(
|
|
renderer: THREE.WebGLRenderer,
|
|
antTarget: THREE.WebGLRenderTarget,
|
|
): ColonyStatsData {
|
|
const width = antTarget.width;
|
|
const height = antTarget.height;
|
|
const pixelCount = width * height;
|
|
|
|
// resize buffer if needed
|
|
if (this.buffer.length !== pixelCount * 4) {
|
|
this.buffer = new Float32Array(pixelCount * 4);
|
|
}
|
|
|
|
renderer.readRenderTargetPixels(
|
|
antTarget,
|
|
0,
|
|
0,
|
|
width,
|
|
height,
|
|
this.buffer,
|
|
);
|
|
|
|
let carryingCount = 0;
|
|
let activeAnts = 0;
|
|
|
|
for (let i = 0; i < pixelCount; i++) {
|
|
const posX = this.buffer[i * 4];
|
|
const posY = this.buffer[i * 4 + 1];
|
|
const w = this.buffer[i * 4 + 3]; // alpha = packed state
|
|
|
|
// skip uninitialized ants (both coordinates at origin)
|
|
if (posX === 0 && posY === 0) continue;
|
|
|
|
activeAnts++;
|
|
const isCarrying = Math.trunc(w) & 1;
|
|
if (isCarrying) carryingCount++;
|
|
}
|
|
|
|
this.statsData.totalAnts = activeAnts;
|
|
this.statsData.foragerRatio =
|
|
activeAnts > 0 ? carryingCount / activeAnts : 0;
|
|
|
|
return this.statsData;
|
|
}
|
|
|
|
public get data(): ColonyStatsData {
|
|
return this.statsData;
|
|
}
|
|
}
|