All files / engine/Source/Scene PickDepth.js

24.24% Statements 8/33
0% Branches 0/8
0% Functions 0/10
24.24% Lines 8/33

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                                      1x                                                                                         1x         1x 1x                                 1x                                     1x       1x       1x                      
import Cartesian4 from "../Core/Cartesian4.js";
import defined from "../Core/defined.js";
import destroyObject from "../Core/destroyObject.js";
import FramebufferManager from "../Renderer/FramebufferManager.js";
import RenderState from "../Renderer/RenderState.js";
 
/**
 * @alias PickDepth
 * @constructor
 *
 * @private
 */
function PickDepth() {
  this._framebuffer = new FramebufferManager();
 
  this._textureToCopy = undefined;
  this._copyDepthCommand = undefined;
}
 
Object.defineProperties(PickDepth.prototype, {
  framebuffer: {
    get: function () {
      return this._framebuffer.framebuffer;
    },
  },
});
 
function updateFramebuffers(pickDepth, context, depthTexture) {
  const { width, height } = depthTexture;
  pickDepth._framebuffer.update(context, width, height);
}
 
function updateCopyCommands(pickDepth, context, depthTexture) {
  if (!defined(pickDepth._copyDepthCommand)) {
    pickDepth._copyDepthCommand = context.createViewportQuadCommand(
      `uniform highp sampler2D colorTexture;
 
in vec2 v_textureCoordinates;
 
void main()
{
  vec4 globeDepthPacked = texture(czm_globeDepthTexture, v_textureCoordinates);
  float globeDepth = czm_unpackDepth(globeDepthPacked);
  float depth = texture(colorTexture, v_textureCoordinates).r;
  out_FragColor = czm_branchFreeTernary(globeDepth <= 0.0 || globeDepth >= 1.0 || depth < globeDepth && depth > 0.0 && depth < 1.0,
    czm_packDepth(depth), globeDepthPacked);
}
`,
      {
        renderState: RenderState.fromCache(),
        uniformMap: {
          colorTexture: function () {
            return pickDepth._textureToCopy;
          },
        },
        owner: pickDepth,
      },
    );
  }
 
  pickDepth._textureToCopy = depthTexture;
  pickDepth._copyDepthCommand.framebuffer = pickDepth.framebuffer;
}
 
PickDepth.prototype.update = function (context, depthTexture) {
  updateFramebuffers(this, context, depthTexture);
  updateCopyCommands(this, context, depthTexture);
};
 
const scratchPackedDepth = new Cartesian4();
const packedDepthScale = new Cartesian4(
  1.0,
  1.0 / 255.0,
  1.0 / 65025.0,
  1.0 / 16581375.0,
);
 
/**
 * Read the depth from the framebuffer at the given coordinate.
 *
 * @param {Context} context
 * @param {number} x The x-coordinate at which to read the depth.
 * @param {number} y The y-coordinate at which to read the depth.
 * @returns {number} The depth read from the framebuffer.
 *
 * @private
 */
PickDepth.prototype.getDepth = function (context, x, y) {
  // If this function is called before the framebuffer is created, the depth is undefined.
  if (!defined(this.framebuffer)) {
    return undefined;
  }
 
  const pixels = context.readPixels({
    x: x,
    y: y,
    width: 1,
    height: 1,
    framebuffer: this.framebuffer,
  });
 
  const packedDepth = Cartesian4.unpack(pixels, 0, scratchPackedDepth);
  Cartesian4.divideByScalar(packedDepth, 255.0, packedDepth);
  return Cartesian4.dot(packedDepth, packedDepthScale);
};
 
PickDepth.prototype.executeCopyDepth = function (context, passState) {
  this._copyDepthCommand.execute(context, passState);
};
 
PickDepth.prototype.isDestroyed = function () {
  return false;
};
 
PickDepth.prototype.destroy = function () {
  this._framebuffer.destroy();
  if (defined(this._copyDepthCommand)) {
    this._copyDepthCommand.shaderProgram =
      defined(this._copyDepthCommand.shaderProgram) &&
      this._copyDepthCommand.shaderProgram.destroy();
  }
 
  return destroyObject(this);
};
export default PickDepth;