ants/src/ColonyStats.ts

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;
}
}