faster selection in editor
This commit is contained in:
parent
4e7b44dc57
commit
8575327af8
|
|
@ -13,24 +13,51 @@ type ObjectEditorViewProps = {
|
|||
object: Runtime<ObjectInstance>;
|
||||
}
|
||||
|
||||
export const ObjectEditorView = observer(function ({ object }: ObjectEditorViewProps) {
|
||||
const groupRef = useRef<Group>(null);
|
||||
|
||||
const objectType = state.world.getObjectTypeById(object.typeId);
|
||||
type SelectionOverlayProps = {
|
||||
objectId: string;
|
||||
groupRef: RefObject<Group | null>;
|
||||
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 &&
|
||||
state.worldEditor.selectedObjectId === object.id;
|
||||
state.worldEditor.selectedObjectId === objectId;
|
||||
const selectionMode = isSelected ? state.worldEditor.selectedObjectMode : undefined;
|
||||
|
||||
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)
|
||||
return null;
|
||||
|
||||
function handleClick(e: ThreeEvent<MouseEvent>) {
|
||||
if (e.delta > 5) return;
|
||||
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() {
|
||||
|
|
@ -45,13 +72,11 @@ export const ObjectEditorView = observer(function ({ object }: ObjectEditorViewP
|
|||
}
|
||||
|
||||
return (<>
|
||||
{(isSelected && selectionMode !== undefined && groupRef.current) &&
|
||||
<TransformControls
|
||||
object={groupRef as RefObject<Group>}
|
||||
mode={selectionMode}
|
||||
onMouseUp={handleTransformEnd}
|
||||
<SelectionOverlay
|
||||
objectId={object.id}
|
||||
groupRef={groupRef}
|
||||
onTransformEnd={handleTransformEnd}
|
||||
/>
|
||||
}
|
||||
<ObjectViewInternal
|
||||
ref={groupRef}
|
||||
object={object}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ type ObjectViewInternalProps = {
|
|||
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) {
|
||||
const trimeshArgs = useMemo(
|
||||
() => buildObjectTrimesh(objectType, state.world.data.voxelTypes),
|
||||
|
|
|
|||
Loading…
Reference in New Issue