123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- import { ArrayTools } from "../Misc/arrayTools.js";
- import { Matrix, Vector3 } from "../Maths/math.vector.js";
- /**
- * Class used to store bounding sphere information
- */
- export class BoundingSphere {
- /**
- * Creates a new bounding sphere
- * @param min defines the minimum vector (in local space)
- * @param max defines the maximum vector (in local space)
- * @param worldMatrix defines the new world matrix
- */
- constructor(min, max, worldMatrix) {
- /**
- * Gets the center of the bounding sphere in local space
- */
- this.center = Vector3.Zero();
- /**
- * Gets the center of the bounding sphere in world space
- */
- this.centerWorld = Vector3.Zero();
- /**
- * Gets the minimum vector in local space
- */
- this.minimum = Vector3.Zero();
- /**
- * Gets the maximum vector in local space
- */
- this.maximum = Vector3.Zero();
- this.reConstruct(min, max, worldMatrix);
- }
- /**
- * Recreates the entire bounding sphere from scratch as if we call the constructor in place
- * @param min defines the new minimum vector (in local space)
- * @param max defines the new maximum vector (in local space)
- * @param worldMatrix defines the new world matrix
- */
- reConstruct(min, max, worldMatrix) {
- this.minimum.copyFrom(min);
- this.maximum.copyFrom(max);
- const distance = Vector3.Distance(min, max);
- max.addToRef(min, this.center).scaleInPlace(0.5);
- this.radius = distance * 0.5;
- this._update(worldMatrix || Matrix.IdentityReadOnly);
- }
- /**
- * Scale the current bounding sphere by applying a scale factor
- * @param factor defines the scale factor to apply
- * @returns the current bounding box
- */
- scale(factor) {
- const newRadius = this.radius * factor;
- const tmpVectors = BoundingSphere._TmpVector3;
- const tempRadiusVector = tmpVectors[0].setAll(newRadius);
- const min = this.center.subtractToRef(tempRadiusVector, tmpVectors[1]);
- const max = this.center.addToRef(tempRadiusVector, tmpVectors[2]);
- this.reConstruct(min, max, this._worldMatrix);
- return this;
- }
- /**
- * Gets the world matrix of the bounding box
- * @returns a matrix
- */
- getWorldMatrix() {
- return this._worldMatrix;
- }
- // Methods
- /**
- * @internal
- */
- _update(worldMatrix) {
- if (!worldMatrix.isIdentity()) {
- Vector3.TransformCoordinatesToRef(this.center, worldMatrix, this.centerWorld);
- const tempVector = BoundingSphere._TmpVector3[0];
- Vector3.TransformNormalFromFloatsToRef(1.0, 1.0, 1.0, worldMatrix, tempVector);
- this.radiusWorld = Math.max(Math.abs(tempVector.x), Math.abs(tempVector.y), Math.abs(tempVector.z)) * this.radius;
- }
- else {
- this.centerWorld.copyFrom(this.center);
- this.radiusWorld = this.radius;
- }
- }
- /**
- * Tests if the bounding sphere is intersecting the frustum planes
- * @param frustumPlanes defines the frustum planes to test
- * @returns true if there is an intersection
- */
- isInFrustum(frustumPlanes) {
- const center = this.centerWorld;
- const radius = this.radiusWorld;
- for (let i = 0; i < 6; i++) {
- if (frustumPlanes[i].dotCoordinate(center) <= -radius) {
- return false;
- }
- }
- return true;
- }
- /**
- * Tests if the bounding sphere center is in between the frustum planes.
- * Used for optimistic fast inclusion.
- * @param frustumPlanes defines the frustum planes to test
- * @returns true if the sphere center is in between the frustum planes
- */
- isCenterInFrustum(frustumPlanes) {
- const center = this.centerWorld;
- for (let i = 0; i < 6; i++) {
- if (frustumPlanes[i].dotCoordinate(center) < 0) {
- return false;
- }
- }
- return true;
- }
- /**
- * Tests if a point is inside the bounding sphere
- * @param point defines the point to test
- * @returns true if the point is inside the bounding sphere
- */
- intersectsPoint(point) {
- const squareDistance = Vector3.DistanceSquared(this.centerWorld, point);
- if (this.radiusWorld * this.radiusWorld < squareDistance) {
- return false;
- }
- return true;
- }
- // Statics
- /**
- * Checks if two sphere intersect
- * @param sphere0 sphere 0
- * @param sphere1 sphere 1
- * @returns true if the spheres intersect
- */
- static Intersects(sphere0, sphere1) {
- const squareDistance = Vector3.DistanceSquared(sphere0.centerWorld, sphere1.centerWorld);
- const radiusSum = sphere0.radiusWorld + sphere1.radiusWorld;
- if (radiusSum * radiusSum < squareDistance) {
- return false;
- }
- return true;
- }
- /**
- * Creates a sphere from a center and a radius
- * @param center The center
- * @param radius radius
- * @param matrix Optional worldMatrix
- * @returns The sphere
- */
- static CreateFromCenterAndRadius(center, radius, matrix) {
- this._TmpVector3[0].copyFrom(center);
- this._TmpVector3[1].copyFromFloats(0, 0, radius);
- this._TmpVector3[2].copyFrom(center);
- this._TmpVector3[0].addInPlace(this._TmpVector3[1]);
- this._TmpVector3[2].subtractInPlace(this._TmpVector3[1]);
- const sphere = new BoundingSphere(this._TmpVector3[0], this._TmpVector3[2]);
- if (matrix) {
- sphere._worldMatrix = matrix;
- }
- else {
- sphere._worldMatrix = Matrix.Identity();
- }
- return sphere;
- }
- }
- BoundingSphere._TmpVector3 = ArrayTools.BuildArray(3, Vector3.Zero);
- //# sourceMappingURL=boundingSphere.js.map
|