🚀 Auto-deploy: melhoria no snap e medição AR em 25/05/2026 01:28:33

This commit is contained in:
2026-05-25 01:28:33 +00:00
parent 61591dc84e
commit 0baed4a871
+75 -35
View File
@@ -538,6 +538,26 @@ function HologramModel({ model, presentationState }: { model: SceneModel; presen
// Cenário da Sala de Reunião Clara
function ThreeMeetingRoomScene({ currentActiveModel, presentationState, isFocusMode }: { currentActiveModel: SceneModel | null; presentationState: PresentationState; isFocusMode: boolean }) {
const tableGeom = useMemo(() => {
// Geometria da mesa em U / Retangular de cantos arredondados
const shape = new THREE.Shape();
shape.moveTo(-1.6, -1.1);
shape.lineTo(1.6, -1.1);
shape.quadraticCurveTo(1.9, -1.1, 1.9, -0.8);
shape.lineTo(1.9, 0.8);
shape.quadraticCurveTo(1.9, 1.1, 1.6, 1.1);
shape.lineTo(-1.6, 1.1);
shape.quadraticCurveTo(-1.9, 1.1, -1.9, 0.8);
shape.lineTo(-1.9, -0.8);
shape.quadraticCurveTo(-1.9, -1.1, -1.6, -1.1);
const hole = new THREE.Path();
hole.absellipse(0, 0, 0.9, 0.45, 0, Math.PI * 2, true);
shape.holes.push(hole);
return new THREE.ExtrudeGeometry(shape, { depth: 0.06, bevelEnabled: true, bevelThickness: 0.01, bevelSize: 0.01, bevelSegments: 3 });
}, []);
return (
<group>
{/* Luzes da Sala / Foco */}
@@ -577,29 +597,28 @@ function ThreeMeetingRoomScene({ currentActiveModel, presentationState, isFocusM
<meshStandardMaterial color="#bae6fd" roughness={0.1} emissive="#bae6fd" emissiveIntensity={0.4} />
</mesh>
{/* Mesa Cilíndrica Central de 1m de diâmetro (raio 0.5) */}
<group position={[0, 0, 0]}>
{/* Base no chão */}
<mesh position={[0, 0.01, 0]} castShadow receiveShadow>
<cylinderGeometry args={[0.25, 0.25, 0.02, 32]} />
<meshStandardMaterial color="#475569" metalness={0.7} roughness={0.2} />
</mesh>
{/* Coluna / Pé da mesa */}
<mesh position={[0, 0.45, 0]} castShadow receiveShadow>
<cylinderGeometry args={[0.06, 0.06, 0.9, 32]} />
<meshStandardMaterial color="#64748b" metalness={0.8} roughness={0.1} />
</mesh>
{/* Tampo da mesa (Diâmetro 1m, altura 0.9m) */}
<mesh position={[0, 0.9, 0]} castShadow receiveShadow>
<cylinderGeometry args={[0.5, 0.5, 0.06, 48]} />
<meshStandardMaterial color="#d97706" roughness={0.4} metalness={0.1} />
</mesh>
{/* Projetor de Holograma (Centro da mesa) */}
<mesh position={[0, 0.931, 0]} rotation={[-Math.PI / 2, 0, 0]}>
<ringGeometry args={[0.22, 0.25, 32]} />
<meshBasicMaterial color="#0ea5e9" transparent opacity={0.6} />
{/* Mesa Elíptica/Retangular com furo central (Madeira Mel Carvalho Clara) */}
<group position={[0, 0.8, 0]} rotation={[Math.PI / 2, 0, 0]}>
<mesh geometry={tableGeom} castShadow receiveShadow>
<meshStandardMaterial color="#d97706" roughness={0.2} metalness={0.1} />
</mesh>
</group>
{/* Pés da mesa (Cromados) */}
{[-1.3, 1.3].map((x) =>
[-0.7, 0.7].map((z) => (
<mesh key={`${x}-${z}`} position={[x, 0.4, z]} castShadow receiveShadow>
<cylinderGeometry args={[0.035, 0.035, 0.8]} />
<meshStandardMaterial color="#d4d4d8" metalness={0.9} roughness={0.1} />
</mesh>
))
)}
{/* Projetor de Holograma / Círculo centralizado desenhado na mesa */}
<mesh position={[0, 0.861, 0]} rotation={[-Math.PI / 2, 0, 0]}>
<ringGeometry args={[0.22, 0.25, 32]} />
<meshBasicMaterial color="#0ea5e9" transparent opacity={0.6} />
</mesh>
</>
)}
@@ -787,18 +806,28 @@ export default function MeetingRoom() {
tempChannel
.on('presence', { event: 'sync' }, () => {
const state = tempChannel.presenceState();
console.log("👥 [Lobby Watcher Sync] Estado de presença bruto:", state);
const formattedPeers: Record<string, PeerData> = {};
Object.keys(state).forEach((chairKey) => {
// Ignora outros watchers do lobby
if (chairKey.startsWith('lobby_watcher_')) return;
const presences = state[chairKey] as unknown as PeerData[];
Object.keys(state).forEach((key) => {
if (key.startsWith('lobby_watcher_')) return;
const presences = state[key] as unknown as PeerData[];
if (presences && presences.length > 0) {
formattedPeers[chairKey] = presences[0];
presences.forEach((presence) => {
if (presence && presence.chairId && presence.username) {
formattedPeers[presence.chairId] = {
...presence,
avatarId: Number(presence.avatarId) || 1,
cargo: presence.cargo || 'Colaborador',
empresa: presence.empresa || 'SteelXR Corp',
role: presence.role || 'guest'
};
}
});
}
});
console.log("👥 [Lobby Watcher Sync] Peers formatados:", formattedPeers);
setPeers(formattedPeers);
})
.subscribe();
@@ -862,28 +891,39 @@ export default function MeetingRoom() {
const channel = supabase.channel(`meeting_room_${finalRoomId}`, {
config: {
broadcast: { self: true },
presence: { key: selectedChair },
broadcast: { self: true }
},
});
channelRef.current = channel;
// Sincroniza participantes online
// Sincroniza participantes online com tolerância a múltiplos formatos e falhas de conexão
channel
.on('presence', { event: 'sync' }, () => {
const state = channel.presenceState();
console.log("👥 [Presence Sync] Estado de presença bruto da reunião:", state);
const formattedPeers: Record<string, PeerData> = {};
let count = 0;
Object.keys(state).forEach((chairKey) => {
if (chairKey.startsWith('lobby_watcher_')) return;
const presences = state[chairKey] as unknown as PeerData[];
Object.keys(state).forEach((key) => {
if (key.startsWith('lobby_watcher_')) return;
const presences = state[key] as unknown as PeerData[];
if (presences && presences.length > 0) {
formattedPeers[chairKey] = presences[0];
count++;
presences.forEach((presence) => {
if (presence && presence.chairId && presence.username) {
formattedPeers[presence.chairId] = {
...presence,
avatarId: Number(presence.avatarId) || 1,
cargo: presence.cargo || 'Colaborador',
empresa: presence.empresa || 'SteelXR Corp',
role: presence.role || 'guest'
};
count++;
}
});
}
});
console.log("👥 [Presence Sync] Peers formatados:", formattedPeers);
setPeers(formattedPeers);
setActiveUsersCount(count);
})