From 2e704e91dbab83e086d74b23ec26c3aa8e9f3ba1 Mon Sep 17 00:00:00 2001 From: Xiaoji Chen Date: Fri, 20 Dec 2019 12:42:02 -0800 Subject: [PATCH 1/2] fix various culling issues --- modules/culling/src/lib/culling-volume.js | 26 ++-- .../src/lib/perspective-off-center-frustum.js | 70 +++++------ modules/culling/src/lib/plane.js | 2 +- .../culling/test/lib/culling-volume.spec.js | 113 +++++++++--------- 4 files changed, 93 insertions(+), 118 deletions(-) diff --git a/modules/culling/src/lib/culling-volume.js b/modules/culling/src/lib/culling-volume.js index bce6f417..6b5373f9 100644 --- a/modules/culling/src/lib/culling-volume.js +++ b/modules/culling/src/lib/culling-volume.js @@ -54,10 +54,10 @@ export default class CullingVolume { let plane1 = this.planes[planeIndex + 1]; if (!plane0) { - plane0 = this.planes[planeIndex] = new Vector4(); + plane0 = this.planes[planeIndex] = new Plane(); } if (!plane1) { - plane1 = this.planes[planeIndex + 1] = new Vector4(); + plane1 = this.planes[planeIndex + 1] = new Plane(); } const plane0Center = scratchPlaneCenter @@ -66,11 +66,7 @@ export default class CullingVolume { .add(center); const plane0Distance = -faceNormal.dot(plane0Center); - // plane0.fromNormalDistance(faceNormal, plane0Distance); - plane0.x = faceNormal.x; - plane0.y = faceNormal.y; - plane0.z = faceNormal.z; - plane0.w = plane0Distance; + plane0.fromCoefficients(faceNormal.x, faceNormal.y, faceNormal.z, plane0Distance); const plane1Center = scratchPlaneCenter .copy(faceNormal) @@ -81,11 +77,12 @@ export default class CullingVolume { const plane1Distance = -negatedFaceNormal.dot(plane1Center); - // plane1.fromNormalDistance(negatedFaceNormal, plane1Distance); - plane1.x = negatedFaceNormal.x; - plane1.y = negatedFaceNormal.y; - plane1.z = negatedFaceNormal.z; - plane1.w = plane1Distance; + plane1.fromCoefficients( + negatedFaceNormal.x, + negatedFaceNormal.y, + negatedFaceNormal.z, + plane1Distance + ); planeIndex += 2; } @@ -98,8 +95,7 @@ export default class CullingVolume { assert(boundingVolume); // const planes = this.planes; let intersect = Intersect.INSIDE; - for (const planeCoefficients of this.planes) { - const plane = scratchPlane.fromCoefficients(...planeCoefficients); + for (const plane of this.planes) { const result = boundingVolume.intersectPlane(plane); switch (result) { case Intersect.OUTSIDE: @@ -150,7 +146,7 @@ export default class CullingVolume { continue; } - const plane = scratchPlane.fromCoefficients(...planes[k]); + const plane = planes[k]; const result = boundingVolume.intersectPlane(plane); if (result === Intersect.OUTSIDE) { return CullingVolume.MASK_OUTSIDE; diff --git a/modules/culling/src/lib/perspective-off-center-frustum.js b/modules/culling/src/lib/perspective-off-center-frustum.js index 460f31ec..21483cb1 100644 --- a/modules/culling/src/lib/perspective-off-center-frustum.js +++ b/modules/culling/src/lib/perspective-off-center-frustum.js @@ -5,9 +5,11 @@ // - It has not been fully adapted to math.gl conventions // - Documentation has not been ported -import {Vector3, Vector4, Matrix4, assert} from 'math.gl'; +import {Vector3, Matrix4, assert} from 'math.gl'; import CullingVolume from './culling-volume'; +import Plane from './plane'; +const scratchPlaneUpVector = new Vector3(); const scratchPlaneRightVector = new Vector3(); const scratchPlaneNearCenter = new Vector3(); const scratchPlaneFarCenter = new Vector3(); @@ -94,7 +96,14 @@ export default class PerspectiveOffCenterFrustum { this.far = options.far; this._far = this.far; - this._cullingVolume = new CullingVolume(); + this._cullingVolume = new CullingVolume([ + new Plane(), + new Plane(), + new Plane(), + new Plane(), + new Plane(), + new Plane() + ]); this._perspectiveMatrix = new Matrix4(); this._infinitePerspective = new Matrix4(); } @@ -181,7 +190,11 @@ export default class PerspectiveOffCenterFrustum { const planes = this._cullingVolume.planes; - const right = scratchPlaneRightVector.copy(direction).cross(up); + up = scratchPlaneUpVector.copy(up).normalize(); + const right = scratchPlaneRightVector + .copy(direction) + .cross(up) + .normalize(); const nearCenter = scratchPlaneNearCenter .copy(direction) @@ -201,16 +214,11 @@ export default class PerspectiveOffCenterFrustum { .multiplyByScalar(this.left) .add(nearCenter) .subtract(position) - .normalize() .cross(up) .normalize(); - planes[0] = planes[0] || new Vector4(); let plane = planes[0]; - plane.x = normal.x; - plane.y = normal.y; - plane.z = normal.z; - plane.w = -normal.dot(position); + plane.fromCoefficients(normal.x, normal.y, normal.z, -normal.dot(position)); // Right plane computation normal @@ -218,16 +226,12 @@ export default class PerspectiveOffCenterFrustum { .multiplyByScalar(this.right) .add(nearCenter) .subtract(position) - .normalize() .cross(up) - .normalize(); + .normalize() + .negate(); - planes[1] = planes[1] || new Vector4(); plane = planes[1]; - plane.x = normal.x; - plane.y = normal.y; - plane.z = normal.z; - plane.w = -normal.dot(position); + plane.fromCoefficients(normal.x, normal.y, normal.z, -normal.dot(position)); // Bottom plane computation normal @@ -235,16 +239,12 @@ export default class PerspectiveOffCenterFrustum { .multiplyByScalar(this.bottom) .add(nearCenter) .subtract(position) - .normalize() .cross(right) - .normalize(); + .normalize() + .negate(); - planes[2] = planes[2] || new Vector4(); plane = planes[2]; - plane.x = normal.x; - plane.y = normal.y; - plane.z = normal.z; - plane.w = -normal.dot(position); + plane.fromCoefficients(normal.x, normal.y, normal.z, -normal.dot(position)); // Top plane computation normal @@ -252,39 +252,23 @@ export default class PerspectiveOffCenterFrustum { .multiplyByScalar(this.top) .add(nearCenter) .subtract(position) - .normalize() .cross(right) .normalize(); - planes[3] = planes[3] || new Vector4(); plane = planes[3]; - plane.x = normal.x; - plane.y = normal.y; - plane.z = normal.z; - plane.w = -normal.dot(position); + plane.fromCoefficients(normal.x, normal.y, normal.z, -normal.dot(position)); normal = new Vector3().copy(direction).normalize(); // Near plane computation - planes[4] = planes[4] || new Vector4(); plane = planes[4]; - plane.x = direction.x; - plane.y = direction.y; - plane.z = direction.z; - plane.w = -direction.dot(nearCenter); + plane.fromCoefficients(normal.x, normal.y, normal.z, -normal.dot(nearCenter)); // Far plane computation - normal - .copy(direction) - .negate() - .normalize(); + normal.negate(); - planes[5] = planes[5] || new Vector4(); plane = planes[5]; - plane.x = normal.x; - plane.y = normal.y; - plane.z = normal.z; - plane.w = -normal.dot(farCenter); + plane.fromCoefficients(normal.x, normal.y, normal.z, -normal.dot(farCenter)); return this._cullingVolume; } diff --git a/modules/culling/src/lib/plane.js b/modules/culling/src/lib/plane.js index ef8960e9..4cc70567 100644 --- a/modules/culling/src/lib/plane.js +++ b/modules/culling/src/lib/plane.js @@ -35,7 +35,7 @@ export default class Plane { // Creates a plane from the general equation fromCoefficients(a, b, c, d) { this.normal.set(a, b, c); - assert(this.normal.len() === 1); + assert(equals(this.normal.len(), 1)); this.distance = d; return this; } diff --git a/modules/culling/test/lib/culling-volume.spec.js b/modules/culling/test/lib/culling-volume.spec.js index 9fc9042e..48136f71 100644 --- a/modules/culling/test/lib/culling-volume.spec.js +++ b/modules/culling/test/lib/culling-volume.spec.js @@ -80,9 +80,8 @@ function testWithAndWithoutPlaneMask(t, culling, bound, intersect) { t.equals(culling.computeVisibilityWithPlaneMask(bound, mask), mask); } -/* -test('CullingVolume#box intersections', tt => { - test('CullingVolume#can contain an axis aligned bounding box', t => { +test('CullingVolume#box intersections', ttt => { + ttt.test('CullingVolume#can contain an axis aligned bounding box', t => { const box1 = new AxisAlignedBoundingBox().fromPoints([ new Vector3(-0.5, 0, -1.25), new Vector3(0.5, 0, -1.25), @@ -92,12 +91,10 @@ test('CullingVolume#box intersections', tt => { testWithAndWithoutPlaneMask(t, cullingVolume, box1, Intersect.INSIDE); t.end(); }); - tt.end(); -}); - test('CullingVolume#can partially contain an axis aligned bounding box', tt => { - test('CullingVolume#on the far plane', t => { - const box2 = AxisAlignedBoundingBox.fromPoints([ + ttt.test('CullingVolume#can partially contain an axis aligned bounding box', tt => { + tt.test('CullingVolume#on the far plane', t => { + const box2 = new AxisAlignedBoundingBox().fromPoints([ new Vector3(-0.5, 0, -1.5), new Vector3(0.5, 0, -1.5), new Vector3(-0.5, 0, -2.5), @@ -107,8 +104,8 @@ test('CullingVolume#box intersections', tt => { t.end(); }); - test('CullingVolume#on the near plane', t => { - const box3 = AxisAlignedBoundingBox.fromPoints([ + tt.test('CullingVolume#on the near plane', t => { + const box3 = new AxisAlignedBoundingBox().fromPoints([ new Vector3(-0.5, 0, -0.5), new Vector3(0.5, 0, -0.5), new Vector3(-0.5, 0, -1.5), @@ -118,8 +115,8 @@ test('CullingVolume#box intersections', tt => { t.end(); }); - test('CullingVolume#on the left plane', t => { - const box4 = AxisAlignedBoundingBox.fromPoints([ + tt.test('CullingVolume#on the left plane', t => { + const box4 = new AxisAlignedBoundingBox().fromPoints([ new Vector3(-1.5, 0, -1.25), new Vector3(0, 0, -1.25), new Vector3(-1.5, 0, -1.5), @@ -129,8 +126,8 @@ test('CullingVolume#box intersections', tt => { t.end(); }); - test('CullingVolume#on the right plane', t => { - const box5 = AxisAlignedBoundingBox.fromPoints([ + tt.test('CullingVolume#on the right plane', t => { + const box5 = new AxisAlignedBoundingBox().fromPoints([ new Vector3(0, 0, -1.25), new Vector3(1.5, 0, -1.25), new Vector3(0, 0, -1.5), @@ -140,8 +137,8 @@ test('CullingVolume#box intersections', tt => { t.end(); }); - test('CullingVolume#on the top plane', t => { - const box6 = AxisAlignedBoundingBox.fromPoints([ + tt.test('CullingVolume#on the top plane', t => { + const box6 = new AxisAlignedBoundingBox().fromPoints([ new Vector3(-0.5, 0, -1.25), new Vector3(0.5, 0, -1.25), new Vector3(-0.5, 2.0, -1.75), @@ -151,8 +148,8 @@ test('CullingVolume#box intersections', tt => { t.end(); }); - test('CullingVolume#on the bottom plane', t => { - const box7 = AxisAlignedBoundingBox.fromPoints([ + tt.test('CullingVolume#on the bottom plane', t => { + const box7 = new AxisAlignedBoundingBox().fromPoints([ new Vector3(-0.5, -2.0, -1.25), new Vector3(0.5, 0, -1.25), new Vector3(-0.5, -2.0, -1.5), @@ -166,7 +163,7 @@ test('CullingVolume#box intersections', tt => { test('CullingVolume#can not contain an axis aligned bounding box', tt => { test('CullingVolume#past the far plane', t => { - const box8 = AxisAlignedBoundingBox.fromPoints([ + const box8 = new AxisAlignedBoundingBox().fromPoints([ new Vector3(-0.5, 0, -2.25), new Vector3(0.5, 0, -2.25), new Vector3(-0.5, 0, -2.75), @@ -177,7 +174,7 @@ test('CullingVolume#box intersections', tt => { }); test('CullingVolume#before the near plane', t => { - const box9 = AxisAlignedBoundingBox.fromPoints([ + const box9 = new AxisAlignedBoundingBox().fromPoints([ new Vector3(-0.5, 0, -0.25), new Vector3(0.5, 0, -0.25), new Vector3(-0.5, 0, -0.75), @@ -188,7 +185,7 @@ test('CullingVolume#box intersections', tt => { }); test('CullingVolume#past the left plane', t => { - const box10 = AxisAlignedBoundingBox.fromPoints([ + const box10 = new AxisAlignedBoundingBox().fromPoints([ new Vector3(-5, 0, -1.25), new Vector3(-3, 0, -1.25), new Vector3(-5, 0, -1.75), @@ -199,7 +196,7 @@ test('CullingVolume#box intersections', tt => { }); test('CullingVolume#past the right plane', t => { - const box11 = AxisAlignedBoundingBox.fromPoints([ + const box11 = new AxisAlignedBoundingBox().fromPoints([ new Vector3(3, 0, -1.25), new Vector3(5, 0, -1.25), new Vector3(3, 0, -1.75), @@ -210,7 +207,7 @@ test('CullingVolume#box intersections', tt => { }); test('CullingVolume#past the top plane', t => { - const box12 = AxisAlignedBoundingBox.fromPoints([ + const box12 = new AxisAlignedBoundingBox().fromPoints([ new Vector3(-0.5, 3, -1.25), new Vector3(0.5, 3, -1.25), new Vector3(-0.5, 5, -1.75), @@ -221,7 +218,7 @@ test('CullingVolume#box intersections', tt => { }); test('CullingVolume#past the bottom plane', t => { - const box13 = AxisAlignedBoundingBox.fromPoints([ + const box13 = new AxisAlignedBoundingBox().fromPoints([ new Vector3(-0.5, -3, -1.25), new Vector3(0.5, -3, -1.25), new Vector3(-0.5, -5, -1.75), @@ -234,11 +231,9 @@ test('CullingVolume#box intersections', tt => { }); ttt.end(); }); -*/ -/* test('CullingVolume#sphere intersection', ttt => { - test('CullingVolume#can contain a sphere', t => { + ttt.test('CullingVolume#can contain a sphere', t => { const sphere1 = makeBoundingSphereFromPoints([ new Vector3(0, 0, -1.25), new Vector3(0, 0, -1.75) @@ -247,8 +242,8 @@ test('CullingVolume#sphere intersection', ttt => { t.end(); }); - test('CullingVolume#can partially contain a sphere', tt => { - test('CullingVolume#on the far plane', t => { + ttt.test('CullingVolume#can partially contain a sphere', tt => { + tt.test('CullingVolume#on the far plane', t => { const sphere2 = makeBoundingSphereFromPoints([ new Vector3(0, 0, -1.5), new Vector3(0, 0, -2.5) @@ -257,7 +252,7 @@ test('CullingVolume#sphere intersection', ttt => { t.end(); }); - test('CullingVolume#on the near plane', t => { + tt.test('CullingVolume#on the near plane', t => { const sphere3 = makeBoundingSphereFromPoints([ new Vector3(0, 0, -0.5), new Vector3(0, 0, -1.5) @@ -266,7 +261,7 @@ test('CullingVolume#sphere intersection', ttt => { t.end(); }); - test('CullingVolume#on the left plane', t => { + tt.test('CullingVolume#on the left plane', t => { const sphere4 = makeBoundingSphereFromPoints([ new Vector3(-1.0, 0, -1.5), new Vector3(0, 0, -1.5) @@ -275,7 +270,7 @@ test('CullingVolume#sphere intersection', ttt => { t.end(); }); - test('CullingVolume#on the right plane', t => { + tt.test('CullingVolume#on the right plane', t => { const sphere5 = makeBoundingSphereFromPoints([ new Vector3(0, 0, -1.5), new Vector3(1.0, 0, -1.5) @@ -284,7 +279,7 @@ test('CullingVolume#sphere intersection', ttt => { t.end(); }); - test('CullingVolume#on the top plane', t => { + tt.test('CullingVolume#on the top plane', t => { const sphere6 = makeBoundingSphereFromPoints([ new Vector3(0, 0, -1.5), new Vector3(0, 2.0, -1.5) @@ -293,7 +288,7 @@ test('CullingVolume#sphere intersection', ttt => { t.end(); }); - test('CullingVolume#on the bottom plane', t => { + tt.test('CullingVolume#on the bottom plane', t => { const sphere7 = makeBoundingSphereFromPoints([ new Vector3(0, -2.0, -1.5), new Vector3(0, 0, -1.5) @@ -304,8 +299,8 @@ test('CullingVolume#sphere intersection', ttt => { tt.end(); }); - test('CullingVolume#can not contain a sphere', tt => { - test('CullingVolume#past the far plane', t => { + ttt.test('CullingVolume#can not contain a sphere', tt => { + tt.test('CullingVolume#past the far plane', t => { const sphere8 = makeBoundingSphereFromPoints([ new Vector3(0, 0, -2.25), new Vector3(0, 0, -2.75) @@ -314,7 +309,7 @@ test('CullingVolume#sphere intersection', ttt => { t.end(); }); - test('CullingVolume#before the near plane', t => { + tt.test('CullingVolume#before the near plane', t => { const sphere9 = makeBoundingSphereFromPoints([ new Vector3(0, 0, -0.25), new Vector3(0, 0, -0.5) @@ -323,7 +318,7 @@ test('CullingVolume#sphere intersection', ttt => { t.end(); }); - test('CullingVolume#past the left plane', t => { + tt.test('CullingVolume#past the left plane', t => { const sphere10 = makeBoundingSphereFromPoints([ new Vector3(-5, 0, -1.25), new Vector3(-4.5, 0, -1.75) @@ -332,7 +327,7 @@ test('CullingVolume#sphere intersection', ttt => { t.end(); }); - test('CullingVolume#past the right plane', t => { + tt.test('CullingVolume#past the right plane', t => { const sphere11 = makeBoundingSphereFromPoints([ new Vector3(4.5, 0, -1.25), new Vector3(5, 0, -1.75) @@ -341,7 +336,7 @@ test('CullingVolume#sphere intersection', ttt => { t.end(); }); - test('CullingVolume#past the top plane', t => { + tt.test('CullingVolume#past the top plane', t => { const sphere12 = makeBoundingSphereFromPoints([ new Vector3(-0.5, 4.5, -1.25), new Vector3(-0.5, 5, -1.25) @@ -350,7 +345,7 @@ test('CullingVolume#sphere intersection', ttt => { t.end(); }); - test('CullingVolume#past the bottom plane', t => { + tt.test('CullingVolume#past the bottom plane', t => { const sphere13 = makeBoundingSphereFromPoints([ new Vector3(-0.5, -4.5, -1.25), new Vector3(-0.5, -5, -1.25) @@ -370,20 +365,20 @@ test('CullingVolume#construct from bounding sphere', ttt => { ); const cullingVolume = new CullingVolume().fromBoundingSphere(boundingSphereCullingVolume); - test('CullingVolume#throws without a boundingSphere', t => { + ttt.test('CullingVolume#throws without a boundingSphere', t => { t.throws(() => new CullingVolume().fromBoundingSphere()); t.end(); }); - test('CullingVolume#can contain a volume', t => { - const sphere1 = BoundingSphere.clone(boundingSphereCullingVolume); + ttt.test('CullingVolume#can contain a volume', t => { + const sphere1 = boundingSphereCullingVolume.clone(); sphere1.radius *= 0.5; testWithAndWithoutPlaneMask(t, cullingVolume, sphere1, Intersect.INSIDE); t.end(); }); - test('CullingVolume#can partially contain a volume', tt => { - test('CullingVolume#on the far plane', t => { + ttt.test('CullingVolume#can partially contain a volume', tt => { + tt.test('CullingVolume#on the far plane', t => { const offset = new Vector3(0.0, 0.0, boundingSphereCullingVolume.radius * 1.5); const center = new Vector3().add(boundingSphereCullingVolume.center, offset, new Vector3()); const radius = boundingSphereCullingVolume.radius * 0.5; @@ -393,7 +388,7 @@ test('CullingVolume#construct from bounding sphere', ttt => { t.end(); }); - test('CullingVolume#on the near plane', t => { + tt.test('CullingVolume#on the near plane', t => { const offset = new Vector3(0.0, 0.0, -boundingSphereCullingVolume.radius * 1.5); const center = new Vector3().add(boundingSphereCullingVolume.center, offset, new Vector3()); const radius = boundingSphereCullingVolume.radius * 0.5; @@ -403,7 +398,7 @@ test('CullingVolume#construct from bounding sphere', ttt => { t.end(); }); - test('CullingVolume#on the left plane', t => { + tt.test('CullingVolume#on the left plane', t => { const offset = new Vector3(-boundingSphereCullingVolume.radius * 1.5, 0.0, 0.0); const center = new Vector3().add(boundingSphereCullingVolume.center, offset, new Vector3()); const radius = boundingSphereCullingVolume.radius * 0.5; @@ -413,7 +408,7 @@ test('CullingVolume#construct from bounding sphere', ttt => { t.end(); }); - test('CullingVolume#on the right plane', t => { + tt.test('CullingVolume#on the right plane', t => { const offset = new Vector3(boundingSphereCullingVolume.radius * 1.5, 0.0, 0.0); const center = new Vector3().add(boundingSphereCullingVolume.center, offset, new Vector3()); const radius = boundingSphereCullingVolume.radius * 0.5; @@ -423,7 +418,7 @@ test('CullingVolume#construct from bounding sphere', ttt => { t.end(); }); - test('CullingVolume#on the top plane', t => { + tt.test('CullingVolume#on the top plane', t => { const offset = new Vector3(0.0, boundingSphereCullingVolume.radius * 1.5, 0.0); const center = new Vector3().add(boundingSphereCullingVolume.center, offset, new Vector3()); const radius = boundingSphereCullingVolume.radius * 0.5; @@ -433,19 +428,20 @@ test('CullingVolume#construct from bounding sphere', ttt => { t.end(); }); - test('CullingVolume#on the bottom plane', t => { + tt.test('CullingVolume#on the bottom plane', t => { const offset = new Vector3(0.0, -boundingSphereCullingVolume.radius * 1.5, 0.0); const center = new Vector3().add(boundingSphereCullingVolume.center, offset, new Vector3()); const radius = boundingSphereCullingVolume.radius * 0.5; const sphere7 = new BoundingSphere(center, radius); testWithAndWithoutPlaneMask(t, cullingVolume, sphere7, Intersect.INTERSECTING); + t.end(); }); tt.end(); }); - test('CullingVolume#can not contain a volume', tt => { - test('CullingVolume#past the far plane', t => { + ttt.test('CullingVolume#can not contain a volume', tt => { + tt.test('CullingVolume#past the far plane', t => { const offset = new Vector3(0.0, 0.0, boundingSphereCullingVolume.radius * 2.0); const center = new Vector3().add(boundingSphereCullingVolume.center, offset, new Vector3()); const radius = boundingSphereCullingVolume.radius * 0.5; @@ -455,7 +451,7 @@ test('CullingVolume#construct from bounding sphere', ttt => { t.end(); }); - test('CullingVolume#before the near plane', t => { + tt.test('CullingVolume#before the near plane', t => { const offset = new Vector3(0.0, 0.0, -boundingSphereCullingVolume.radius * 2.0); const center = new Vector3().add(boundingSphereCullingVolume.center, offset, new Vector3()); const radius = boundingSphereCullingVolume.radius * 0.5; @@ -465,7 +461,7 @@ test('CullingVolume#construct from bounding sphere', ttt => { t.end(); }); - test('CullingVolume#past the left plane', t => { + tt.test('CullingVolume#past the left plane', t => { const offset = new Vector3(-boundingSphereCullingVolume.radius * 2.0, 0.0, 0.0); const center = new Vector3().add(boundingSphereCullingVolume.center, offset, new Vector3()); const radius = boundingSphereCullingVolume.radius * 0.5; @@ -475,7 +471,7 @@ test('CullingVolume#construct from bounding sphere', ttt => { t.end(); }); - test('CullingVolume#past the right plane', t => { + tt.test('CullingVolume#past the right plane', t => { const offset = new Vector3(boundingSphereCullingVolume.radius * 2.0, 0.0, 0.0); const center = new Vector3().add(boundingSphereCullingVolume.center, offset, new Vector3()); const radius = boundingSphereCullingVolume.radius * 0.5; @@ -485,7 +481,7 @@ test('CullingVolume#construct from bounding sphere', ttt => { t.end(); }); - test('CullingVolume#past the top plane', t => { + tt.test('CullingVolume#past the top plane', t => { const offset = new Vector3(0.0, boundingSphereCullingVolume.radius * 2.0, 0.0); const center = new Vector3().add(boundingSphereCullingVolume.center, offset, new Vector3()); const radius = boundingSphereCullingVolume.radius * 0.5; @@ -495,7 +491,7 @@ test('CullingVolume#construct from bounding sphere', ttt => { t.end(); }); - test('CullingVolume#past the bottom plane', t => { + tt.test('CullingVolume#past the bottom plane', t => { const offset = new Vector3(0.0, -boundingSphereCullingVolume.radius * 2.0, 0.0); const center = new Vector3().add(boundingSphereCullingVolume.center, offset, new Vector3()); const radius = boundingSphereCullingVolume.radius * 0.5; @@ -508,4 +504,3 @@ test('CullingVolume#construct from bounding sphere', ttt => { }); ttt.end(); }); -*/ From 70b51b7bb2dfac9aeab68f76c9c66334fae3d774 Mon Sep 17 00:00:00 2001 From: Xiaoji Chen Date: Fri, 20 Dec 2019 13:04:40 -0800 Subject: [PATCH 2/2] clean up plane generation --- modules/culling/src/lib/culling-volume.js | 9 ++---- .../src/lib/perspective-off-center-frustum.js | 28 ++++++------------- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/modules/culling/src/lib/culling-volume.js b/modules/culling/src/lib/culling-volume.js index 6b5373f9..bbd6ceec 100644 --- a/modules/culling/src/lib/culling-volume.js +++ b/modules/culling/src/lib/culling-volume.js @@ -66,7 +66,7 @@ export default class CullingVolume { .add(center); const plane0Distance = -faceNormal.dot(plane0Center); - plane0.fromCoefficients(faceNormal.x, faceNormal.y, faceNormal.z, plane0Distance); + plane0.fromPointNormal(plane0Center, faceNormal); const plane1Center = scratchPlaneCenter .copy(faceNormal) @@ -77,12 +77,7 @@ export default class CullingVolume { const plane1Distance = -negatedFaceNormal.dot(plane1Center); - plane1.fromCoefficients( - negatedFaceNormal.x, - negatedFaceNormal.y, - negatedFaceNormal.z, - plane1Distance - ); + plane1.fromPointNormal(plane1Center, negatedFaceNormal); planeIndex += 2; } diff --git a/modules/culling/src/lib/perspective-off-center-frustum.js b/modules/culling/src/lib/perspective-off-center-frustum.js index 21483cb1..2b307066 100644 --- a/modules/culling/src/lib/perspective-off-center-frustum.js +++ b/modules/culling/src/lib/perspective-off-center-frustum.js @@ -214,11 +214,9 @@ export default class PerspectiveOffCenterFrustum { .multiplyByScalar(this.left) .add(nearCenter) .subtract(position) - .cross(up) - .normalize(); + .cross(up); - let plane = planes[0]; - plane.fromCoefficients(normal.x, normal.y, normal.z, -normal.dot(position)); + planes[0].fromPointNormal(position, normal); // Right plane computation normal @@ -227,11 +225,9 @@ export default class PerspectiveOffCenterFrustum { .add(nearCenter) .subtract(position) .cross(up) - .normalize() .negate(); - plane = planes[1]; - plane.fromCoefficients(normal.x, normal.y, normal.z, -normal.dot(position)); + planes[1].fromPointNormal(position, normal); // Bottom plane computation normal @@ -240,11 +236,9 @@ export default class PerspectiveOffCenterFrustum { .add(nearCenter) .subtract(position) .cross(right) - .normalize() .negate(); - plane = planes[2]; - plane.fromCoefficients(normal.x, normal.y, normal.z, -normal.dot(position)); + planes[2].fromPointNormal(position, normal); // Top plane computation normal @@ -252,23 +246,19 @@ export default class PerspectiveOffCenterFrustum { .multiplyByScalar(this.top) .add(nearCenter) .subtract(position) - .cross(right) - .normalize(); + .cross(right); - plane = planes[3]; - plane.fromCoefficients(normal.x, normal.y, normal.z, -normal.dot(position)); + planes[3].fromPointNormal(position, normal); - normal = new Vector3().copy(direction).normalize(); + normal = new Vector3().copy(direction); // Near plane computation - plane = planes[4]; - plane.fromCoefficients(normal.x, normal.y, normal.z, -normal.dot(nearCenter)); + planes[4].fromPointNormal(nearCenter, normal); // Far plane computation normal.negate(); - plane = planes[5]; - plane.fromCoefficients(normal.x, normal.y, normal.z, -normal.dot(farCenter)); + planes[5].fromPointNormal(farCenter, normal); return this._cullingVolume; }