add structure bounding box corners to layered outline
This commit is contained in:
+37
-20
@@ -1,38 +1,36 @@
|
|||||||
import { system, world } from "@minecraft/server";
|
import { system, world } from "@minecraft/server";
|
||||||
import { Vector } from "../lib/Vector";
|
import { Vector } from "../lib/Vector";
|
||||||
|
|
||||||
const drawFrequency = 8;
|
|
||||||
const drawParticle = "minecraft:villager_happy";
|
|
||||||
|
|
||||||
export class Outliner {
|
export class Outliner {
|
||||||
dimension;
|
dimension;
|
||||||
min = new Vector();
|
min = new Vector();
|
||||||
max = new Vector();
|
max = new Vector();
|
||||||
#shouldDraw = true;
|
drawParticle = "minecraft:villager_happy";
|
||||||
|
drawFrequency = 8;
|
||||||
|
|
||||||
#drawParticles = [];
|
#drawParticles = [];
|
||||||
#runner = null;
|
#runner = null;
|
||||||
|
|
||||||
constructor(dimension, min, max) {
|
constructor(dimension, min, max) {
|
||||||
this.dimension = world.getDimension(dimension);
|
this.dimension = dimension;
|
||||||
this.min = new Vector(min.x, min.y, min.z);
|
this.min = new Vector(min.x, min.y, min.z);
|
||||||
this.max = new Vector(max.x, max.y, max.z);
|
this.max = new Vector(max.x, max.y, max.z);
|
||||||
|
this.vertices = this.getVertices(min, max);
|
||||||
this.startDraw();
|
this.startDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
startDraw() {
|
startDraw() {
|
||||||
this.#shouldDraw = true;
|
this.#runner = system.runInterval(() => this.draw(), this.drawFrequency);
|
||||||
this.#runner = system.runInterval(() => this.draw(), drawFrequency);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stopDraw() {
|
stopDraw() {
|
||||||
system.clearRun(this.#runner);
|
system.clearRun(this.#runner);
|
||||||
this.shouldDraw = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
draw() {
|
draw() {
|
||||||
if (!this.#shouldDraw) return;
|
|
||||||
this.#drawParticles.length = 0;
|
this.#drawParticles.length = 0;
|
||||||
|
this.#drawParticles.push(...this.getVerticeParticleLocations());
|
||||||
this.#drawParticles.push(...this.getCubiodParticleLocations());
|
this.#drawParticles.push(...this.getCubiodParticleLocations());
|
||||||
|
|
||||||
for (const [particleType, location] of this.#drawParticles) {
|
for (const [particleType, location] of this.#drawParticles) {
|
||||||
@@ -44,17 +42,31 @@ export class Outliner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getCubiodParticleLocations() {
|
getVertices(min, max) {
|
||||||
const vertices = [
|
return [
|
||||||
new Vector(this.min.x, this.min.y, this.min.z),
|
new Vector(min.x, min.y, min.z),
|
||||||
new Vector(this.max.x, this.min.y, this.min.z),
|
new Vector(max.x, min.y, min.z),
|
||||||
new Vector(this.min.x, this.max.y, this.min.z),
|
new Vector(min.x, max.y, min.z),
|
||||||
new Vector(this.max.x, this.max.y, this.min.z),
|
new Vector(max.x, max.y, min.z),
|
||||||
new Vector(this.min.x, this.min.y, this.max.z),
|
new Vector(min.x, min.y, max.z),
|
||||||
new Vector(this.max.x, this.min.y, this.max.z),
|
new Vector(max.x, min.y, max.z),
|
||||||
new Vector(this.min.x, this.max.y, this.max.z),
|
new Vector(min.x, max.y, max.z),
|
||||||
new Vector(this.max.x, this.max.y, this.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 = [
|
const edges = [
|
||||||
[0, 1],
|
[0, 1],
|
||||||
[0, 2],
|
[0, 2],
|
||||||
@@ -71,13 +83,18 @@ export class Outliner {
|
|||||||
];
|
];
|
||||||
const edgePoints = [];
|
const edgePoints = [];
|
||||||
for (const edge of edges) {
|
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);
|
const resolution = Math.min(Math.floor(endVertex.subtract(startVertex).length), 16);
|
||||||
for (let i = 1; i < resolution; i++) {
|
for (let i = 1; i < resolution; i++) {
|
||||||
const t = i / resolution;
|
const t = i / resolution;
|
||||||
edgePoints.push(startVertex.lerp(endVertex, t));
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { world } from "@minecraft/server";
|
import { world } from "@minecraft/server";
|
||||||
import { Outliner } from "./Outliner";
|
import { Outliner } from "./Outliner";
|
||||||
|
import { StructureOutliner } from "./StructureOutliner";
|
||||||
|
|
||||||
export class StructureInstance {
|
export class StructureInstance {
|
||||||
name;
|
name;
|
||||||
@@ -13,6 +14,7 @@ export class StructureInstance {
|
|||||||
mirror: false,
|
mirror: false,
|
||||||
currentLayer: 0
|
currentLayer: 0
|
||||||
};
|
};
|
||||||
|
outliner = void 0;
|
||||||
|
|
||||||
constructor(instanceName, structureId) {
|
constructor(instanceName, structureId) {
|
||||||
this.name = instanceName;
|
this.name = instanceName;
|
||||||
@@ -22,9 +24,8 @@ export class StructureInstance {
|
|||||||
this.#structure.saveToWorld();
|
this.#structure.saveToWorld();
|
||||||
this.#options = this.loadOptions();
|
this.#options = this.loadOptions();
|
||||||
this.#options.structureId = structureId;
|
this.#options.structureId = structureId;
|
||||||
if (this.#options.isEnabled)
|
|
||||||
this.refreshOutliner();
|
|
||||||
this.updateOptions();
|
this.updateOptions();
|
||||||
|
this.outliner = new StructureOutliner(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadOptions() {
|
loadOptions() {
|
||||||
@@ -75,6 +76,16 @@ export class StructureInstance {
|
|||||||
return this.#options.currentLayer || 0;
|
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() {
|
*getBlocks() {
|
||||||
const max = this.#structure.size;
|
const max = this.#structure.size;
|
||||||
for (let x = 0; x < max.x; x++) {
|
for (let x = 0; x < max.x; x++) {
|
||||||
@@ -135,7 +146,7 @@ export class StructureInstance {
|
|||||||
disable() {
|
disable() {
|
||||||
this.#options.isEnabled = false;
|
this.#options.isEnabled = false;
|
||||||
this.updateOptions();
|
this.updateOptions();
|
||||||
this.outliner.stopDraw();
|
this.refreshOutliner();
|
||||||
}
|
}
|
||||||
|
|
||||||
move(dimensionId, location) {
|
move(dimensionId, location) {
|
||||||
@@ -154,16 +165,7 @@ export class StructureInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
refreshOutliner() {
|
refreshOutliner() {
|
||||||
if (!this.#options.isEnabled)
|
this.outliner.refresh();
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isLocationInStructure(dimensionId, structureLocation) {
|
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;
|
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() {
|
hasLayers() {
|
||||||
return this.#structure.size.y > 1;
|
return this.#structure.size.y > 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user