Add existing to tracked
This commit is contained in:
+219
@@ -0,0 +1,219 @@
|
||||
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 {OrientedBoundingBox}
|
||||
* @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;
|
||||
Reference in New Issue
Block a user