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:
parent
e6af97f402
commit
29e5dbeb06
3 changed files with 29 additions and 33 deletions
|
|
@ -18,7 +18,7 @@ export default class DrawScene extends AbstractScene {
|
||||||
uniforms: {
|
uniforms: {
|
||||||
tWorld: { value: null },
|
tWorld: { value: null },
|
||||||
pointerPosition: { value: new THREE.Vector2() },
|
pointerPosition: { value: new THREE.Vector2() },
|
||||||
drawMode: { value: 0 },
|
drawMode: { value: -1 },
|
||||||
brushRadius: { value: 0 },
|
brushRadius: { value: 0 },
|
||||||
},
|
},
|
||||||
vertexShader,
|
vertexShader,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,13 @@
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import Config from "../Config";
|
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 type Renderer from "../Renderer";
|
||||||
import fragmentShaderAnts from "../shaders/ants.frag";
|
import fragmentShaderAnts from "../shaders/ants.frag";
|
||||||
import vertexShaderAnts from "../shaders/ants.vert";
|
import vertexShaderAnts from "../shaders/ants.vert";
|
||||||
|
|
@ -7,21 +15,13 @@ import fragmentShaderGround from "../shaders/screenWorld.frag";
|
||||||
import vertexShaderGround from "../shaders/screenWorld.vert";
|
import vertexShaderGround from "../shaders/screenWorld.vert";
|
||||||
import AbstractScene from "./AbstractScene";
|
import AbstractScene from "./AbstractScene";
|
||||||
|
|
||||||
enum PointerState {
|
|
||||||
None,
|
|
||||||
Food,
|
|
||||||
Home,
|
|
||||||
Obstacle,
|
|
||||||
Erase,
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class ScreenScene extends AbstractScene {
|
export default class ScreenScene extends AbstractScene {
|
||||||
public readonly camera: THREE.OrthographicCamera;
|
public readonly camera: THREE.OrthographicCamera;
|
||||||
public readonly material: THREE.ShaderMaterial;
|
public readonly material: THREE.ShaderMaterial;
|
||||||
public ants!: THREE.InstancedMesh;
|
public ants!: THREE.InstancedMesh;
|
||||||
public readonly groundMaterial: THREE.ShaderMaterial;
|
public readonly groundMaterial: THREE.ShaderMaterial;
|
||||||
public readonly pointerPosition: THREE.Vector2 = new THREE.Vector2();
|
public readonly pointerPosition: THREE.Vector2 = new THREE.Vector2();
|
||||||
public drawMode: PointerState = PointerState.None;
|
public drawMode: number = -1;
|
||||||
// zoom stored in Config.cameraZoom
|
// zoom stored in Config.cameraZoom
|
||||||
private isPointerDown: boolean = false;
|
private isPointerDown: boolean = false;
|
||||||
public renderWidth: number = 1;
|
public renderWidth: number = 1;
|
||||||
|
|
@ -148,26 +148,34 @@ export default class ScreenScene extends AbstractScene {
|
||||||
window.addEventListener("keydown", (e) => {
|
window.addEventListener("keydown", (e) => {
|
||||||
switch (e.code) {
|
switch (e.code) {
|
||||||
case "KeyQ": {
|
case "KeyQ": {
|
||||||
this.drawMode = PointerState.Home;
|
this.drawMode = MAT_HOME;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "KeyW": {
|
case "KeyW": {
|
||||||
this.drawMode = PointerState.Food;
|
this.drawMode = MAT_FOOD;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "KeyE": {
|
case "KeyE": {
|
||||||
this.drawMode = PointerState.Obstacle;
|
this.drawMode = MAT_ROCK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "KeyR": {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener("keyup", () => {
|
window.addEventListener("keyup", () => {
|
||||||
this.drawMode = PointerState.None;
|
this.drawMode = -1;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,24 +13,12 @@ uniform float brushRadius;
|
||||||
void main() {
|
void main() {
|
||||||
vec4 lastState = texture(tWorld, vUv);
|
vec4 lastState = texture(tWorld, vUv);
|
||||||
|
|
||||||
int cellData = int(lastState.x);
|
float materialId = lastState.x;
|
||||||
int isFood = cellData & 1;
|
|
||||||
int isHome = (cellData & 2) >> 1;
|
|
||||||
int isObstacle = (cellData & 4) >> 2;
|
|
||||||
|
|
||||||
if (distance(pointerPosition, vUv) < brushRadius / WORLD_SIZE) {
|
// drawMode >= 0 means painting that material ID; -1 means not drawing
|
||||||
if (drawMode == 1.) {
|
if (drawMode >= 0. && distance(pointerPosition, vUv) < brushRadius / WORLD_SIZE) {
|
||||||
isFood = 1;
|
materialId = drawMode;
|
||||||
} else if (drawMode == 2.) {
|
|
||||||
isHome = 1;
|
|
||||||
} else if (drawMode == 3.) {
|
|
||||||
isObstacle = 1;
|
|
||||||
} else if (drawMode == 4.) {
|
|
||||||
isFood = 0;
|
|
||||||
isHome = 0;
|
|
||||||
isObstacle = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FragColor = vec4(float(isFood + (isHome << 1) + (isObstacle << 2)), lastState.yzw);
|
FragColor = vec4(materialId, lastState.yzw);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue