106 lines
3.4 KiB
JavaScript
106 lines
3.4 KiB
JavaScript
import { system } from "@minecraft/server";
|
|
import { BlockVerificationLevel } from "../../Enums/BlockVerificationLevel";
|
|
import { renderProfileOf } from "../../Enums/RenderMode";
|
|
import { RefreshRate } from "../../Verifier/RefreshRate";
|
|
import { Vector } from "../../../lib/Vector";
|
|
import { DebugBoxLayer } from "./DebugBoxLayer";
|
|
import { PreviewParticleLayer } from "./PreviewParticleLayer";
|
|
import { PreviewSweep } from "./PreviewSweep";
|
|
|
|
const RENDER_INTERVAL_TICKS = 1;
|
|
|
|
export class BlockPreviewRenderer {
|
|
instance;
|
|
|
|
#profile;
|
|
#sweep = new PreviewSweep();
|
|
#boxes = new DebugBoxLayer();
|
|
#particles;
|
|
#runner;
|
|
|
|
constructor(instance) {
|
|
this.instance = instance;
|
|
this.#applyRenderMode();
|
|
}
|
|
|
|
refresh(isPriority = false) {
|
|
this.#stop();
|
|
this.#applyRenderMode();
|
|
if (!this.instance.isEnabled() || !this.instance.options.verifier.isEnabled)
|
|
return;
|
|
if (isPriority)
|
|
this.#sweep.arm();
|
|
this.#runner = system.runInterval(() => this.#renderNextSlice(), RENDER_INTERVAL_TICKS);
|
|
}
|
|
|
|
renderBlockAt(location) {
|
|
if (!this.#runner)
|
|
return;
|
|
const frame = this.#openFrame();
|
|
if (frame)
|
|
this.#drawCell(frame, location);
|
|
}
|
|
|
|
#applyRenderMode() {
|
|
this.#profile = renderProfileOf(this.instance.options.renderMode);
|
|
this.#particles = new PreviewParticleLayer(this.#profile.blockPreview);
|
|
}
|
|
|
|
#stop() {
|
|
this.#boxes.clear();
|
|
if (!this.#runner)
|
|
return;
|
|
system.clearRun(this.#runner);
|
|
this.#runner = void 0;
|
|
this.#sweep.reset();
|
|
}
|
|
|
|
#renderNextSlice() {
|
|
const frame = this.#openFrame();
|
|
if (!frame)
|
|
return;
|
|
const refreshSeconds = this.instance.options.verifier.refreshSeconds;
|
|
for (const location of this.#sweep.locations(frame.bounds, frame.volume, refreshSeconds))
|
|
this.#drawCell(frame, location);
|
|
}
|
|
|
|
#openFrame() {
|
|
const bounds = this.instance.getActiveBounds();
|
|
const volume = Vector.volume(bounds.min, bounds.max);
|
|
if (volume <= 0)
|
|
return void 0;
|
|
const grid = this.instance.verifier.getCompletedGrid();
|
|
if (!grid?.matchesBounds(bounds))
|
|
return void 0;
|
|
this.#boxes.retarget(bounds);
|
|
return {
|
|
bounds,
|
|
volume,
|
|
grid,
|
|
dimension: this.instance.getDimension(),
|
|
lifetimeSeconds: RefreshRate.cycleSeconds(volume, this.instance.options.verifier.refreshSeconds)
|
|
};
|
|
}
|
|
|
|
#drawCell(frame, location) {
|
|
const verificationLevel = frame.grid.get(location);
|
|
const origin = this.instance.toGlobalCoords(location);
|
|
if (this.#profile.debugMarkers) {
|
|
const index = frame.grid.indexOf(location);
|
|
this.#boxes.draw(index, frame.dimension, origin, verificationLevel);
|
|
}
|
|
if (!this.#profile.particleOverlays)
|
|
return;
|
|
if (verificationLevel === BlockVerificationLevel.Unknown || verificationLevel === BlockVerificationLevel.Air)
|
|
return;
|
|
this.#particles.draw({
|
|
dimension: frame.dimension,
|
|
origin,
|
|
block: this.instance.getBlock(location),
|
|
verificationLevel,
|
|
lifetimeSeconds: frame.lifetimeSeconds,
|
|
occlusionMask: frame.grid.occlusionMaskAt(location)
|
|
});
|
|
}
|
|
}
|