UNPKG

three-stdlib

Version:

stand-alone library of threejs examples

133 lines (132 loc) 4.14 kB
import { CompressedTextureLoader, RGBA_PVRTC_4BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGBA_PVRTC_2BPPV1_Format, RGB_PVRTC_2BPPV1_Format } from "three"; class PVRLoader extends CompressedTextureLoader { constructor(manager) { super(manager); } parse(buffer, loadMipmaps) { const headerLengthInt = 13; const header = new Uint32Array(buffer, 0, headerLengthInt); const pvrDatas = { buffer, header, loadMipmaps }; if (header[0] === 55727696) { return _parseV3(pvrDatas); } else if (header[11] === 559044176) { return _parseV2(pvrDatas); } else { console.error("THREE.PVRLoader: Unknown PVR format."); } } } function _parseV3(pvrDatas) { const header = pvrDatas.header; let bpp, format; const metaLen = header[12], pixelFormat = header[2], height = header[6], width = header[7], numFaces = header[10], numMipmaps = header[11]; switch (pixelFormat) { case 0: bpp = 2; format = RGB_PVRTC_2BPPV1_Format; break; case 1: bpp = 2; format = RGBA_PVRTC_2BPPV1_Format; break; case 2: bpp = 4; format = RGB_PVRTC_4BPPV1_Format; break; case 3: bpp = 4; format = RGBA_PVRTC_4BPPV1_Format; break; default: console.error("THREE.PVRLoader: Unsupported PVR format:", pixelFormat); } pvrDatas.dataPtr = 52 + metaLen; pvrDatas.bpp = bpp; pvrDatas.format = format; pvrDatas.width = width; pvrDatas.height = height; pvrDatas.numSurfaces = numFaces; pvrDatas.numMipmaps = numMipmaps; pvrDatas.isCubemap = numFaces === 6; return _extract(pvrDatas); } function _parseV2(pvrDatas) { const header = pvrDatas.header; const headerLength = header[0], height = header[1], width = header[2], numMipmaps = header[3], flags = header[4], bitmaskAlpha = header[10], numSurfs = header[12]; const TYPE_MASK = 255; const PVRTC_2 = 24, PVRTC_4 = 25; const formatFlags = flags & TYPE_MASK; let bpp, format; const _hasAlpha = bitmaskAlpha > 0; if (formatFlags === PVRTC_4) { format = _hasAlpha ? RGBA_PVRTC_4BPPV1_Format : RGB_PVRTC_4BPPV1_Format; bpp = 4; } else if (formatFlags === PVRTC_2) { format = _hasAlpha ? RGBA_PVRTC_2BPPV1_Format : RGB_PVRTC_2BPPV1_Format; bpp = 2; } else { console.error("THREE.PVRLoader: Unknown PVR format:", formatFlags); } pvrDatas.dataPtr = headerLength; pvrDatas.bpp = bpp; pvrDatas.format = format; pvrDatas.width = width; pvrDatas.height = height; pvrDatas.numSurfaces = numSurfs; pvrDatas.numMipmaps = numMipmaps + 1; pvrDatas.isCubemap = numSurfs === 6; return _extract(pvrDatas); } function _extract(pvrDatas) { const pvr = { mipmaps: [], width: pvrDatas.width, height: pvrDatas.height, format: pvrDatas.format, mipmapCount: pvrDatas.numMipmaps, isCubemap: pvrDatas.isCubemap }; const buffer = pvrDatas.buffer; let dataOffset = pvrDatas.dataPtr, dataSize = 0, blockSize = 0, blockWidth = 0, blockHeight = 0, widthBlocks = 0, heightBlocks = 0; const bpp = pvrDatas.bpp, numSurfs = pvrDatas.numSurfaces; if (bpp === 2) { blockWidth = 8; blockHeight = 4; } else { blockWidth = 4; blockHeight = 4; } blockSize = blockWidth * blockHeight * bpp / 8; pvr.mipmaps.length = pvrDatas.numMipmaps * numSurfs; let mipLevel = 0; while (mipLevel < pvrDatas.numMipmaps) { const sWidth = pvrDatas.width >> mipLevel, sHeight = pvrDatas.height >> mipLevel; widthBlocks = sWidth / blockWidth; heightBlocks = sHeight / blockHeight; if (widthBlocks < 2) widthBlocks = 2; if (heightBlocks < 2) heightBlocks = 2; dataSize = widthBlocks * heightBlocks * blockSize; for (let surfIndex = 0; surfIndex < numSurfs; surfIndex++) { const byteArray = new Uint8Array(buffer, dataOffset, dataSize); const mipmap = { data: byteArray, width: sWidth, height: sHeight }; pvr.mipmaps[surfIndex * pvrDatas.numMipmaps + mipLevel] = mipmap; dataOffset += dataSize; } mipLevel++; } return pvr; } export { PVRLoader }; //# sourceMappingURL=PVRLoader.js.map