faster selection in editor
This commit is contained in:
parent
4e7b44dc57
commit
8575327af8
|
|
@ -13,24 +13,51 @@ type ObjectEditorViewProps = {
|
||||||
object: Runtime<ObjectInstance>;
|
object: Runtime<ObjectInstance>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ObjectEditorView = observer(function ({ object }: ObjectEditorViewProps) {
|
type SelectionOverlayProps = {
|
||||||
const groupRef = useRef<Group>(null);
|
objectId: string;
|
||||||
|
groupRef: RefObject<Group | null>;
|
||||||
const objectType = state.world.getObjectTypeById(object.typeId);
|
onTransformEnd: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Separate observer so only the 2 affected instances (selected/deselected)
|
||||||
|
// re-render on selection change, not all N objects in the scene.
|
||||||
|
const SelectionOverlay = observer(function ({ objectId, groupRef, onTransformEnd }: SelectionOverlayProps) {
|
||||||
const isSelected = state.worldEditor.isEnabled &&
|
const isSelected = state.worldEditor.isEnabled &&
|
||||||
state.worldEditor.selectedObjectId === object.id;
|
state.worldEditor.selectedObjectId === objectId;
|
||||||
const selectionMode = isSelected ? state.worldEditor.selectedObjectMode : undefined;
|
const selectionMode = isSelected ? state.worldEditor.selectedObjectMode : undefined;
|
||||||
|
|
||||||
useHelper(isSelected ? groupRef : { current: null } as any, BoxHelper, 'white');
|
useHelper(isSelected ? groupRef : { current: null } as any, BoxHelper, 'white');
|
||||||
|
|
||||||
|
if (!isSelected || selectionMode === undefined || !groupRef.current)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TransformControls
|
||||||
|
object={groupRef as RefObject<Group>}
|
||||||
|
mode={selectionMode}
|
||||||
|
onMouseUp={onTransformEnd}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ObjectEditorView = observer(function ({ object }: ObjectEditorViewProps) {
|
||||||
|
const groupRef = useRef<Group>(null);
|
||||||
|
|
||||||
|
// Only observes world object types — not selection state — so won't
|
||||||
|
// re-render when a different object is selected.
|
||||||
|
const objectType = state.world.getObjectTypeById(object.typeId);
|
||||||
if (!objectType)
|
if (!objectType)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
function handleClick(e: ThreeEvent<MouseEvent>) {
|
function handleClick(e: ThreeEvent<MouseEvent>) {
|
||||||
if (e.delta > 5) return;
|
if (e.delta > 5) return;
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
state.worldEditor.setSelectedObject(object.id, nextSelectionEditMode(selectionMode));
|
// Reading selection state inside an event handler: not tracked by observer.
|
||||||
|
const currentMode = state.worldEditor.isEnabled &&
|
||||||
|
state.worldEditor.selectedObjectId === object.id
|
||||||
|
? state.worldEditor.selectedObjectMode
|
||||||
|
: undefined;
|
||||||
|
state.worldEditor.setSelectedObject(object.id, nextSelectionEditMode(currentMode));
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTransformEnd() {
|
function handleTransformEnd() {
|
||||||
|
|
@ -45,13 +72,11 @@ export const ObjectEditorView = observer(function ({ object }: ObjectEditorViewP
|
||||||
}
|
}
|
||||||
|
|
||||||
return (<>
|
return (<>
|
||||||
{(isSelected && selectionMode !== undefined && groupRef.current) &&
|
<SelectionOverlay
|
||||||
<TransformControls
|
objectId={object.id}
|
||||||
object={groupRef as RefObject<Group>}
|
groupRef={groupRef}
|
||||||
mode={selectionMode}
|
onTransformEnd={handleTransformEnd}
|
||||||
onMouseUp={handleTransformEnd}
|
|
||||||
/>
|
/>
|
||||||
}
|
|
||||||
<ObjectViewInternal
|
<ObjectViewInternal
|
||||||
ref={groupRef}
|
ref={groupRef}
|
||||||
object={object}
|
object={object}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ type ObjectViewInternalProps = {
|
||||||
onClick?: (e: ThreeEvent<MouseEvent>) => void;
|
onClick?: (e: ThreeEvent<MouseEvent>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ObjectViewInternal = observer(forwardRef<Group, ObjectViewInternalProps>(
|
export const ObjectViewInternal = observer(forwardRef<Group | null, ObjectViewInternalProps>(
|
||||||
function ({ object, objectType, onClick }, ref) {
|
function ({ object, objectType, onClick }, ref) {
|
||||||
const trimeshArgs = useMemo(
|
const trimeshArgs = useMemo(
|
||||||
() => buildObjectTrimesh(objectType, state.world.data.voxelTypes),
|
() => buildObjectTrimesh(objectType, state.world.data.voxelTypes),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue