forked from PrismarineJS/prismarine-web-client
-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: true hand display behind the setting (#217)
- Loading branch information
Showing
11 changed files
with
444 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import * as THREE from 'three' | ||
import { loadSkinToCanvas } from 'skinview-utils' | ||
import stevePng from 'mc-assets/dist/other-textures/latest/entity/player/wide/steve.png' | ||
|
||
let steveTexture: THREE.Texture | ||
export const getMyHand = async (image?: string) => { | ||
let newMap: THREE.Texture | ||
if (!image && steveTexture) { | ||
newMap = steveTexture | ||
} else { | ||
image ??= stevePng | ||
const skinCanvas = document.createElement('canvas') | ||
const img = new Image() | ||
img.src = image | ||
await new Promise<void>(resolve => { | ||
img.onload = () => { | ||
resolve() | ||
} | ||
}) | ||
loadSkinToCanvas(skinCanvas, img) | ||
newMap = new THREE.CanvasTexture(skinCanvas) | ||
// newMap.flipY = false | ||
newMap.magFilter = THREE.NearestFilter | ||
newMap.minFilter = THREE.NearestFilter | ||
if (!image) { | ||
steveTexture = newMap | ||
} | ||
} | ||
|
||
// right arm | ||
const box = new THREE.BoxGeometry() | ||
const material = new THREE.MeshStandardMaterial() | ||
const slim = false | ||
const mesh = new THREE.Mesh(box, material) | ||
mesh.scale.x = slim ? 3 : 4 | ||
mesh.scale.y = 12 | ||
mesh.scale.z = 4 | ||
setSkinUVs(box, 40, 16, slim ? 3 : 4, 12, 4) | ||
material.map = newMap | ||
material.needsUpdate = true | ||
const group = new THREE.Group() | ||
group.add(mesh) | ||
group.scale.set(0.1, 0.1, 0.1) | ||
mesh.rotation.z = Math.PI | ||
return group | ||
} | ||
|
||
function setUVs ( | ||
box: THREE.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) => [ | ||
new THREE.Vector2(x1 / textureWidth, 1 - y2 / textureHeight), | ||
new THREE.Vector2(x2 / textureWidth, 1 - y2 / textureHeight), | ||
new THREE.Vector2(x2 / textureWidth, 1 - y1 / textureHeight), | ||
new THREE.Vector2(x1 / textureWidth, 1 - y1 / textureHeight), | ||
] | ||
|
||
const top = toFaceVertices(u + depth, v, u + width + depth, v + depth) | ||
const bottom = toFaceVertices(u + width + depth, v, u + width * 2 + depth, v + depth) | ||
const left = toFaceVertices(u, v + depth, u + depth, v + depth + height) | ||
const front = toFaceVertices(u + depth, v + depth, u + width + depth, v + depth + height) | ||
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 uvAttr = box.attributes.uv as THREE.BufferAttribute | ||
const uvRight = [right[3], right[2], right[0], right[1]] | ||
const uvLeft = [left[3], left[2], left[0], left[1]] | ||
const uvTop = [top[3], top[2], top[0], top[1]] | ||
const uvBottom = [bottom[0], bottom[1], bottom[3], bottom[2]] | ||
const uvFront = [front[3], front[2], front[0], front[1]] | ||
const uvBack = [back[3], back[2], back[0], back[1]] | ||
|
||
// Create a new array to hold the modified UV data | ||
const newUVData = [] as number[] | ||
|
||
// Iterate over the arrays and copy the data to uvData | ||
for (const uvArray of [uvRight, uvLeft, uvTop, uvBottom, uvFront, uvBack]) { | ||
for (const uv of uvArray) { | ||
newUVData.push(uv.x, uv.y) | ||
} | ||
} | ||
|
||
uvAttr.set(new Float32Array(newUVData)) | ||
uvAttr.needsUpdate = true | ||
} | ||
|
||
function setSkinUVs (box: THREE.BoxGeometry, u: number, v: number, width: number, height: number, depth: number): void { | ||
setUVs(box, u, v, width, height, depth, 64, 64) | ||
} |
Oops, something went wrong.