All files / engine/Source/Scene I3SDecoder.js

100% Statements 34/34
83.33% Branches 10/12
100% Functions 4/4
100% Lines 34/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134                                    1x         1x         1x     4x     4x 3x     1x                           1x               7x 6x 5x     4x 4x     4x   3x   3x   3x 3x 3x   3x 1x 1x 1x 2x 2x 2x 2x     3x 3x   3x           3x             3x   3x                                         3x          
import Cartographic from "../Core/Cartographic.js";
import Check from "../Core/Check.js";
import defined from "../Core/defined.js";
import Ellipsoid from "../Core/Ellipsoid.js";
import FeatureDetection from "../Core/FeatureDetection.js";
import CesiumMath from "../Core/Math.js";
import Matrix3 from "../Core/Matrix3.js";
import RuntimeError from "../Core/RuntimeError.js";
import TaskProcessor from "../Core/TaskProcessor.js";
 
/**
 * Decode I3S using web workers.
 *
 * @private
 */
function I3SDecoder() {}
 
// Maximum concurrency to use when decoding draco models
I3SDecoder._maxDecodingConcurrency = Math.max(
  FeatureDetection.hardwareConcurrency - 1,
  1,
);
 
I3SDecoder._decodeTaskProcessor = new TaskProcessor(
  "decodeI3S",
  I3SDecoder._maxDecodingConcurrency,
);
 
I3SDecoder._promise = undefined;
 
async function initializeDecoder() {
  const result = await I3SDecoder._decodeTaskProcessor.initWebAssemblyModule({
    wasmBinaryFile: "ThirdParty/draco_decoder.wasm",
  });
  if (result) {
    return I3SDecoder._decodeTaskProcessor;
  }
 
  throw new RuntimeError("I3S decoder could not be initialized.");
}
 
/**
 * Transcodes I3S to glTF in a web worker
 * @param {string} url custom attributes source URL
 * @param {object} defaultGeometrySchema Schema to use during decoding
 * @param {I3SGeometry} geometryData The draco encoded geometry data
 * @param {Array} [featureData] The draco encoded feature data
 * @param {object} [symbologyData] The rendering symbology to apply
 * @returns Promise<undefined|object> Returns a promise which resolves to the glTF result, or undefined if the task cannot be scheduled this frame.
 *
 * @exception {RuntimeError} I3S decoder could not be initialized.
 */
I3SDecoder.decode = async function (
  url,
  defaultGeometrySchema,
  geometryData,
  featureData,
  symbologyData,
) {
  //>>includeStart('debug', pragmas.debug);
  Check.typeOf.string("url", url);
  Check.defined("defaultGeometrySchema", defaultGeometrySchema);
  Check.defined("geometryData", geometryData);
  //>>includeEnd('debug');
 
  Eif (!defined(I3SDecoder._promise)) {
    I3SDecoder._promise = initializeDecoder();
  }
 
  return I3SDecoder._promise.then(function (taskProcessor) {
    // Prepare the data to send to the worker
    const parentData = geometryData._parent._data;
    const parentRotationInverseMatrix =
      geometryData._parent._inverseRotationMatrix;
 
    let longitude = 0.0;
    let latitude = 0.0;
    let height = 0.0;
 
    if (defined(parentData.obb)) {
      longitude = parentData.obb.center[0];
      latitude = parentData.obb.center[1];
      height = parentData.obb.center[2];
    } else Eif (defined(parentData.mbs)) {
      longitude = parentData.mbs[0];
      latitude = parentData.mbs[1];
      height = parentData.mbs[2];
    }
 
    const axisFlipRotation = Matrix3.fromRotationX(-CesiumMath.PI_OVER_TWO);
    const parentRotation = new Matrix3();
 
    Matrix3.multiply(
      axisFlipRotation,
      parentRotationInverseMatrix,
      parentRotation,
    );
 
    const cartographicCenter = Cartographic.fromDegrees(
      longitude,
      latitude,
      height,
    );
 
    const cartesianCenter =
      Ellipsoid.WGS84.cartographicToCartesian(cartographicCenter);
 
    const payload = {
      binaryData: geometryData._data,
      featureData:
        defined(featureData) && defined(featureData[0])
          ? featureData[0].data
          : undefined,
      schema: defaultGeometrySchema,
      bufferInfo: geometryData._geometryBufferInfo,
      ellipsoidRadiiSquare: Ellipsoid.WGS84.radiiSquared,
      url: url,
      geoidDataList: geometryData._dataProvider._geoidDataList,
      cartographicCenter: cartographicCenter,
      cartesianCenter: cartesianCenter,
      parentRotation: parentRotation,
      enableFeatures: geometryData._dataProvider.showFeatures,
      splitGeometryByColorTransparency:
        geometryData._dataProvider.adjustMaterialAlphaMode,
      symbologyData: symbologyData,
      calculateNormals: geometryData._dataProvider.calculateNormals,
    };
 
    return taskProcessor.scheduleTask(payload);
  });
};
 
export default I3SDecoder;