add panorama support, close #86
This commit is contained in:
parent
ff510a9ad0
commit
02c520e421
|
@ -231,6 +231,17 @@
|
||||||
onclick="document.getElementById('cape_url_upload').click();">Browse...</button>
|
onclick="document.getElementById('cape_url_upload').click();">Browse...</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="control">
|
||||||
|
<label>Panorama URL: <input id="panorama_url" type="text" value="" placeholder="none" list="default_panorama"></label>
|
||||||
|
<datalist id="default_panorama">
|
||||||
|
<option value="">
|
||||||
|
</datalist>
|
||||||
|
<input id="panorama_url_upload" type="file" accept="image/*" style="display: none;">
|
||||||
|
<button type="button" class="control"
|
||||||
|
onclick="document.getElementById('panorama_url_upload').click();">Browse...</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="control-section">
|
<div class="control-section">
|
||||||
|
@ -303,6 +314,22 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reloadPanorama() {
|
||||||
|
const input = document.getElementById("panorama_url");
|
||||||
|
const url = input.value;
|
||||||
|
if (url === "") {
|
||||||
|
skinViewer.background = "white";
|
||||||
|
input.setCustomValidity("");
|
||||||
|
} else {
|
||||||
|
skinViewer.loadPanorama(url)
|
||||||
|
.then(() => input.setCustomValidity(""))
|
||||||
|
.catch(e => {
|
||||||
|
input.setCustomValidity("Image can't be loaded.");
|
||||||
|
console.error(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function initializeControls() {
|
function initializeControls() {
|
||||||
document.getElementById("canvas_width").addEventListener("change", e => skinViewer.width = e.target.value);
|
document.getElementById("canvas_width").addEventListener("change", e => skinViewer.width = e.target.value);
|
||||||
document.getElementById("canvas_height").addEventListener("change", e => skinViewer.height = e.target.value);
|
document.getElementById("canvas_height").addEventListener("change", e => skinViewer.height = e.target.value);
|
||||||
|
@ -348,31 +375,28 @@
|
||||||
.addEventListener("change", e => skinViewer.playerObject.skin[part][layer].visible = e.target.checked);
|
.addEventListener("change", e => skinViewer.playerObject.skin[part][layer].visible = e.target.checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const skinReader = new FileReader();
|
|
||||||
skinReader.addEventListener("load", e => {
|
const initializeUploadButton = (urlInput, browseButton, callback) => {
|
||||||
document.getElementById("skin_url").value = skinReader.result;
|
const reader = new FileReader();
|
||||||
reloadSkin();
|
reader.addEventListener("load", e => {
|
||||||
});
|
document.getElementById(urlInput).value = reader.result;
|
||||||
document.getElementById("skin_url_upload").addEventListener("change", e => {
|
callback();
|
||||||
const file = e.target.files[0];
|
});
|
||||||
if (file !== undefined) {
|
document.getElementById(browseButton).addEventListener("change", e => {
|
||||||
skinReader.readAsDataURL(file);
|
const file = e.target.files[0];
|
||||||
}
|
if (file !== undefined) {
|
||||||
});
|
reader.readAsDataURL(file);
|
||||||
const capeReader = new FileReader();
|
}
|
||||||
capeReader.addEventListener("load", e => {
|
});
|
||||||
document.getElementById("cape_url").value = capeReader.result;
|
};
|
||||||
reloadCape();
|
initializeUploadButton("skin_url", "skin_url_upload", reloadSkin);
|
||||||
});
|
initializeUploadButton("cape_url", "cape_url_upload", reloadCape);
|
||||||
document.getElementById("cape_url_upload").addEventListener("change", e => {
|
initializeUploadButton("panorama_url", "panorama_url_upload", reloadPanorama);
|
||||||
const file = e.target.files[0];
|
|
||||||
if (file !== undefined) {
|
|
||||||
capeReader.readAsDataURL(file);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
document.getElementById("skin_url").addEventListener("change", () => reloadSkin());
|
document.getElementById("skin_url").addEventListener("change", () => reloadSkin());
|
||||||
document.getElementById("skin_model").addEventListener("change", () => reloadSkin());
|
document.getElementById("skin_model").addEventListener("change", () => reloadSkin());
|
||||||
document.getElementById("cape_url").addEventListener("change", () => reloadCape());
|
document.getElementById("cape_url").addEventListener("change", () => reloadCape());
|
||||||
|
document.getElementById("panorama_url").addEventListener("change", () => reloadPanorama());
|
||||||
|
|
||||||
for (const el of document.querySelectorAll('input[type="radio"][name="back_equipment"]')) {
|
for (const el of document.querySelectorAll('input[type="radio"][name="back_equipment"]')) {
|
||||||
el.addEventListener("change", e => {
|
el.addEventListener("change", e => {
|
||||||
|
@ -394,8 +418,7 @@
|
||||||
|
|
||||||
function initializeViewer() {
|
function initializeViewer() {
|
||||||
skinViewer = new skinview3d.FXAASkinViewer({
|
skinViewer = new skinview3d.FXAASkinViewer({
|
||||||
canvas: document.getElementById("skin_container"),
|
canvas: document.getElementById("skin_container")
|
||||||
background: 0x5a76f3
|
|
||||||
});
|
});
|
||||||
orbitControl = skinview3d.createOrbitControls(skinViewer);
|
orbitControl = skinview3d.createOrbitControls(skinViewer);
|
||||||
rotateAnimation = null;
|
rotateAnimation = null;
|
||||||
|
@ -424,6 +447,7 @@
|
||||||
}
|
}
|
||||||
reloadSkin();
|
reloadSkin();
|
||||||
reloadCape();
|
reloadCape();
|
||||||
|
reloadPanorama();
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeControls();
|
initializeControls();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { inferModelType, isTextureSource, loadCapeToCanvas, loadImage, loadSkinToCanvas, ModelType, RemoteImage, TextureSource } from "skinview-utils";
|
import { inferModelType, isTextureSource, loadCapeToCanvas, loadImage, loadSkinToCanvas, ModelType, RemoteImage, TextureSource } from "skinview-utils";
|
||||||
import { Color, ColorRepresentation, NearestFilter, PerspectiveCamera, Scene, Texture, Vector2, WebGLRenderer } from "three";
|
import { Color, ColorRepresentation, EquirectangularReflectionMapping, 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";
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ export class SkinViewer {
|
||||||
readonly capeCanvas: HTMLCanvasElement;
|
readonly capeCanvas: HTMLCanvasElement;
|
||||||
private readonly skinTexture: Texture;
|
private readonly skinTexture: Texture;
|
||||||
private readonly capeTexture: Texture;
|
private readonly capeTexture: Texture;
|
||||||
|
private backgroundTexture: Texture | null = null;
|
||||||
|
|
||||||
private _disposed: boolean = false;
|
private _disposed: boolean = false;
|
||||||
private _renderPaused: boolean = false;
|
private _renderPaused: boolean = false;
|
||||||
|
@ -208,6 +209,27 @@ export class SkinViewer {
|
||||||
this.playerObject.backEquipment = null;
|
this.playerObject.backEquipment = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadPanorama<S extends TextureSource | RemoteImage>(
|
||||||
|
source: S
|
||||||
|
): S extends TextureSource ? void : Promise<void>;
|
||||||
|
|
||||||
|
loadPanorama<S extends TextureSource | RemoteImage>(
|
||||||
|
source: S
|
||||||
|
): void | Promise<void> {
|
||||||
|
if (isTextureSource(source)) {
|
||||||
|
if (this.backgroundTexture !== null) {
|
||||||
|
this.backgroundTexture.dispose();
|
||||||
|
}
|
||||||
|
this.backgroundTexture = new Texture();
|
||||||
|
this.backgroundTexture.image = source;
|
||||||
|
this.backgroundTexture.mapping = EquirectangularReflectionMapping;
|
||||||
|
this.backgroundTexture.needsUpdate = true;
|
||||||
|
this.scene.background = this.backgroundTexture;
|
||||||
|
} else {
|
||||||
|
return loadImage(source).then(image => this.loadPanorama(image));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private draw(): void {
|
private draw(): void {
|
||||||
this.animations.runAnimationLoop(this.playerObject);
|
this.animations.runAnimationLoop(this.playerObject);
|
||||||
this.render();
|
this.render();
|
||||||
|
@ -242,6 +264,10 @@ export class SkinViewer {
|
||||||
this.renderer.dispose();
|
this.renderer.dispose();
|
||||||
this.skinTexture.dispose();
|
this.skinTexture.dispose();
|
||||||
this.capeTexture.dispose();
|
this.capeTexture.dispose();
|
||||||
|
if (this.backgroundTexture !== null) {
|
||||||
|
this.backgroundTexture.dispose();
|
||||||
|
this.backgroundTexture = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get disposed(): boolean {
|
get disposed(): boolean {
|
||||||
|
@ -294,5 +320,9 @@ export class SkinViewer {
|
||||||
} else {
|
} else {
|
||||||
this.scene.background = new Color(value);
|
this.scene.background = new Color(value);
|
||||||
}
|
}
|
||||||
|
if (this.backgroundTexture !== null && value !== this.backgroundTexture) {
|
||||||
|
this.backgroundTexture.dispose();
|
||||||
|
this.backgroundTexture = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue