Add debug overlay
This commit is contained in:
parent
4355d13c0b
commit
08b79ae312
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"tabWidth": 4,
|
||||||
|
"semi": true,
|
||||||
|
"printWidth": 100,
|
||||||
|
"singleQuote": false,
|
||||||
|
"quoteProps": "preserve",
|
||||||
|
"arrowParens": "avoid"
|
||||||
|
}
|
||||||
|
|
@ -99,17 +99,40 @@
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.skin_wrap {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#debug_canvas {
|
||||||
|
position: absolute;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
padding: 6px;
|
||||||
|
color: #fff;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
width: 100px;
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<div class="skin_wrap">
|
||||||
<canvas id="skin_container"></canvas>
|
<canvas id="skin_container"></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
|
|
||||||
<button id="reset_all" type="button" class="control">Reset All</button>
|
<button id="reset_all" type="button" class="control">Reset All</button>
|
||||||
|
|
||||||
|
<div class="control-section">
|
||||||
|
<h1>Debug Mode</h1>
|
||||||
|
<label class="control"><input id="debug_mode_checkbox" type="checkbox"> Enable</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="control-section">
|
<div class="control-section">
|
||||||
<h1>Viewport</h1>
|
<h1>Viewport</h1>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -381,6 +404,14 @@
|
||||||
rotateAnimation.speed = e.target.value;
|
rotateAnimation.speed = e.target.value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
document.getElementById("debug_mode_checkbox").addEventListener("change", e => {
|
||||||
|
const value = e.target.checked;
|
||||||
|
skinViewer.debugInfo = value
|
||||||
|
|
||||||
|
// toggle it
|
||||||
|
skinViewer.debugCanvas.setState(value);
|
||||||
|
});
|
||||||
|
|
||||||
for (const el of document.querySelectorAll('input[type="radio"][name="primary_animation"]')) {
|
for (const el of document.querySelectorAll('input[type="radio"][name="primary_animation"]')) {
|
||||||
el.addEventListener("change", e => {
|
el.addEventListener("change", e => {
|
||||||
if (primaryAnimation !== null) {
|
if (primaryAnimation !== null) {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,100 @@
|
||||||
|
import { SkinViewer } from "./viewer";
|
||||||
|
|
||||||
|
export class DebugCanvas {
|
||||||
|
private wrapperElement: HTMLElement | null;
|
||||||
|
private canvas: HTMLCanvasElement | null;
|
||||||
|
private ctx: CanvasRenderingContext2D | null;
|
||||||
|
private _skinViewer: SkinViewer;
|
||||||
|
public enabled: boolean = false;
|
||||||
|
|
||||||
|
constructor(skinViewer: SkinViewer) {
|
||||||
|
this.canvas = null;
|
||||||
|
this.ctx = null;
|
||||||
|
this.wrapperElement = null;
|
||||||
|
|
||||||
|
this._skinViewer = skinViewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
createCanvas(): void {
|
||||||
|
// create the canvas
|
||||||
|
this.canvas = document.createElement("canvas");
|
||||||
|
|
||||||
|
const width = 100;
|
||||||
|
const height = 92;
|
||||||
|
|
||||||
|
this.ctx = this.canvas.getContext("2d");
|
||||||
|
|
||||||
|
// attempt dpi correction
|
||||||
|
const ratio = Math.ceil(window.devicePixelRatio);
|
||||||
|
this.canvas.width = width * ratio;
|
||||||
|
this.canvas.height = height * ratio;
|
||||||
|
this.canvas.style.width = `${width}px`;
|
||||||
|
this.canvas.style.height = `${height}px`;
|
||||||
|
|
||||||
|
// create a wrapper node
|
||||||
|
const wrapper = document.createElement("div");
|
||||||
|
wrapper.style.position = "absolute";
|
||||||
|
wrapper.style.top = "0";
|
||||||
|
wrapper.style.left = "0";
|
||||||
|
wrapper.style.background = "rgba(0,0,0,0.5)";
|
||||||
|
wrapper.appendChild(this.canvas);
|
||||||
|
|
||||||
|
this.wrapperElement = wrapper;
|
||||||
|
|
||||||
|
// add it to the dom and overlay it aboslute
|
||||||
|
const parent = this._skinViewer.canvas.parentNode;
|
||||||
|
if (parent) {
|
||||||
|
parent.appendChild(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
destroyCanvas(): void {
|
||||||
|
// attempt to remove canvas
|
||||||
|
this.wrapperElement?.remove();
|
||||||
|
|
||||||
|
this.canvas = null;
|
||||||
|
this.wrapperElement = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(state: boolean): void {
|
||||||
|
// set the new state
|
||||||
|
this.enabled = state;
|
||||||
|
|
||||||
|
// call the create/destroy method based on prior
|
||||||
|
this.enabled ? this.createCanvas() : this.destroyCanvas();
|
||||||
|
|
||||||
|
// debug log
|
||||||
|
console.info("[Debug canvas]", this.enabled ? "enabled": "disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
render(): void {
|
||||||
|
const { ctx, canvas, _skinViewer } = this;
|
||||||
|
|
||||||
|
if (!ctx || !canvas) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { x, y, z } = _skinViewer.camera.position;
|
||||||
|
const { x: rotX, y: rotY, z: rotZ } = _skinViewer.camera.rotation;
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
ctx.font = '14px serif';
|
||||||
|
ctx.fillStyle = 'white';
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
`x: ${x.toFixed(2)}`,
|
||||||
|
`y: ${y.toFixed(2)}`,
|
||||||
|
`z: ${z.toFixed(2)}`,
|
||||||
|
`rotX: ${rotX.toFixed(2)}`,
|
||||||
|
`rotY: ${rotY.toFixed(2)}`,
|
||||||
|
`rotZ: ${rotZ.toFixed(2)}`,
|
||||||
|
]
|
||||||
|
|
||||||
|
const spacing = 15;
|
||||||
|
const offsetX = 15;
|
||||||
|
const offsetY = 6;
|
||||||
|
items.forEach((s, index) => ctx.fillText(s, offsetY, offsetX + spacing * index));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ import { inferModelType, isTextureSource, loadCapeToCanvas, loadImage, loadSkinT
|
||||||
import { Color, ColorRepresentation, EquirectangularReflectionMapping, Group, NearestFilter, PerspectiveCamera, Scene, Texture, Vector2, WebGLRenderer } from "three";
|
import { Color, ColorRepresentation, EquirectangularReflectionMapping, Group, NearestFilter, PerspectiveCamera, Scene, Texture, Vector2, WebGLRenderer } from "three";
|
||||||
import { RootAnimation } from "./animation.js";
|
import { RootAnimation } from "./animation.js";
|
||||||
import { BackEquipment, PlayerObject } from "./model.js";
|
import { BackEquipment, PlayerObject } from "./model.js";
|
||||||
|
import { DebugCanvas } from "./debug.js";
|
||||||
|
|
||||||
export interface LoadOptions {
|
export interface LoadOptions {
|
||||||
/**
|
/**
|
||||||
|
|
@ -87,6 +88,8 @@ export class SkinViewer {
|
||||||
private onContextLost: (event: Event) => void;
|
private onContextLost: (event: Event) => void;
|
||||||
private onContextRestored: () => void;
|
private onContextRestored: () => void;
|
||||||
|
|
||||||
|
public debugCanvas: DebugCanvas;
|
||||||
|
|
||||||
constructor(options: SkinViewerOptions = {}) {
|
constructor(options: SkinViewerOptions = {}) {
|
||||||
this.canvas = options.canvas === undefined ? document.createElement("canvas") : options.canvas;
|
this.canvas = options.canvas === undefined ? document.createElement("canvas") : options.canvas;
|
||||||
|
|
||||||
|
|
@ -101,6 +104,9 @@ export class SkinViewer {
|
||||||
this.capeTexture.magFilter = NearestFilter;
|
this.capeTexture.magFilter = NearestFilter;
|
||||||
this.capeTexture.minFilter = NearestFilter;
|
this.capeTexture.minFilter = NearestFilter;
|
||||||
|
|
||||||
|
// setup debug canvas class
|
||||||
|
this.debugCanvas = new DebugCanvas(this);
|
||||||
|
|
||||||
this.scene = new Scene();
|
this.scene = new Scene();
|
||||||
|
|
||||||
this.camera = new PerspectiveCamera();
|
this.camera = new PerspectiveCamera();
|
||||||
|
|
@ -251,6 +257,10 @@ export class SkinViewer {
|
||||||
this.animations.runAnimationLoop(this.playerObject);
|
this.animations.runAnimationLoop(this.playerObject);
|
||||||
this.render();
|
this.render();
|
||||||
this.animationID = window.requestAnimationFrame(() => this.draw());
|
this.animationID = window.requestAnimationFrame(() => this.draw());
|
||||||
|
|
||||||
|
// render the debug canvas
|
||||||
|
this.debugCanvas.render();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue