Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
0b4589de05
2
LICENSE
2
LICENSE
|
|
@ -1,7 +1,7 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2014-2018 Kent Rasmussen
|
Copyright (c) 2014-2018 Kent Rasmussen
|
||||||
Copyright (c) 2017-2020 Haowei Wen, Sean Boult and contributors
|
Copyright (c) 2017-2021 Haowei Wen, Sean Boult and contributors
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
20
package.json
20
package.json
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "skinview3d",
|
"name": "skinview3d",
|
||||||
"version": "2.0.0-beta.1",
|
"version": "2.0.0",
|
||||||
"description": "Three.js powered Minecraft skin viewer",
|
"description": "Three.js powered Minecraft skin viewer",
|
||||||
"main": "libs/skinview3d.js",
|
"main": "libs/skinview3d.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|
@ -38,21 +38,21 @@
|
||||||
"bundles"
|
"bundles"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"skinview-utils": "file:../skinview-utils",
|
"skinview-utils": "^0.6.0",
|
||||||
"three": "^0.122.0"
|
"three": "^0.125.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-node-resolve": "^10.0.0",
|
"@rollup/plugin-node-resolve": "^11.2.0",
|
||||||
"@rollup/plugin-typescript": "^6.1.0",
|
"@rollup/plugin-typescript": "^8.2.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.8.1",
|
"@typescript-eslint/eslint-plugin": "^4.15.1",
|
||||||
"@typescript-eslint/parser": "^4.8.1",
|
"@typescript-eslint/parser": "^4.15.1",
|
||||||
"@yushijinhun/three-minifier-rollup": "^0.2.0",
|
"@yushijinhun/three-minifier-rollup": "^0.2.0",
|
||||||
"eslint": "^7.13.0",
|
"eslint": "^7.20.0",
|
||||||
"local-web-server": "^4.2.1",
|
"local-web-server": "^4.2.1",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"rollup": "^2.33.3",
|
"rollup": "^2.39.0",
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
"typescript": "^4.0.5"
|
"typescript": "^4.1.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
34
src/model.ts
34
src/model.ts
|
|
@ -1,5 +1,5 @@
|
||||||
import { ModelType } from "skinview-utils";
|
import { ModelType } from "skinview-utils";
|
||||||
import { BoxGeometry, DoubleSide, FrontSide, Group, Mesh, MeshBasicMaterial, Object3D, Texture, Vector2 } from "three";
|
import { BoxGeometry, BufferAttribute, DoubleSide, FrontSide, Group, Mesh, MeshBasicMaterial, Object3D, Texture, Vector2 } from "three";
|
||||||
|
|
||||||
function setUVs(box: BoxGeometry, u: number, v: number, width: number, height: number, depth: number, textureWidth: number, textureHeight: number): void {
|
function setUVs(box: BoxGeometry, u: number, v: number, width: number, height: number, depth: number, textureWidth: number, textureHeight: number): void {
|
||||||
const toFaceVertices = (x1: number, y1: number, x2: number, y2: number) => [
|
const toFaceVertices = (x1: number, y1: number, x2: number, y2: number) => [
|
||||||
|
|
@ -16,20 +16,16 @@ function setUVs(box: BoxGeometry, u: number, v: number, width: number, height: n
|
||||||
const right = toFaceVertices(u + width + depth, v + depth, u + width + depth * 2, v + height + depth);
|
const right = toFaceVertices(u + width + depth, v + depth, u + width + depth * 2, v + height + depth);
|
||||||
const back = toFaceVertices(u + width + depth * 2, v + depth, u + width * 2 + depth * 2, v + height + depth);
|
const back = toFaceVertices(u + width + depth * 2, v + depth, u + width * 2 + depth * 2, v + height + depth);
|
||||||
|
|
||||||
box.faceVertexUvs[0] = [
|
const uvAttr = box.attributes.uv as BufferAttribute;
|
||||||
[right[3], right[0], right[2]],
|
uvAttr.copyVector2sArray([
|
||||||
[right[0], right[1], right[2]],
|
right[3], right[2], right[0], right[1],
|
||||||
[left[3], left[0], left[2]],
|
left[3], left[2], left[0], left[1],
|
||||||
[left[0], left[1], left[2]],
|
top[3], top[2], top[0], top[1],
|
||||||
[top[3], top[0], top[2]],
|
bottom[0], bottom[1], bottom[3], bottom[2],
|
||||||
[top[0], top[1], top[2]],
|
front[3], front[2], front[0], front[1],
|
||||||
[bottom[0], bottom[3], bottom[1]],
|
back[3], back[2], back[0], back[1]
|
||||||
[bottom[3], bottom[2], bottom[1]],
|
]);
|
||||||
[front[3], front[0], front[2]],
|
uvAttr.needsUpdate = true;
|
||||||
[front[0], front[1], front[2]],
|
|
||||||
[back[3], back[0], back[2]],
|
|
||||||
[back[0], back[1], back[2]]
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSkinUVs(box: BoxGeometry, u: number, v: number, width: number, height: number, depth: number): void {
|
function setSkinUVs(box: BoxGeometry, u: number, v: number, width: number, height: number, depth: number): void {
|
||||||
|
|
@ -133,8 +129,6 @@ export class SkinObject extends Group {
|
||||||
rightArmMesh.scale.y = 12;
|
rightArmMesh.scale.y = 12;
|
||||||
rightArmMesh.scale.z = 4;
|
rightArmMesh.scale.z = 4;
|
||||||
setSkinUVs(rightArmBox, 40, 16, this.slim ? 3 : 4, 12, 4);
|
setSkinUVs(rightArmBox, 40, 16, this.slim ? 3 : 4, 12, 4);
|
||||||
rightArmBox.uvsNeedUpdate = true;
|
|
||||||
rightArmBox.elementsNeedUpdate = true;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const rightArm2Box = new BoxGeometry();
|
const rightArm2Box = new BoxGeometry();
|
||||||
|
|
@ -144,8 +138,6 @@ export class SkinObject extends Group {
|
||||||
rightArm2Mesh.scale.y = 12.5;
|
rightArm2Mesh.scale.y = 12.5;
|
||||||
rightArm2Mesh.scale.z = 4.5;
|
rightArm2Mesh.scale.z = 4.5;
|
||||||
setSkinUVs(rightArm2Box, 40, 32, this.slim ? 3 : 4, 12, 4);
|
setSkinUVs(rightArm2Box, 40, 32, this.slim ? 3 : 4, 12, 4);
|
||||||
rightArm2Box.uvsNeedUpdate = true;
|
|
||||||
rightArm2Box.elementsNeedUpdate = true;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const rightArmPivot = new Group();
|
const rightArmPivot = new Group();
|
||||||
|
|
@ -170,8 +162,6 @@ export class SkinObject extends Group {
|
||||||
leftArmMesh.scale.y = 12;
|
leftArmMesh.scale.y = 12;
|
||||||
leftArmMesh.scale.z = 4;
|
leftArmMesh.scale.z = 4;
|
||||||
setSkinUVs(leftArmBox, 32, 48, this.slim ? 3 : 4, 12, 4);
|
setSkinUVs(leftArmBox, 32, 48, this.slim ? 3 : 4, 12, 4);
|
||||||
leftArmBox.uvsNeedUpdate = true;
|
|
||||||
leftArmBox.elementsNeedUpdate = true;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const leftArm2Box = new BoxGeometry();
|
const leftArm2Box = new BoxGeometry();
|
||||||
|
|
@ -181,8 +171,6 @@ export class SkinObject extends Group {
|
||||||
leftArm2Mesh.scale.y = 12.5;
|
leftArm2Mesh.scale.y = 12.5;
|
||||||
leftArm2Mesh.scale.z = 4.5;
|
leftArm2Mesh.scale.z = 4.5;
|
||||||
setSkinUVs(leftArm2Box, 48, 48, this.slim ? 3 : 4, 12, 4);
|
setSkinUVs(leftArm2Box, 48, 48, this.slim ? 3 : 4, 12, 4);
|
||||||
leftArm2Box.uvsNeedUpdate = true;
|
|
||||||
leftArm2Box.elementsNeedUpdate = true;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const leftArmPivot = new Group();
|
const leftArmPivot = new Group();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { applyMixins, CapeContainer, EarsContainer, ModelType, SkinContainer, RemoteImage, TextureSource } from "skinview-utils";
|
import { inferModelType, isTextureSource, loadCapeToCanvas, loadImage, loadSkinToCanvas, ModelType, RemoteImage, TextureSource } from "skinview-utils";
|
||||||
import { NearestFilter, PerspectiveCamera, Scene, Texture, Vector2, WebGLRenderer } from "three";
|
import { 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";
|
||||||
|
|
@ -49,7 +49,7 @@ export interface SkinViewerOptions {
|
||||||
renderPaused?: boolean;
|
renderPaused?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SkinViewer {
|
export class SkinViewer {
|
||||||
readonly canvas: HTMLCanvasElement;
|
readonly canvas: HTMLCanvasElement;
|
||||||
readonly scene: Scene;
|
readonly scene: Scene;
|
||||||
readonly camera: PerspectiveCamera;
|
readonly camera: PerspectiveCamera;
|
||||||
|
|
@ -132,19 +132,35 @@ class SkinViewer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected skinLoaded(model: ModelType, options: LoadOptions = {}): void {
|
loadSkin(empty: null): void;
|
||||||
|
loadSkin<S extends TextureSource | RemoteImage>(
|
||||||
|
source: S,
|
||||||
|
model?: ModelType | "auto-detect",
|
||||||
|
options?: LoadOptions
|
||||||
|
): S extends TextureSource ? void : Promise<void>;
|
||||||
|
|
||||||
|
loadSkin(
|
||||||
|
source: TextureSource | RemoteImage | null,
|
||||||
|
model: ModelType | "auto-detect" = "auto-detect",
|
||||||
|
options: LoadOptions = {}
|
||||||
|
): void | Promise<void> {
|
||||||
|
if (source === null) {
|
||||||
|
this.resetSkin();
|
||||||
|
} else if (isTextureSource(source)) {
|
||||||
|
loadSkinToCanvas(this.skinCanvas, source);
|
||||||
|
const actualModel = model === "auto-detect" ? inferModelType(this.skinCanvas) : model;
|
||||||
this.skinTexture.needsUpdate = true;
|
this.skinTexture.needsUpdate = true;
|
||||||
this.playerObject.skin.modelType = model;
|
this.playerObject.skin.modelType = actualModel;
|
||||||
if (options.makeVisible !== false) {
|
if (options.makeVisible !== false) {
|
||||||
this.playerObject.skin.visible = true;
|
this.playerObject.skin.visible = true;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return loadImage(source).then(image => this.loadSkin(image, model, options));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected capeLoaded(options: CapeLoadOptions = {}): void {
|
resetSkin(): void {
|
||||||
this.capeTexture.needsUpdate = true;
|
this.playerObject.skin.visible = false;
|
||||||
if (options.makeVisible !== false) {
|
|
||||||
this.playerObject.backEquipment = options.backEquipment === undefined ? "cape" : options.backEquipment;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected earsLoaded(options: LoadOptions = {}): void {
|
protected earsLoaded(options: LoadOptions = {}): void {
|
||||||
|
|
@ -158,7 +174,7 @@ class SkinViewer {
|
||||||
this.playerObject.skin.visible = false;
|
this.playerObject.skin.visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected resetCape(): void {
|
resetCape(): void {
|
||||||
this.playerObject.backEquipment = null;
|
this.playerObject.backEquipment = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -238,6 +254,3 @@ class SkinViewer {
|
||||||
this.setSize(this.width, newHeight);
|
this.setSize(this.width, newHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
interface SkinViewer extends SkinContainer<LoadOptions>, CapeContainer<CapeLoadOptions>, EarsContainer<LoadOptions> { }
|
|
||||||
applyMixins(SkinViewer, [SkinContainer, CapeContainer, EarsContainer]);
|
|
||||||
export { SkinViewer };
|
|
||||||
Loading…
Reference in New Issue