diff --git a/app/src/components/Warehouse3D.tsx b/app/src/components/Warehouse3D.tsx index 395f7cc..d7f6002 100644 --- a/app/src/components/Warehouse3D.tsx +++ b/app/src/components/Warehouse3D.tsx @@ -80,13 +80,13 @@ function WindDirectionIndicator({ angle, width, length, height }: { angle: numbe const isDark = useCanvasTheme() === 'dark'; const color = isDark ? "#38bdf8" : "#0284c7"; // Light blue / dark blue - // Angle 0: Wind blows along X axis, from negative X towards origin (hitting Wall C at X=-width/2) - // Angle 90: Wind blows along Z axis, from negative Z towards origin (hitting Wall A at Z=-length/2) + // Angle 0: Wind blows along Z axis (Perpendicular à largura X) + // Angle 90: Wind blows along X axis (Paralelo à largura X) - const dir = angle === 90 ? new THREE.Vector3(0, 0, 1) : new THREE.Vector3(1, 0, 0); + const dir = angle === 0 ? new THREE.Vector3(0, 0, 1) : new THREE.Vector3(1, 0, 0); const distance = Math.max(width, length) * 0.6 + 5; - const startPos = angle === 90 ? new THREE.Vector3(0, height / 2, -distance) : new THREE.Vector3(-distance, height / 2, 0); + const startPos = angle === 0 ? new THREE.Vector3(0, height / 2, -distance) : new THREE.Vector3(-distance, height / 2, 0); const quat = new THREE.Quaternion(); quat.setFromUnitVectors(new THREE.Vector3(0, 1, 0), dir); diff --git a/app/src/components/three/AirflowSystem.tsx b/app/src/components/three/AirflowSystem.tsx index dbaf1e8..e723473 100644 --- a/app/src/components/three/AirflowSystem.tsx +++ b/app/src/components/three/AirflowSystem.tsx @@ -60,10 +60,11 @@ export function AirflowSystem({ windAngle, width, length, height, permeabilityCa useFrame((state) => { if (!meshRef.current) return; const time = state.clock.elapsedTime; - const isParallel = windAngle === 90; - - // Vetor direção do vento - const windDir = isParallel ? new THREE.Vector3(0, 0, 1) : new THREE.Vector3(1, 0, 0); + + // Agora 0° é paralelo à Parede A (ao longo do eixo Z) + // E 90° é paralelo à Parede C (ao longo do eixo X) + const isZAxis = windAngle === 0; + const windDir = isZAxis ? new THREE.Vector3(0, 0, 1) : new THREE.Vector3(1, 0, 0); const halfW = width / 2; const halfL = length / 2; @@ -72,7 +73,6 @@ export function AirflowSystem({ windAngle, width, length, height, permeabilityCa const roofAvgCpe = (roofCpe.E + roofCpe.F + roofCpe.G + roofCpe.H + roofCpe.I + roofCpe.J) / 6; particles.forEach((p, i) => { - // Determinar a zona e o Cpe local let localCpe = 0; let deflectY = 0; let deflectX = 0; @@ -93,29 +93,31 @@ export function AirflowSystem({ windAngle, width, length, height, permeabilityCa else if (Math.abs(pz - (halfL)) < margin) localCpe = wallCpe.B; else if (Math.abs(px - (-halfW)) < margin) localCpe = wallCpe.C; else if (Math.abs(px - (halfW)) < margin) localCpe = wallCpe.D; - else localCpe = cpi; // Dentro do prédio + else localCpe = cpi; - // Se bateu na parede a barlavento, desvia o fluxo (Aerodinâmica) + // Colisão: Expulsar as partículas do interior com força (Desvio realístico) const isAirtight = permeabilityCase !== 'four-equally-permeable'; if (isAirtight) { - if (windAngle === 0 && px < -halfW + margin) { - deflectY = p.baseSpeed * 1.5; // Sobe - deflectZ = pz > 0 ? p.baseSpeed * 1.5 : -p.baseSpeed * 1.5; // Vai pros lados - } else if (windAngle === 90 && pz < -halfL + margin) { - deflectY = p.baseSpeed * 1.5; // Sobe - deflectX = px > 0 ? p.baseSpeed * 1.5 : -p.baseSpeed * 1.5; // Vai pros lados + if (windAngle === 0 && pz < -halfL + margin) { + deflectY = p.baseSpeed * 2.0; // Levanta pro telhado + deflectX = px > 0 ? p.baseSpeed * 2.0 : -p.baseSpeed * 2.0; // Contorna laterais + p.position.z -= p.baseSpeed * 1.5; // Impede de avançar + } else if (windAngle === 90 && px < -halfW + margin) { + deflectY = p.baseSpeed * 2.0; // Levanta pro telhado + deflectZ = pz > 0 ? p.baseSpeed * 2.0 : -p.baseSpeed * 2.0; // Contorna laterais + p.position.x -= p.baseSpeed * 1.5; // Impede de avançar } } } else if (aboveRoof) { localCpe = roofAvgCpe; - // Vórtice no telhado - p.position.y += Math.sin(time * 5 + p.wobbleOffset) * 0.03; + // Turbulência de vórtice severo no telhado + p.position.y += Math.sin(time * 5 + p.wobbleOffset) * 0.05; } - // Suaviza a transição de Cpe para a cor não piscar + // Suaviza a transição de Cpe para a cor fluir p.currentCpe += (localCpe - p.currentCpe) * 0.1; - // Modifica velocidade com base no Cpe (Pressão > 0 diminui vel, Sucção < 0 aumenta vel) + // Modifica velocidade com base no Cpe (Pressão > 0 diminui, Sucção < 0 aumenta) const speedModifier = Math.max(0.2, 1 - (p.currentCpe * 0.5)); const currentSpeed = p.baseSpeed * speedModifier; @@ -128,46 +130,39 @@ export function AirflowSystem({ windAngle, width, length, height, permeabilityCa p.position.y += Math.sin(time * p.wobbleSpeed * 10 + p.wobbleOffset) * 0.01; // Recicla partículas que saem da tela - if (isParallel) { + if (isZAxis) { if (p.position.z > halfL + 30) { p.position.z = -halfL - 30; - p.position.y = Math.random() * (height * 2); + p.position.y = Math.random() * (height * 2.5); p.position.x = (Math.random() - 0.5) * (width * 3); p.currentCpe = 0; } } else { if (p.position.x > halfW + 30) { p.position.x = -halfW - 30; - p.position.y = Math.random() * (height * 2); + p.position.y = Math.random() * (height * 2.5); p.position.z = (Math.random() - 0.5) * (length * 3); p.currentCpe = 0; } } - // Atualiza posição e escala na matriz dummy.position.copy(p.position); - // Aponta para a direção do movimento real const moveVec = new THREE.Vector3(windDir.x + deflectX, deflectY, windDir.z + deflectZ).normalize(); dummy.lookAt(p.position.clone().add(moveVec)); dummy.rotateX(Math.PI / 2); - // Estica a barrinha dependendo da velocidade (efeito blur) - dummy.scale.set(1, 1 + currentSpeed * 5, 1); - + // Estica barrinha com a velocidade + dummy.scale.set(1, 1 + currentSpeed * 6, 1); dummy.updateMatrix(); meshRef.current!.setMatrixAt(i, dummy.matrix); - // Atualiza Cor if (p.currentCpe > 0) { - // Pressão (Quente: Vermelho -> Laranja) colorObj.set('#ef4444').lerp(new THREE.Color('#fcd34d'), 1 - Math.min(1, p.currentCpe)); } else if (p.currentCpe < 0) { - // Sucção (Frio: Azul claro -> Azul escuro) const intensity = Math.min(1, Math.abs(p.currentCpe)); colorObj.set('#7dd3fc').lerp(new THREE.Color('#1e40af'), intensity); } else { - // Neutro colorObj.set('#f1f5f9'); } meshRef.current!.setColorAt(i, colorObj); @@ -181,11 +176,11 @@ export function AirflowSystem({ windAngle, width, length, height, permeabilityCa return ( - +