{"version":3,"file":"DRACOExporter.cjs","sources":["../../src/exporters/DRACOExporter.ts"],"sourcesContent":["import type { EncoderModule } from 'draco3d'\nimport { BufferGeometry, Mesh, Points } from 'three'\n\n/**\n * Export draco compressed files from threejs geometry objects.\n *\n * Draco files are compressed and usually are smaller than conventional 3D file formats.\n *\n * The exporter receives a options object containing\n *  - decodeSpeed, indicates how to tune the encoder regarding decode speed (0 gives better speed but worst quality)\n *  - encodeSpeed, indicates how to tune the encoder parameters (0 gives better speed but worst quality)\n *  - encoderMethod\n *  - quantization, indicates the presision of each type of data stored in the draco file in the order (POSITION, NORMAL, COLOR, TEX_COORD, GENERIC)\n *  - exportUvs\n *  - exportNormals\n */\n\ndeclare const DracoEncoderModule: () => EncoderModule\n\nclass DRACOExporter {\n  // Encoder methods\n\n  public static MESH_EDGEBREAKER_ENCODING = 1\n  public static MESH_SEQUENTIAL_ENCODING = 0\n\n  // Geometry type\n\n  public static POINT_CLOUD = 0\n  public static TRIANGULAR_MESH = 1\n\n  // Attribute type\n  public static INVALID = -1\n  public static POSITION = 0\n  public static NORMAL = 1\n  public static COLOR = 2\n  public static TEX_COORD = 3\n  public static GENERIC = 4\n\n  public parse(\n    object: Mesh | Points,\n    options = {\n      decodeSpeed: 5,\n      encodeSpeed: 5,\n      encoderMethod: DRACOExporter.MESH_EDGEBREAKER_ENCODING,\n      quantization: [16, 8, 8, 8, 8],\n      exportUvs: true,\n      exportNormals: true,\n      exportColor: false,\n    },\n  ): Int8Array {\n    if (object instanceof BufferGeometry && object.isBufferGeometry) {\n      throw new Error('DRACOExporter: The first parameter of parse() is now an instance of Mesh or Points.')\n    }\n\n    if (DracoEncoderModule === undefined) {\n      throw new Error('THREE.DRACOExporter: required the draco_encoder to work.')\n    }\n\n    const geometry = object.geometry\n\n    const dracoEncoder = DracoEncoderModule()\n    const encoder = new dracoEncoder.Encoder()\n    let builder\n    let dracoObject\n\n    if (!geometry.isBufferGeometry) {\n      throw new Error('THREE.DRACOExporter.parse(geometry, options): geometry is not a THREE.BufferGeometry instance.')\n    }\n\n    if (object instanceof Mesh && object.isMesh) {\n      builder = new dracoEncoder.MeshBuilder()\n      dracoObject = new dracoEncoder.Mesh()\n\n      const vertices = geometry.getAttribute('position')\n      // @ts-ignore\n      builder.AddFloatAttributeToMesh(\n        dracoObject,\n        dracoEncoder.POSITION,\n        vertices.count,\n        vertices.itemSize,\n        vertices.array,\n      )\n\n      const faces = geometry.getIndex()\n\n      if (faces !== null) {\n        builder.AddFacesToMesh(dracoObject, faces.count / 3, faces.array as Uint16Array | Uint32Array)\n      } else {\n        const faces = new (vertices.count > 65535 ? Uint32Array : Uint16Array)(vertices.count)\n\n        for (let i = 0; i < faces.length; i++) {\n          faces[i] = i\n        }\n\n        builder.AddFacesToMesh(dracoObject, vertices.count, faces)\n      }\n\n      if (options.exportNormals) {\n        const normals = geometry.getAttribute('normal')\n\n        if (normals !== undefined) {\n          // @ts-ignore\n          builder.AddFloatAttributeToMesh(\n            dracoObject,\n            dracoEncoder.NORMAL,\n            normals.count,\n            normals.itemSize,\n            normals.array,\n          )\n        }\n      }\n\n      if (options.exportUvs) {\n        const uvs = geometry.getAttribute('uv')\n\n        if (uvs !== undefined) {\n          // @ts-ignore\n          builder.AddFloatAttributeToMesh(dracoObject, dracoEncoder.TEX_COORD, uvs.count, uvs.itemSize, uvs.array)\n        }\n      }\n\n      if (options.exportColor) {\n        const colors = geometry.getAttribute('color')\n\n        if (colors !== undefined) {\n          // @ts-ignore\n          builder.AddFloatAttributeToMesh(dracoObject, dracoEncoder.COLOR, colors.count, colors.itemSize, colors.array)\n        }\n      }\n    } else if (object instanceof Points && object.isPoints) {\n      // @ts-ignore\n      builder = new dracoEncoder.PointCloudBuilder()\n      // @ts-ignore\n      dracoObject = new dracoEncoder.PointCloud()\n\n      const vertices = geometry.getAttribute('position')\n      builder.AddFloatAttribute(dracoObject, dracoEncoder.POSITION, vertices.count, vertices.itemSize, vertices.array)\n\n      if (options.exportColor) {\n        const colors = geometry.getAttribute('color')\n\n        if (colors !== undefined) {\n          builder.AddFloatAttribute(dracoObject, dracoEncoder.COLOR, colors.count, colors.itemSize, colors.array)\n        }\n      }\n    } else {\n      throw new Error('DRACOExporter: Unsupported object type.')\n    }\n\n    //Compress using draco encoder\n\n    const encodedData = new dracoEncoder.DracoInt8Array()\n\n    //Sets the desired encoding and decoding speed for the given options from 0 (slowest speed, but the best compression) to 10 (fastest, but the worst compression).\n\n    const encodeSpeed = options.encodeSpeed !== undefined ? options.encodeSpeed : 5\n    const decodeSpeed = options.decodeSpeed !== undefined ? options.decodeSpeed : 5\n\n    encoder.SetSpeedOptions(encodeSpeed, decodeSpeed)\n\n    // Sets the desired encoding method for a given geometry.\n\n    if (options.encoderMethod !== undefined) {\n      encoder.SetEncodingMethod(options.encoderMethod)\n    }\n\n    // Sets the quantization (number of bits used to represent) compression options for a named attribute.\n    // The attribute values will be quantized in a box defined by the maximum extent of the attribute values.\n    if (options.quantization !== undefined) {\n      for (let i = 0; i < 5; i++) {\n        if (options.quantization[i] !== undefined) {\n          encoder.SetAttributeQuantization(i, options.quantization[i])\n        }\n      }\n    }\n\n    let length\n\n    if (object instanceof Mesh && object.isMesh) {\n      length = encoder.EncodeMeshToDracoBuffer(dracoObject, encodedData)\n    } else {\n      // @ts-ignore\n      length = encoder.EncodePointCloudToDracoBuffer(dracoObject, true, encodedData)\n    }\n\n    dracoEncoder.destroy(dracoObject)\n\n    if (length === 0) {\n      throw new Error('THREE.DRACOExporter: Draco encoding failed.')\n    }\n\n    //Copy encoded data to buffer.\n    const outputData = new Int8Array(new ArrayBuffer(length))\n\n    for (let i = 0; i < length; i++) {\n      outputData[i] = encodedData.GetValue(i)\n    }\n\n    dracoEncoder.destroy(encodedData)\n    dracoEncoder.destroy(encoder)\n    dracoEncoder.destroy(builder)\n\n    return outputData\n  }\n}\n\nexport { DRACOExporter }\n"],"names":["BufferGeometry","Mesh","faces","Points"],"mappings":"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"}