This repository has been archived on 2026-01-04. You can view files and clone it, but cannot push or open issues or pull requests.
polyplus/popup.js
Index f65d95bca2 feat: add back popup, and quick links to popup
credits to svgrepo.com for the chrome and firefox icons
2024-06-30 03:59:05 -05:00

89 lines
No EOL
2.7 KiB
JavaScript

/*
ParseGLB & GetTexture function code made by ChatGPT (I didn't want to use external libraries because of storage space)
*/
document.getElementById('settings-btn').href = chrome.runtime.getURL('settings.html')
const ExtractButton = document.getElementById('extract-texture')
ExtractButton.addEventListener('click', async function(){
const MeshURL = (await (await fetch('https://api.polytoria.com/v1/assets/serve-mesh/' + ExtractButton.previousElementSibling.value)).json()).url
if (MeshURL !== undefined) {
const Mesh = (await (await fetch(MeshURL)).arrayBuffer())
const ParsedGTLF = ParseGLB(Mesh)
const Texture = GetTexture(ParsedGTLF);
if (Texture) {
const DownloadLink = document.createElement('a');
DownloadLink.href = Texture;
DownloadLink.download = ExtractButton.previousElementSibling.value + '.png';
document.body.appendChild(DownloadLink)
DownloadLink.click()
DownloadLink.remove()
}
}
})
function ParseGLB(arrayBuffer) {
const MAGIC_glTF = 0x46546C67;
const dataView = new DataView(arrayBuffer);
const magic = dataView.getUint32(0, true);
if (magic !== MAGIC_glTF) {
throw new Error('Invalid GLB file.');
}
const version = dataView.getUint32(4, true);
if (version !== 2) {
throw new Error('Unsupported GLB version.');
}
const length = dataView.getUint32(8, true);
const chunkLength = dataView.getUint32(12, true);
const chunkType = dataView.getUint32(16, true);
if (chunkType !== 0x4E4F534A) {
throw new Error('Invalid GLB JSON chunk.');
}
const jsonChunk = new TextDecoder().decode(
new Uint8Array(arrayBuffer, 20, chunkLength)
);
const json = JSON.parse(jsonChunk);
const binChunkHeader = 20 + chunkLength;
const binChunkLength = dataView.getUint32(binChunkHeader, true);
const binChunkType = dataView.getUint32(binChunkHeader + 4, true);
if (binChunkType !== 0x004E4942) {
throw new Error('Invalid GLB BIN chunk.');
}
const binChunk = arrayBuffer.slice(binChunkHeader + 8, binChunkHeader + 8 + binChunkLength);
return {
json: json,
bin: binChunk
};
}
function GetTexture(gltf) {
let Texture = null
const images = gltf.json.images;
if (images.length === 0) {
return null;
}
const image = images[0];
const bufferView = gltf.json.bufferViews[image.bufferView];
const byteOffset = bufferView.byteOffset || 0;
const byteLength = bufferView.byteLength;
const buffer = new Uint8Array(gltf.bin, byteOffset, byteLength);
const blob = new Blob([buffer], { type: image.mimeType });
return URL.createObjectURL(blob);
}