Extend draw tools to support material palette

Replace bit-flag draw modes with direct material ID painting. draw.frag
now writes the material ID float directly instead of toggling individual
cell flag bits. ScreenScene drops the PointerState enum in favor of
numeric material IDs from constants.ts, and adds Digit1/Digit2 bindings
for sand and dirt.
This commit is contained in:
Jared Miller 2026-03-11 13:52:03 -04:00
parent e6af97f402
commit 29e5dbeb06
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C
3 changed files with 29 additions and 33 deletions

View file

@ -18,7 +18,7 @@ export default class DrawScene extends AbstractScene {
uniforms: {
tWorld: { value: null },
pointerPosition: { value: new THREE.Vector2() },
drawMode: { value: 0 },
drawMode: { value: -1 },
brushRadius: { value: 0 },
},
vertexShader,

View file

@ -1,5 +1,13 @@
import * as THREE from "three";
import Config from "../Config";
import {
MAT_AIR,
MAT_DIRT,
MAT_FOOD,
MAT_HOME,
MAT_ROCK,
MAT_SAND,
} from "../constants";
import type Renderer from "../Renderer";
import fragmentShaderAnts from "../shaders/ants.frag";
import vertexShaderAnts from "../shaders/ants.vert";
@ -7,21 +15,13 @@ import fragmentShaderGround from "../shaders/screenWorld.frag";
import vertexShaderGround from "../shaders/screenWorld.vert";
import AbstractScene from "./AbstractScene";
enum PointerState {
None,
Food,
Home,
Obstacle,
Erase,
}
export default class ScreenScene extends AbstractScene {
public readonly camera: THREE.OrthographicCamera;
public readonly material: THREE.ShaderMaterial;
public ants!: THREE.InstancedMesh;
public readonly groundMaterial: THREE.ShaderMaterial;
public readonly pointerPosition: THREE.Vector2 = new THREE.Vector2();
public drawMode: PointerState = PointerState.None;
public drawMode: number = -1;
// zoom stored in Config.cameraZoom
private isPointerDown: boolean = false;
public renderWidth: number = 1;
@ -148,26 +148,34 @@ export default class ScreenScene extends AbstractScene {
window.addEventListener("keydown", (e) => {
switch (e.code) {
case "KeyQ": {
this.drawMode = PointerState.Home;
this.drawMode = MAT_HOME;
break;
}
case "KeyW": {
this.drawMode = PointerState.Food;
this.drawMode = MAT_FOOD;
break;
}
case "KeyE": {
this.drawMode = PointerState.Obstacle;
this.drawMode = MAT_ROCK;
break;
}
case "KeyR": {
this.drawMode = PointerState.Erase;
this.drawMode = MAT_AIR;
break;
}
case "Digit1": {
this.drawMode = MAT_SAND;
break;
}
case "Digit2": {
this.drawMode = MAT_DIRT;
break;
}
}
});
window.addEventListener("keyup", () => {
this.drawMode = PointerState.None;
this.drawMode = -1;
});
}

View file

@ -13,24 +13,12 @@ uniform float brushRadius;
void main() {
vec4 lastState = texture(tWorld, vUv);
int cellData = int(lastState.x);
int isFood = cellData & 1;
int isHome = (cellData & 2) >> 1;
int isObstacle = (cellData & 4) >> 2;
float materialId = lastState.x;
if (distance(pointerPosition, vUv) < brushRadius / WORLD_SIZE) {
if (drawMode == 1.) {
isFood = 1;
} else if (drawMode == 2.) {
isHome = 1;
} else if (drawMode == 3.) {
isObstacle = 1;
} else if (drawMode == 4.) {
isFood = 0;
isHome = 0;
isObstacle = 0;
}
// drawMode >= 0 means painting that material ID; -1 means not drawing
if (drawMode >= 0. && distance(pointerPosition, vUv) < brushRadius / WORLD_SIZE) {
materialId = drawMode;
}
FragColor = vec4(float(isFood + (isHome << 1) + (isObstacle << 2)), lastState.yzw);
}
FragColor = vec4(materialId, lastState.yzw);
}