Skip to content

Commit

Permalink
fix(Composer): Fixes spinning/moving 3D cursor. Adds Safe bounding bo…
Browse files Browse the repository at this point in the history
…x creation to disable taking the size of helpers which can make the scene gigantic. Also adds a system cursor with 3D cursor to not lose it in large scenes
  • Loading branch information
jwills-jdubs committed Nov 7, 2022
1 parent 3281019 commit b8b6556
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 14 deletions.
8 changes: 4 additions & 4 deletions packages/scene-composer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,10 @@
"jest": {
"coverageThreshold": {
"global": {
"lines": 77.58,
"statements": 76.75,
"functions": 77.58,
"branches": 63.72,
"lines": 77.63,
"statements": 76.8,
"functions": 77.65,
"branches": 63.75,
"branchesTrue": 100
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const ViewCursorWidget = () => {
setCursorVisible(!!addingWidget);
setCursorStyle(addingWidget ? 'edit' : 'move');
esc();
gl.domElement.style.cursor = addingWidget ? 'none' : 'auto';
gl.domElement.style.cursor = addingWidget ? 'crosshair' : 'auto';
}, [addingWidget]);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { sceneComposerIdContext } from '../../common/sceneComposerIdContext';
import { useEditorState } from '../../store';
import { CameraControlImpl, TweenValueObject } from '../../store/internalInterfaces';
import useActiveCamera from '../../hooks/useActiveCamera';
import { getSafeBoundingBox } from '../../utils/objectThreeUtils';

import { MapControls, OrbitControls } from './controls';

Expand Down Expand Up @@ -205,7 +206,7 @@ export function findBestViewingPosition(
initial: boolean,
controls?: CameraControlImpl,
): FixedCameraTarget {
const objectBoundingBox = new THREE.Box3().expandByObject(object);
const objectBoundingBox = getSafeBoundingBox(object);
const size = new THREE.Vector3();
objectBoundingBox.getSize(size);

Expand Down
36 changes: 32 additions & 4 deletions packages/scene-composer/src/utils/objectThreeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,36 @@ export function enableShadow(component: IModelRefComponentInternal, obj: THREE.O
}
}

export const resetObjectCenter = (object: THREE.Object3D) => {
const box = new THREE.Box3().setFromObject(object);
box.getCenter(object.position);
object.position.multiplyScalar(-1);
export const resetObjectCenter = (obj: THREE.Object3D) => {
const box = new THREE.Box3().setFromObject(obj);
box.getCenter(obj.position);
obj.position.multiplyScalar(-1);
};

export const getSafeBoundingBox = (obj: THREE.Object3D): THREE.Box3 => {
// TODO: When on latest ThreeJS replace this with new THREE.Box3().setFromObject(obj, true);
const fullBoundingBox = new THREE.Box3().setFromObject(obj);
// Because LineSegments have absurd sizes in ThreeJS we need to account for these in the scene and ignore them.
// Map all Line Segments to their parent for re-parenting
const lineMap: Map<THREE.Object3D, THREE.Object3D> = new Map<THREE.Object3D, THREE.Object3D>();
obj.traverse((child) => {
if ((child as THREE.LineSegments).isLineSegments) {
if (child.parent) {
lineMap.set(child.parent, child);
}
}
});

// Severe the connection
lineMap.forEach((line) => {
line.removeFromParent();
});

const safeBoundingBox = new THREE.Box3().setFromObject(obj);

// Re-connect
lineMap.forEach((line, parent) => {
parent.add(line);
});
return safeBoundingBox;
};
3 changes: 0 additions & 3 deletions packages/scene-composer/src/utils/raycastUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ export function getIntersectionTransform(intersection: THREE.Intersection): {
normal.transformDirection(intersection.object.matrixWorld);
normal.multiplyScalar(1);
normal.add(intersection.point.clone());

// Push out
position.addScaledVector(normal, 0.0001);
}

return { position, normal };
Expand Down
24 changes: 24 additions & 0 deletions packages/scene-composer/tests/utils/objectThreeUtils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
getComponentGroupName,
getComponentsGroupName,
getEntityGroupName,
getSafeBoundingBox,
} from '../../src/utils/objectThreeUtils';

/* eslint-enable */
Expand Down Expand Up @@ -108,4 +109,27 @@ describe('objectThreeUtils', () => {
expect(object.receiveShadow).toBeTruthy();
expect(object.material.map?.anisotropy).toEqual(16);
});

it('should get the safe bounding box ignoring lineSegments', () => {
const cube = new THREE.Mesh();
const boxGeometry = new THREE.BoxGeometry(2, 2, 2);
const material = new THREE.MeshBasicMaterial();
cube.geometry = boxGeometry;
cube.material = material;

const expectedBoundingBox = new THREE.Box3().setFromObject(cube);
const originalBoundingBox = getSafeBoundingBox(cube);
expect(originalBoundingBox).toEqual(expectedBoundingBox);

const line = new THREE.LineSegments();
const lineGeometry = new THREE.BufferGeometry();
lineGeometry.setFromPoints([new THREE.Vector3(0, 0, 0), new THREE.Vector3(1000, 1000, 1000)]);
line.geometry = lineGeometry;
line.material = material;

cube.add(line);

const safeBoundingBox = getSafeBoundingBox(cube);
expect(safeBoundingBox).toEqual(originalBoundingBox);
});
});
2 changes: 1 addition & 1 deletion packages/scene-composer/tests/utils/raycastUtils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('raycastUtils', () => {

const transform = getIntersectionTransform(intersection);

expect(transform.position).toEqual(new THREE.Vector3(1.0001, 2.0003, 3.0003));
expect(transform.position).toEqual(new THREE.Vector3(1, 2, 3));
expect(transform.normal).toEqual(new THREE.Vector3(1, 3, 3));
});
});
Expand Down

0 comments on commit b8b6556

Please sign in to comment.