| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 | import BoundingSphere from "../Core/BoundingSphere.js";import BoxOutlineGeometry from "../Core/BoxOutlineGeometry.js";import Cartesian3 from "../Core/Cartesian3.js";import Check from "../Core/Check.js";import ColorGeometryInstanceAttribute from "../Core/ColorGeometryInstanceAttribute.js";import GeometryInstance from "../Core/GeometryInstance.js";import Matrix3 from "../Core/Matrix3.js";import Matrix4 from "../Core/Matrix4.js";import CesiumMath from "../Core/Math.js";import OrientedBoundingBox from "../Core/OrientedBoundingBox.js";import PerInstanceColorAppearance from "./PerInstanceColorAppearance.js";import Primitive from "./Primitive.js";const scratchU = new Cartesian3();const scratchV = new Cartesian3();const scratchW = new Cartesian3();const scratchCartesian = new Cartesian3();function computeMissingVector(a, b, result) {  result = Cartesian3.cross(a, b, result);  const magnitude = Cartesian3.magnitude(result);  return Cartesian3.multiplyByScalar(    result,    CesiumMath.EPSILON7 / magnitude,    result  );}function findOrthogonalVector(a, result) {  const temp = Cartesian3.normalize(a, scratchCartesian);  const b = Cartesian3.equalsEpsilon(    temp,    Cartesian3.UNIT_X,    CesiumMath.EPSILON6  )    ? Cartesian3.UNIT_Y    : Cartesian3.UNIT_X;  return computeMissingVector(a, b, result);}function checkHalfAxes(halfAxes) {  let u = Matrix3.getColumn(halfAxes, 0, scratchU);  let v = Matrix3.getColumn(halfAxes, 1, scratchV);  let w = Matrix3.getColumn(halfAxes, 2, scratchW);  const uZero = Cartesian3.equals(u, Cartesian3.ZERO);  const vZero = Cartesian3.equals(v, Cartesian3.ZERO);  const wZero = Cartesian3.equals(w, Cartesian3.ZERO);  if (!uZero && !vZero && !wZero) {    return halfAxes;  }  if (uZero && vZero && wZero) {    halfAxes[0] = CesiumMath.EPSILON7;    halfAxes[4] = CesiumMath.EPSILON7;    halfAxes[8] = CesiumMath.EPSILON7;    return halfAxes;  }  if (uZero && !vZero && !wZero) {    u = computeMissingVector(v, w, u);  } else if (!uZero && vZero && !wZero) {    v = computeMissingVector(u, w, v);  } else if (!uZero && !vZero && wZero) {    w = computeMissingVector(v, u, w);  } else if (!uZero) {    v = findOrthogonalVector(u, v);    w = computeMissingVector(v, u, w);  } else if (!vZero) {    u = findOrthogonalVector(v, u);    w = computeMissingVector(v, u, w);  } else if (!wZero) {    u = findOrthogonalVector(w, u);    v = computeMissingVector(w, u, v);  }  Matrix3.setColumn(halfAxes, 0, u, halfAxes);  Matrix3.setColumn(halfAxes, 1, v, halfAxes);  Matrix3.setColumn(halfAxes, 2, w, halfAxes);  return halfAxes;}/** * A tile bounding volume specified as an oriented bounding box. * @alias TileOrientedBoundingBox * @constructor * * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the box. * @param {Matrix3} [halfAxes=Matrix3.ZERO] The three orthogonal half-axes of the bounding box. *                                          Equivalently, the transformation matrix, to rotate and scale a 2x2x2 *                                          cube centered at the origin. * * @private */function TileOrientedBoundingBox(center, halfAxes) {  halfAxes = checkHalfAxes(halfAxes);  this._orientedBoundingBox = new OrientedBoundingBox(center, halfAxes);  this._boundingSphere = BoundingSphere.fromOrientedBoundingBox(    this._orientedBoundingBox  );}Object.defineProperties(TileOrientedBoundingBox.prototype, {  /**   * The underlying bounding volume.   *   * @memberof TileOrientedBoundingBox.prototype   *   * @type {Object}   * @readonly   */  boundingVolume: {    get: function () {      return this._orientedBoundingBox;    },  },  /**   * The underlying bounding sphere.   *   * @memberof TileOrientedBoundingBox.prototype   *   * @type {BoundingSphere}   * @readonly   */  boundingSphere: {    get: function () {      return this._boundingSphere;    },  },});/** * Computes the distance between this bounding box and the camera attached to frameState. * * @param {FrameState} frameState The frameState to which the camera is attached. * @returns {Number} The distance between the camera and the bounding box in meters. Returns 0 if the camera is inside the bounding volume. */TileOrientedBoundingBox.prototype.distanceToCamera = function (frameState) {  //>>includeStart('debug', pragmas.debug);  Check.defined("frameState", frameState);  //>>includeEnd('debug');  return Math.sqrt(    this._orientedBoundingBox.distanceSquaredTo(frameState.camera.positionWC)  );};/** * Determines which side of a plane this box is located. * * @param {Plane} plane The plane to test against. * @returns {Intersect} {@link Intersect.INSIDE} if the entire box is on the side of the plane *                      the normal is pointing, {@link Intersect.OUTSIDE} if the entire box is *                      on the opposite side, and {@link Intersect.INTERSECTING} if the box *                      intersects the plane. */TileOrientedBoundingBox.prototype.intersectPlane = function (plane) {  //>>includeStart('debug', pragmas.debug);  Check.defined("plane", plane);  //>>includeEnd('debug');  return this._orientedBoundingBox.intersectPlane(plane);};/** * Update the bounding box after the tile is transformed. * * @param {Cartesian3} center The center of the box. * @param {Matrix3} halfAxes The three orthogonal half-axes of the bounding box. *                           Equivalently, the transformation matrix, to rotate and scale a 2x2x2 *                           cube centered at the origin. */TileOrientedBoundingBox.prototype.update = function (center, halfAxes) {  Cartesian3.clone(center, this._orientedBoundingBox.center);  halfAxes = checkHalfAxes(halfAxes);  Matrix3.clone(halfAxes, this._orientedBoundingBox.halfAxes);  BoundingSphere.fromOrientedBoundingBox(    this._orientedBoundingBox,    this._boundingSphere  );};/** * Creates a debug primitive that shows the outline of the box. * * @param {Color} color The desired color of the primitive's mesh * @return {Primitive} */TileOrientedBoundingBox.prototype.createDebugVolume = function (color) {  //>>includeStart('debug', pragmas.debug);  Check.defined("color", color);  //>>includeEnd('debug');  const geometry = new BoxOutlineGeometry({    // Make a 2x2x2 cube    minimum: new Cartesian3(-1.0, -1.0, -1.0),    maximum: new Cartesian3(1.0, 1.0, 1.0),  });  const modelMatrix = Matrix4.fromRotationTranslation(    this.boundingVolume.halfAxes,    this.boundingVolume.center  );  const instance = new GeometryInstance({    geometry: geometry,    id: "outline",    modelMatrix: modelMatrix,    attributes: {      color: ColorGeometryInstanceAttribute.fromColor(color),    },  });  return new Primitive({    geometryInstances: instance,    appearance: new PerInstanceColorAppearance({      translucent: false,      flat: true,    }),    asynchronous: false,  });};export default TileOrientedBoundingBox;
 |