🚀 Auto-deploy: melhoria no snap e medição AR em 25/05/2026 01:28:33
This commit is contained in:
+75
-35
@@ -538,6 +538,26 @@ function HologramModel({ model, presentationState }: { model: SceneModel; presen
|
|||||||
|
|
||||||
// Cenário da Sala de Reunião Clara
|
// Cenário da Sala de Reunião Clara
|
||||||
function ThreeMeetingRoomScene({ currentActiveModel, presentationState, isFocusMode }: { currentActiveModel: SceneModel | null; presentationState: PresentationState; isFocusMode: boolean }) {
|
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 (
|
return (
|
||||||
<group>
|
<group>
|
||||||
{/* Luzes da Sala / Foco */}
|
{/* Luzes da Sala / Foco */}
|
||||||
@@ -577,29 +597,28 @@ function ThreeMeetingRoomScene({ currentActiveModel, presentationState, isFocusM
|
|||||||
<meshStandardMaterial color="#bae6fd" roughness={0.1} emissive="#bae6fd" emissiveIntensity={0.4} />
|
<meshStandardMaterial color="#bae6fd" roughness={0.1} emissive="#bae6fd" emissiveIntensity={0.4} />
|
||||||
</mesh>
|
</mesh>
|
||||||
|
|
||||||
{/* Mesa Cilíndrica Central de 1m de diâmetro (raio 0.5) */}
|
{/* Mesa Elíptica/Retangular com furo central (Madeira Mel Carvalho Clara) */}
|
||||||
<group position={[0, 0, 0]}>
|
<group position={[0, 0.8, 0]} rotation={[Math.PI / 2, 0, 0]}>
|
||||||
{/* Base no chão */}
|
<mesh geometry={tableGeom} castShadow receiveShadow>
|
||||||
<mesh position={[0, 0.01, 0]} castShadow receiveShadow>
|
<meshStandardMaterial color="#d97706" roughness={0.2} metalness={0.1} />
|
||||||
<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} />
|
|
||||||
</mesh>
|
</mesh>
|
||||||
</group>
|
</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
|
tempChannel
|
||||||
.on('presence', { event: 'sync' }, () => {
|
.on('presence', { event: 'sync' }, () => {
|
||||||
const state = tempChannel.presenceState();
|
const state = tempChannel.presenceState();
|
||||||
|
console.log("👥 [Lobby Watcher Sync] Estado de presença bruto:", state);
|
||||||
const formattedPeers: Record<string, PeerData> = {};
|
const formattedPeers: Record<string, PeerData> = {};
|
||||||
|
|
||||||
Object.keys(state).forEach((chairKey) => {
|
Object.keys(state).forEach((key) => {
|
||||||
// Ignora outros watchers do lobby
|
if (key.startsWith('lobby_watcher_')) return;
|
||||||
if (chairKey.startsWith('lobby_watcher_')) return;
|
const presences = state[key] as unknown as PeerData[];
|
||||||
|
|
||||||
const presences = state[chairKey] as unknown as PeerData[];
|
|
||||||
if (presences && presences.length > 0) {
|
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);
|
setPeers(formattedPeers);
|
||||||
})
|
})
|
||||||
.subscribe();
|
.subscribe();
|
||||||
@@ -862,28 +891,39 @@ export default function MeetingRoom() {
|
|||||||
|
|
||||||
const channel = supabase.channel(`meeting_room_${finalRoomId}`, {
|
const channel = supabase.channel(`meeting_room_${finalRoomId}`, {
|
||||||
config: {
|
config: {
|
||||||
broadcast: { self: true },
|
broadcast: { self: true }
|
||||||
presence: { key: selectedChair },
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
channelRef.current = channel;
|
channelRef.current = channel;
|
||||||
|
|
||||||
// Sincroniza participantes online
|
// Sincroniza participantes online com tolerância a múltiplos formatos e falhas de conexão
|
||||||
channel
|
channel
|
||||||
.on('presence', { event: 'sync' }, () => {
|
.on('presence', { event: 'sync' }, () => {
|
||||||
const state = channel.presenceState();
|
const state = channel.presenceState();
|
||||||
|
console.log("👥 [Presence Sync] Estado de presença bruto da reunião:", state);
|
||||||
const formattedPeers: Record<string, PeerData> = {};
|
const formattedPeers: Record<string, PeerData> = {};
|
||||||
let count = 0;
|
let count = 0;
|
||||||
|
|
||||||
Object.keys(state).forEach((chairKey) => {
|
Object.keys(state).forEach((key) => {
|
||||||
if (chairKey.startsWith('lobby_watcher_')) return;
|
if (key.startsWith('lobby_watcher_')) return;
|
||||||
const presences = state[chairKey] as unknown as PeerData[];
|
const presences = state[key] as unknown as PeerData[];
|
||||||
if (presences && presences.length > 0) {
|
if (presences && presences.length > 0) {
|
||||||
formattedPeers[chairKey] = presences[0];
|
presences.forEach((presence) => {
|
||||||
count++;
|
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);
|
setPeers(formattedPeers);
|
||||||
setActiveUsersCount(count);
|
setActiveUsersCount(count);
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user