1 line
37 KiB
Plaintext
1 line
37 KiB
Plaintext
|
|
{"version":3,"file":"GeometryCompressionUtils.cjs","sources":["../../src/utils/GeometryCompressionUtils.js"],"sourcesContent":["/**\n * Octahedron and Quantization encodings based on work by:\n *\n * @link https://github.com/tsherif/mesh-quantization-example\n *\n */\n\nimport {\n BufferAttribute,\n Matrix3,\n Matrix4,\n MeshPhongMaterial,\n ShaderChunk,\n ShaderLib,\n UniformsUtils,\n Vector3,\n} from 'three'\nimport { version } from '../_polyfill/constants'\n\nvar GeometryCompressionUtils = {\n /**\n * Make the input mesh.geometry's normal attribute encoded and compressed by 3 different methods.\n * Also will change the mesh.material to `PackedPhongMaterial` which let the vertex shader program decode the normal data.\n *\n * @param {THREE.Mesh} mesh\n * @param {String} encodeMethod\t\t\"DEFAULT\" || \"OCT1Byte\" || \"OCT2Byte\" || \"ANGLES\"\n *\n */\n compressNormals: function (mesh, encodeMethod) {\n if (!mesh.geometry) {\n console.error('Mesh must contain geometry. ')\n }\n\n const normal = mesh.geometry.attributes.normal\n\n if (!normal) {\n console.error('Geometry must contain normal attribute. ')\n }\n\n if (normal.isPacked) return\n\n if (normal.itemSize != 3) {\n console.error('normal.itemSize is not 3, which cannot be encoded. ')\n }\n\n const array = normal.array\n const count = normal.count\n\n let result\n if (encodeMethod == 'DEFAULT') {\n // TODO: Add 1 byte to the result, making the encoded length to be 4 bytes.\n result = new Uint8Array(count * 3)\n\n for (let idx = 0; idx < array.length; idx += 3) {\n const encoded = this.EncodingFuncs.defaultEncode(array[idx], array[idx + 1], array[idx + 2], 1)\n\n result[idx + 0] = encoded[0]\n result[idx + 1] = encoded[1]\n result[idx + 2] = encoded[2]\n }\n\n mesh.geometry.setAttribute('normal', new BufferAttribute(result, 3, true))\n mesh.geometry.attributes.normal.bytes = result.length * 1\n } else if (encodeMethod == 'OCT1Byte') {\n /**\n * It is not recommended to use 1-byte octahedron normals encoding unless you want to extremely reduce the memory usage\n * As it makes vertex data not aligned to a 4 byte boundary which may harm some WebGL implementations and sometimes the normal distortion is visible\n * Please refer to @zeux 's comments in https://github.com/mrdoob/three.js/pull/18208\n */\n\n result = new Int8Array(count * 2)\n\n for (let idx = 0; idx < array.length; idx += 3) {\n const encoded = this.EncodingFuncs.octEncodeBest(array[idx], array[idx + 1], array[idx + 2], 1)\n\n result[(idx / 3) * 2 + 0] = encoded[0]\n result[(idx / 3) * 2 + 1] = encoded[1]\n }\n\n mesh.geometry.setAttribute('normal', new BufferAttribute(result, 2, true))\n mesh.geometry.attributes.normal.bytes = result.length * 1\n } else if (encodeMethod == 'OCT2Byte') {\n result = new Int16Array(count * 2)\n\n for (let idx = 0; idx < array.length; idx += 3) {\n const encoded = this.EncodingFuncs.octEncodeBest(array[idx], array[idx + 1], array[idx + 2], 2)\n\n result[(idx / 3) * 2 + 0] = encoded[0]\n result[(idx / 3) * 2 + 1] = encoded[1]\n }\n\n mesh.geometry.setAttribute('normal', new BufferAttribute(result, 2, true))\n mesh.geometry.attributes.normal.bytes = result.length * 2\n } else if (encodeMethod == 'ANGLES') {\n result = new Uint16Array(count * 2)\n\n for (let idx = 0; idx < array.length; idx += 3) {\n const encoded = this.EncodingFuncs.anglesEncode(array[idx], array[idx + 1], array[idx + 2])\n\n result[(idx / 3) * 2 + 0] = encoded[0]\n result[(idx / 3) * 2 + 1] = encoded[1]\n }\n\n mesh.geometry.setAttribute('normal', new BufferAttribute(result, 2, true))\n mesh.geometry.attributes.normal.bytes = result.length * 2\n } else {\n console.error('Unrecognized encoding method, should be `DEFAULT` or `ANGLES` or `OCT`. ')\n }\n\n mesh.geometry.attributes.normal.needsUp
|