🚀 Auto-deploy: melhoria no snap e medição AR em 24/05/2026 18:28:15
This commit is contained in:
@@ -363,75 +363,125 @@ function ToolsTab(p: XRHudInWorldProps) {
|
||||
const resetScale = useModelStore((s) => s.resetScale);
|
||||
const clearMeasurements = useModelStore((s) => s.clearMeasurements);
|
||||
|
||||
const activeId = useModelStore((s) => s.activeModelId);
|
||||
const models = useModelStore((s) => s.models);
|
||||
const activeModel = models.find((m) => m.id === activeId);
|
||||
const setFineTuning = useModelStore((s) => s.setFineTuning);
|
||||
|
||||
const alignToFace = (face: string) => {
|
||||
let rotX = 0, rotY = 0, rotZ = 0;
|
||||
if (face === 'FRENTE') { rotX = 90; }
|
||||
else if (face === 'LADO') { rotX = 90; rotY = 90; }
|
||||
setFineTuning({ rotX, rotY, rotZ });
|
||||
};
|
||||
|
||||
const snapTo90 = () => {
|
||||
if (!activeModel) return;
|
||||
const ft = activeModel.fineTuning;
|
||||
setFineTuning({
|
||||
rotX: Math.round(ft.rotX / 90) * 90,
|
||||
rotY: Math.round(ft.rotY / 90) * 90,
|
||||
rotZ: Math.round(ft.rotZ / 90) * 90,
|
||||
});
|
||||
};
|
||||
|
||||
const resetRot = () => {
|
||||
setFineTuning({ rotX: 0, rotY: 0, rotZ: 0 });
|
||||
};
|
||||
|
||||
return (
|
||||
<group>
|
||||
<Text position={[-0.24, 0.11, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">Render</Text>
|
||||
<XR3DButton position={[-0.16, 0.085, 0]} size={[0.075, 0.022]} label="Sólido"
|
||||
{/* Fileira 1: Render */}
|
||||
<Text position={[-0.24, 0.125, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">Render</Text>
|
||||
<XR3DButton position={[-0.16, 0.105, 0]} size={[0.075, 0.022]} label="Sólido"
|
||||
active={renderMode === 'solid'} onClick={() => setRenderMode('solid')} />
|
||||
<XR3DButton position={[-0.08, 0.085, 0]} size={[0.075, 0.022]} label="Bordas"
|
||||
<XR3DButton position={[-0.08, 0.105, 0]} size={[0.075, 0.022]} label="Bordas"
|
||||
active={renderMode === 'edges'} onClick={() => setRenderMode('edges')} />
|
||||
|
||||
<Text position={[-0.24, 0.05, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">Toggles</Text>
|
||||
<XR3DButton position={[-0.16, 0.025, 0]} size={[0.075, 0.022]} label={`Grid ${showGrid ? 'ON' : 'OFF'}`}
|
||||
{/* Fileira 2: Toggles */}
|
||||
<Text position={[-0.24, 0.075, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">Toggles</Text>
|
||||
<XR3DButton position={[-0.16, 0.055, 0]} size={[0.075, 0.022]} label={`Grid ${showGrid ? 'ON' : 'OFF'}`}
|
||||
active={showGrid} onClick={() => setShowGrid(!showGrid)} />
|
||||
<XR3DButton position={[-0.08, 0.025, 0]} size={[0.075, 0.022]} label={`Medir ${measureMode ? 'ON' : 'OFF'}`}
|
||||
<XR3DButton position={[-0.08, 0.055, 0]} size={[0.075, 0.022]} label={`Medir ${measureMode ? 'ON' : 'OFF'}`}
|
||||
active={measureMode} onClick={() => setMeasureMode(!measureMode)} />
|
||||
<XR3DButton position={[0.0, 0.025, 0]} size={[0.075, 0.022]} label={`Snap ${p.snapToPlanes ? 'ON' : 'OFF'}`}
|
||||
<XR3DButton position={[0.0, 0.055, 0]} size={[0.075, 0.022]} label={`Snap ${p.snapToPlanes ? 'ON' : 'OFF'}`}
|
||||
active={p.snapToPlanes} onClick={p.onToggleSnap} />
|
||||
<XR3DButton position={[0.08, 0.025, 0]} size={[0.075, 0.022]}
|
||||
<XR3DButton position={[0.08, 0.055, 0]} size={[0.075, 0.022]}
|
||||
label={p.placementMode ? 'Posic…' : 'Reposic.'}
|
||||
active={p.placementMode} onClick={p.onTogglePlacement} />
|
||||
<XR3DButton position={[0.16, 0.025, 0]} size={[0.075, 0.022]}
|
||||
<XR3DButton position={[0.16, 0.055, 0]} size={[0.075, 0.022]}
|
||||
label={`Zoom ${p.allowScale ? 'ON' : 'OFF'}`}
|
||||
active={p.allowScale} onClick={p.onToggleAllowScale} />
|
||||
|
||||
{/* Selecionar — paridade com a tela inicial */}
|
||||
<Text position={[-0.24, -0.005, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">Selecionar</Text>
|
||||
<XR3DButton position={[-0.16, -0.03, 0]} size={[0.075, 0.022]}
|
||||
{/* Fileira 3: Selecionar */}
|
||||
<Text position={[-0.24, 0.025, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">Selecionar</Text>
|
||||
<XR3DButton position={[-0.16, 0.005, 0]} size={[0.075, 0.022]}
|
||||
label={selectionMode ? (selectedCount > 0 ? `${selectedCount} sel.` : 'Selec…') : 'Selec'}
|
||||
active={selectionMode} onClick={() => setSelectionMode(!selectionMode)} />
|
||||
<XR3DButton position={[-0.08, -0.03, 0]} size={[0.075, 0.022]} label="Esconder"
|
||||
<XR3DButton position={[-0.08, 0.005, 0]} size={[0.075, 0.022]} label="Esconder"
|
||||
onClick={hideSelectedElements} />
|
||||
<XR3DButton position={[0.0, -0.03, 0]} size={[0.075, 0.022]} label="Isolar"
|
||||
<XR3DButton position={[0.0, 0.005, 0]} size={[0.075, 0.022]} label="Isolar"
|
||||
onClick={isolateSelectedElements} />
|
||||
<XR3DButton position={[0.08, -0.03, 0]} size={[0.075, 0.022]} label="Mostrar"
|
||||
<XR3DButton position={[0.08, 0.005, 0]} size={[0.075, 0.022]} label="Mostrar"
|
||||
active={hasHidden} onClick={showAllElements} />
|
||||
|
||||
<Text position={[-0.24, -0.06, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">
|
||||
{/* Fileira 4: Opacidade */}
|
||||
<Text position={[-0.24, -0.025, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">
|
||||
Opacidade {Math.round(opacity * 100)}%
|
||||
</Text>
|
||||
<XR3DButton position={[-0.16, -0.085, 0]} size={[0.05, 0.022]} label="−25%"
|
||||
<XR3DButton position={[-0.16, -0.045, 0]} size={[0.05, 0.022]} label="−25%"
|
||||
onClick={() => setOpacity(Math.max(0, opacity - 0.25))} />
|
||||
<XR3DButton position={[-0.105, -0.085, 0]} size={[0.05, 0.022]} label="−5%"
|
||||
<XR3DButton position={[-0.105, -0.045, 0]} size={[0.05, 0.022]} label="−5%"
|
||||
onClick={() => setOpacity(Math.max(0, opacity - 0.05))} />
|
||||
<XR3DButton position={[-0.05, -0.085, 0]} size={[0.05, 0.022]} label="+5%"
|
||||
<XR3DButton position={[-0.05, -0.045, 0]} size={[0.05, 0.022]} label="+5%"
|
||||
onClick={() => setOpacity(Math.min(1, opacity + 0.05))} />
|
||||
<XR3DButton position={[0.005, -0.085, 0]} size={[0.05, 0.022]} label="+25%"
|
||||
<XR3DButton position={[0.005, -0.045, 0]} size={[0.05, 0.022]} label="+25%"
|
||||
onClick={() => setOpacity(Math.min(1, opacity + 0.25))} />
|
||||
<XR3DButton position={[0.06, -0.085, 0]} size={[0.05, 0.022]} label="100%"
|
||||
<XR3DButton position={[0.06, -0.045, 0]} size={[0.05, 0.022]} label="100%"
|
||||
onClick={() => setOpacity(1)} />
|
||||
|
||||
<Text position={[-0.24, -0.115, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">
|
||||
{/* Fileira 5: Escala */}
|
||||
<Text position={[-0.24, -0.075, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">
|
||||
Escala {scaleRatio.label}
|
||||
</Text>
|
||||
{SCALE_LABELS.map((lbl, i) => {
|
||||
const preset = SCALE_PRESETS.find((sp) => sp.label === lbl)!;
|
||||
return (
|
||||
<XR3DButton key={lbl}
|
||||
position={[-0.16 + i * 0.06, -0.14, 0]} size={[0.055, 0.022]} label={lbl}
|
||||
position={[-0.16 + i * 0.06, -0.095, 0]} size={[0.055, 0.022]} label={lbl}
|
||||
active={scaleRatio.label === lbl}
|
||||
onClick={() => setScaleRatio(preset)} />
|
||||
);
|
||||
})}
|
||||
<XR3DButton position={[0.10, -0.14, 0]} size={[0.062, 0.022]}
|
||||
<XR3DButton position={[0.10, -0.095, 0]} size={[0.062, 0.022]}
|
||||
label="↺ Reset" color="#dc2626"
|
||||
onClick={resetScale} fontSize={0.0085} />
|
||||
<XR3DButton position={[0.17, -0.14, 0]} size={[0.062, 0.022]}
|
||||
<XR3DButton position={[0.17, -0.095, 0]} size={[0.062, 0.022]}
|
||||
label="✕ Medidas" color="#dc2626"
|
||||
onClick={clearMeasurements} fontSize={0.0085} />
|
||||
|
||||
{/* Fileira 6: Rotação / Alinhamento Ortogonal */}
|
||||
<Text position={[-0.24, -0.125, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">
|
||||
Alinhar Rotação
|
||||
</Text>
|
||||
<XR3DButton position={[-0.16, -0.145, 0]} size={[0.075, 0.022]}
|
||||
label="Snap 90°" active={false}
|
||||
onClick={snapTo90} fontSize={0.0075} />
|
||||
<XR3DButton position={[-0.08, -0.145, 0]} size={[0.05, 0.022]}
|
||||
label="Topo" active={false}
|
||||
onClick={() => alignToFace('TOPO')} fontSize={0.0075} />
|
||||
<XR3DButton position={[-0.025, -0.145, 0]} size={[0.05, 0.022]}
|
||||
label="Frente" active={false}
|
||||
onClick={() => alignToFace('FRENTE')} fontSize={0.0075} />
|
||||
<XR3DButton position={[0.03, -0.145, 0]} size={[0.05, 0.022]}
|
||||
label="Lado" active={false}
|
||||
onClick={() => alignToFace('LADO')} fontSize={0.0075} />
|
||||
<XR3DButton position={[0.12, -0.145, 0]} size={[0.09, 0.022]}
|
||||
label="Zerar Rot." color="#dc2626"
|
||||
onClick={resetRot} fontSize={0.0075} />
|
||||
|
||||
{measureMode && (
|
||||
<Text position={[-0.24, -0.17, 0]} fontSize={0.0065} color="#a3e635" anchorX="left" maxWidth={0.5}>
|
||||
<Text position={[-0.24, -0.175, 0]} fontSize={0.0055} color="#a3e635" anchorX="left" maxWidth={0.5}>
|
||||
Gatilho D: marcar · A: desfazer · B: limpar · Gatilho E: alternar snap
|
||||
</Text>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user