Skip to content

Commit

Permalink
fix(Composer): Safe bounding box and 3D cursor fix (#327)
Browse files Browse the repository at this point in the history
* fix(Composer): Fixes spinning/moving 3D cursor. Adds Safe bounding box 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

* Remove the unecessary to do and unused var

Co-authored-by: Emily Dodds <mumanity@gmail.com>
  • Loading branch information
jwills-jdubs and mumanity committed Nov 8, 2022
1 parent 08ca02d commit a31585f
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 10 deletions.
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
34 changes: 30 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,34 @@ 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 => {
// 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 a31585f

Please sign in to comment.