Skip to content

Commit 0764cab

Browse files
some changes to handling of skins with (semi-)transparent areas
1 parent afd82cb commit 0764cab

1 file changed

Lines changed: 55 additions & 9 deletions

File tree

src/skin/index.js

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ let defOptions = {
1313
y: 35,
1414
z: 20,
1515
target: [0, 18, 0]
16-
}
16+
},
17+
makeNonTransparentOpaque: true
1718
};
1819

1920
/**
@@ -87,6 +88,11 @@ class SkinRender extends Render {
8788
capeTexture.magFilter = THREE.NearestFilter;
8889
capeTexture.minFilter = THREE.NearestFilter;
8990
capeTexture.anisotropy = 0;
91+
capeTexture.format = THREE.RGBFormat; // no transparency
92+
}
93+
94+
if (skinTexture.image.height === 32) {
95+
skinTexture.format = THREE.RGBFormat; // 64x32 don't have transparency
9096
}
9197

9298
if (!skinRender.attached && !skinRender._scene) {// Don't init scene if attached, since we already have an available scene
@@ -125,7 +131,7 @@ class SkinRender extends Render {
125131
console.log("Skin Image Loaded");
126132

127133
if (texture.slim === undefined) {
128-
if(skinRender._skinImage.height !== 32) {
134+
if (skinRender._skinImage.height !== 32) {
129135

130136
let detectCanvas = document.createElement("canvas");
131137
let detectCtx = detectCanvas.getContext("2d");
@@ -156,6 +162,46 @@ class SkinRender extends Render {
156162
}
157163
}
158164

165+
if (skinRender.options.makeNonTransparentOpaque && skinRender._skinImage.height !== 32) { // 64x32 don't have transparency
166+
let sourceCanvas = document.createElement("canvas");
167+
let sourceContext = sourceCanvas.getContext("2d");
168+
sourceCanvas.width = skinRender._skinImage.width;
169+
sourceCanvas.height = skinRender._skinImage.height;
170+
// draw skin texture
171+
sourceContext.drawImage(skinRender._skinImage, 0, 0);
172+
173+
// remove partial transparency
174+
let opaqueCanvas = document.createElement("canvas");
175+
let opaqueContext = opaqueCanvas.getContext("2d");
176+
opaqueCanvas.width = skinRender._skinImage.width;
177+
opaqueCanvas.height = skinRender._skinImage.height;
178+
179+
let imageData = sourceContext.getImageData(0, 0, sourceCanvas.width, sourceCanvas.height);
180+
let pixels = imageData.data;
181+
182+
function removeTransparency(x, y) {
183+
if (x > 0 && y > 0 && x < 32 && y < 32) return true; // top left, face + right leg + half of body
184+
if (x > 32 && y > 16 && x < 32 + 32 && y < 16 + 16) return true;// mid right, other body half + right arm
185+
if (x > 16 && y > 48 && x < 16 + 32 && y < 48 + 16) return true;// bottom mid, left leg + left arm
186+
return false;
187+
}
188+
189+
// check every pixel for transparency
190+
for (let i = 0; i < pixels.length; i += 4) {
191+
let a = pixels[i + 3];
192+
let x = (i / 4) % sourceCanvas.width;
193+
let y = Math.floor((i / 4) / sourceCanvas.width);
194+
if (a > 16 || removeTransparency(x, y)) { // alpha over threshold OR area not supposed to have transparency at all
195+
pixels[i + 3] = 255; // max the alpha
196+
}
197+
}
198+
199+
// update destination canvas
200+
opaqueContext.putImageData(imageData, 0, 0);
201+
202+
skinTexture = new THREE.CanvasTexture(opaqueCanvas);
203+
}
204+
159205
if (skinLoaded && (capeLoaded || !hasCape)) {
160206
if (!renderStarted) imagesLoaded(skinTexture, capeTexture);
161207
}
@@ -234,20 +280,20 @@ class SkinRender extends Render {
234280
})
235281
} else { // Type
236282
let capeLoadUrl = "https://api.capes.dev/load/";
237-
if(texture.capeUser) {// Try to find a player to use
238-
capeLoadUrl+=texture.capeUser;
239-
}else if (texture.username){
240-
capeLoadUrl+=texture.username;
241-
}else if(texture.uuid){
242-
capeLoadUrl+=texture.uuid;
283+
if (texture.capeUser) {// Try to find a player to use
284+
capeLoadUrl += texture.capeUser;
285+
} else if (texture.username) {
286+
capeLoadUrl += texture.username;
287+
} else if (texture.uuid) {
288+
capeLoadUrl += texture.uuid;
243289
} else {
244290
console.warn("Couldn't find a user to get a cape from");
245291
}
246292
capeLoadUrl += "/" + texture.cape; // append type
247293

248294
getJSON(capeLoadUrl, function (err, data) {
249295
if (err) return console.log(err);
250-
// Should be a single object of the requested type
296+
// Should be a single object of the requested type
251297
if (data.exists) {
252298
texture._capeType = data.type;
253299
skinRender._capeImage.src = data.imageUrls.base.full;

0 commit comments

Comments
 (0)