add structure bounding box corners to layered outline

This commit is contained in:
ForestOfLight
2025-04-14 13:37:37 -07:00
Unverified
parent 3dfdc8616f
commit e21167aa4a
3 changed files with 95 additions and 34 deletions
+38 -21
View File
@@ -1,38 +1,36 @@
import { system, world } from "@minecraft/server";
import { Vector } from "../lib/Vector";
const drawFrequency = 8;
const drawParticle = "minecraft:villager_happy";
export class Outliner {
dimension;
min = new Vector();
max = new Vector();
#shouldDraw = true;
drawParticle = "minecraft:villager_happy";
drawFrequency = 8;
#drawParticles = [];
#runner = null;
constructor(dimension, min, max) {
this.dimension = world.getDimension(dimension);
this.dimension = dimension;
this.min = new Vector(min.x, min.y, min.z);
this.max = new Vector(max.x, max.y, max.z);
this.vertices = this.getVertices(min, max);
this.startDraw();
}
startDraw() {
this.#shouldDraw = true;
this.#runner = system.runInterval(() => this.draw(), drawFrequency);
this.#runner = system.runInterval(() => this.draw(), this.drawFrequency);
}
stopDraw() {
system.clearRun(this.#runner);
this.shouldDraw = false;
}
draw() {
if (!this.#shouldDraw) return;
this.#drawParticles.length = 0;
this.#drawParticles.push(...this.getVerticeParticleLocations());
this.#drawParticles.push(...this.getCubiodParticleLocations());
for (const [particleType, location] of this.#drawParticles) {
@@ -44,17 +42,31 @@ export class Outliner {
}
}
getCubiodParticleLocations() {
const vertices = [
new Vector(this.min.x, this.min.y, this.min.z),
new Vector(this.max.x, this.min.y, this.min.z),
new Vector(this.min.x, this.max.y, this.min.z),
new Vector(this.max.x, this.max.y, this.min.z),
new Vector(this.min.x, this.min.y, this.max.z),
new Vector(this.max.x, this.min.y, this.max.z),
new Vector(this.min.x, this.max.y, this.max.z),
new Vector(this.max.x, this.max.y, this.max.z)
getVertices(min, max) {
return [
new Vector(min.x, min.y, min.z),
new Vector(max.x, min.y, min.z),
new Vector(min.x, max.y, min.z),
new Vector(max.x, max.y, min.z),
new Vector(min.x, min.y, max.z),
new Vector(max.x, min.y, max.z),
new Vector(min.x, max.y, max.z),
new Vector(max.x, max.y, max.z)
];
}
setVertices(dimension, min, max) {
this.dimension = dimension;
this.min = new Vector(min.x, min.y, min.z);
this.max = new Vector(max.x, max.y, max.z);
this.vertices = this.getVertices(min, max);
}
getVerticeParticleLocations() {
return this.vertices.map((v) => [this.drawParticle, v]);
}
getCubiodParticleLocations() {
const edges = [
[0, 1],
[0, 2],
@@ -71,13 +83,18 @@ export class Outliner {
];
const edgePoints = [];
for (const edge of edges) {
const [startVertex, endVertex] = [vertices[edge[0]], vertices[edge[1]]];
const [startVertex, endVertex] = [this.vertices[edge[0]], this.vertices[edge[1]]];
const resolution = Math.min(Math.floor(endVertex.subtract(startVertex).length), 16);
for (let i = 1; i < resolution; i++) {
const t = i / resolution;
edgePoints.push(startVertex.lerp(endVertex, t));
}
}
return vertices.concat(edgePoints).map((v) => [drawParticle, v]);
return edgePoints.map((v) => [this.drawParticle, v]);
}
addStandaloneParticles(locations) {
for (const location of locations)
this.vertices.push(new Vector(location.x, location.y, location.z));
}
}
+19 -13
View File
@@ -1,5 +1,6 @@
import { world } from "@minecraft/server";
import { Outliner } from "./Outliner";
import { StructureOutliner } from "./StructureOutliner";
export class StructureInstance {
name;
@@ -13,6 +14,7 @@ export class StructureInstance {
mirror: false,
currentLayer: 0
};
outliner = void 0;
constructor(instanceName, structureId) {
this.name = instanceName;
@@ -22,9 +24,8 @@ export class StructureInstance {
this.#structure.saveToWorld();
this.#options = this.loadOptions();
this.#options.structureId = structureId;
if (this.#options.isEnabled)
this.refreshOutliner();
this.updateOptions();
this.outliner = new StructureOutliner(this);
}
loadOptions() {
@@ -75,6 +76,16 @@ export class StructureInstance {
return this.#options.currentLayer || 0;
}
getDimension() {
let dimension;
try {
dimension = world.getDimension(this.#options.dimensionId);
} catch (e) {
dimension = world.getDimension("minecraft:overworld");
}
return dimension;
}
*getBlocks() {
const max = this.#structure.size;
for (let x = 0; x < max.x; x++) {
@@ -135,7 +146,7 @@ export class StructureInstance {
disable() {
this.#options.isEnabled = false;
this.updateOptions();
this.outliner.stopDraw();
this.refreshOutliner();
}
move(dimensionId, location) {
@@ -154,16 +165,7 @@ export class StructureInstance {
}
refreshOutliner() {
if (!this.#options.isEnabled)
return;
if (this.outliner)
this.outliner.stopDraw();
if (this.#options.currentLayer > 0) {
const { min, max } = this.getLayeredBounds();
this.outliner = new Outliner(this.#options.dimensionId, this.toGlobalCoords(min), this.toGlobalCoords(max));
} else {
this.outliner = new Outliner(this.#options.dimensionId, this.toGlobalCoords(this.getBounds().min), this.toGlobalCoords(this.getBounds().max));
}
this.outliner.refresh();
}
isLocationInStructure(dimensionId, structureLocation) {
@@ -216,6 +218,10 @@ export class StructureInstance {
return this.#options.dimensionId && this.#options.worldLocation.x !== 0 && this.#options.worldLocation.y !== 0 && this.#options.worldLocation.z !== 0;
}
isUsingLayers() {
return this.hasLayers() && this.#options.currentLayer !== 0;
}
hasLayers() {
return this.#structure.size.y > 1;
}
+38
View File
@@ -0,0 +1,38 @@
import { Outliner } from '../classes/Outliner';
export class StructureOutliner {
constructor(instance) {
this.instance = instance;
this.dimension = instance.getDimension();
this.bounds = instance.getBounds();
this.bounds.min = instance.toGlobalCoords(this.bounds.min);
this.bounds.max = instance.toGlobalCoords(this.bounds.max);
this.outliner = new Outliner(this.dimension, this.bounds.min, this.bounds.max);
this.refresh();
}
refresh() {
this.outliner.stopDraw();
if (!this.instance.isEnabled())
return;
if (this.instance.isUsingLayers())
this.layeredDraw();
else
this.boxDraw();
this.outliner.startDraw();
}
boxDraw() {
this.outliner.setVertices(this.dimension, this.bounds.min, this.bounds.max);
}
layeredDraw() {
const { min, max } = this.instance.getLayeredBounds();
this.outliner.setVertices(this.dimension, this.instance.toGlobalCoords(min), this.instance.toGlobalCoords(max));
this.outliner.addStandaloneParticles(this.getCornerVertices());
}
getCornerVertices() {
return this.outliner.getVertices(this.bounds.min, this.bounds.max);
}
}