🚀 Auto-deploy: BrainWind atualizado em 28/07/2026 12:00:29

This commit is contained in:
2026-07-28 12:00:29 +00:00
parent e8334c3603
commit ce793d2213
+54 -19
View File
@@ -21,7 +21,7 @@ interface AirflowSystemProps {
}
export function AirflowSystem({ windAngle, width, length, height, permeabilityCase, wallCpe, roofCpe, cpi }: AirflowSystemProps) {
const count = 1000;
const count = 400; // Quantidade reduzida
const meshRef = useRef<THREE.InstancedMesh>(null);
const particles = useMemo(() => {
@@ -33,7 +33,7 @@ export function AirflowSystem({ windAngle, width, length, height, permeabilityCa
Math.random() * (height * 3),
(Math.random() - 0.5) * (length * 4)
),
baseSpeed: 0.15 + Math.random() * 0.2,
baseSpeed: 0.10 + Math.random() * 0.08, // Velocidade reduzida em ~20%
wobbleSpeed: Math.random() * 0.05,
wobbleOffset: Math.random() * Math.PI * 2,
currentCpe: 0,
@@ -61,8 +61,8 @@ export function AirflowSystem({ windAngle, width, length, height, permeabilityCa
if (!meshRef.current) return;
const time = state.clock.elapsedTime;
// Agora 0° é paralelo à Parede A e bate na Parede C (Eixo X)
// E 90° é paralelo à Parede C e bate na Parede A (Eixo Z)
// 0° = Eixo X
// 90° = Eixo Z
const isZAxis = windAngle === 90;
const windDir = isZAxis ? new THREE.Vector3(0, 0, 1) : new THREE.Vector3(1, 0, 0);
@@ -87,6 +87,46 @@ export function AirflowSystem({ windAngle, width, length, height, permeabilityCa
const inY = py >= 0 && py <= height;
const aboveRoof = py > height && py <= height + 3 && inX && inZ;
// ====== FLUXO AERODINÂMICO (CONTORNO DO TELHADO) ======
// Modifica o Y para subir antes do prédio e descer na esteira de sucção
const speedModifier = Math.max(0.2, 1 - (p.currentCpe * 0.5));
const currentSpeed = p.baseSpeed * speedModifier;
if (windAngle === 0 && Math.abs(pz) < halfL + margin * 2) {
if (px < -halfW && px > -halfW - height * 2) {
// Subindo antes de bater (Barlavento)
const dist = (-halfW - px);
const lift = Math.max(0, (height - py)) / (dist + 1);
deflectY += lift * currentSpeed * 0.5;
} else if (px >= -halfW && px <= 0 && py > height - 1) {
// Subindo no telhado (1ª Água)
deflectY += currentSpeed * 0.3;
} else if (px > 0 && px <= halfW && py > height - 1) {
// Descendo no telhado (2ª Água)
deflectY -= currentSpeed * 0.2;
} else if (px > halfW && px < halfW + height * 2) {
// Turbilhão de descida (Sotavento)
deflectY -= currentSpeed * 0.3;
}
} else if (windAngle === 90 && Math.abs(px) < halfW + margin * 2) {
if (pz < -halfL && pz > -halfL - height * 2) {
// Subindo antes de bater (Barlavento)
const dist = (-halfL - pz);
const lift = Math.max(0, (height - py)) / (dist + 1);
deflectY += lift * currentSpeed * 0.5;
} else if (pz >= -halfL && pz <= 0 && py > height - 1) {
// Subindo no telhado (1ª Água)
deflectY += currentSpeed * 0.3;
} else if (pz > 0 && pz <= halfL && py > height - 1) {
// Descendo no telhado (2ª Água)
deflectY -= currentSpeed * 0.2;
} else if (pz > halfL && pz < halfL + height * 2) {
// Turbilhão de descida (Sotavento)
deflectY -= currentSpeed * 0.3;
}
}
// =======================================================
if (inY && inX && inZ) {
// Perto das paredes
if (Math.abs(pz - (-halfL)) < margin) localCpe = wallCpe.A;
@@ -95,32 +135,27 @@ export function AirflowSystem({ windAngle, width, length, height, permeabilityCa
else if (Math.abs(px - (halfW)) < margin) localCpe = wallCpe.D;
else localCpe = cpi;
// Colisão: Expulsar as partículas do interior com força (Desvio realístico)
// Colisão dura (Impede entrar na parede sólida)
const isAirtight = permeabilityCase !== 'four-equally-permeable';
if (isAirtight) {
if (windAngle === 90 && 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
deflectY += p.baseSpeed * 2.0;
deflectX += px > 0 ? p.baseSpeed * 2.0 : -p.baseSpeed * 2.0;
p.position.z -= p.baseSpeed * 1.5;
} else if (windAngle === 0 && 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
deflectY += p.baseSpeed * 2.0;
deflectZ += pz > 0 ? p.baseSpeed * 2.0 : -p.baseSpeed * 2.0;
p.position.x -= p.baseSpeed * 1.5;
}
}
} else if (aboveRoof) {
localCpe = roofAvgCpe;
// Turbulência de vórtice severo no telhado
p.position.y += Math.sin(time * 5 + p.wobbleOffset) * 0.05;
p.position.y += Math.sin(time * 5 + p.wobbleOffset) * 0.05; // Vórtice
}
// 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, Sucção < 0 aumenta)
const speedModifier = Math.max(0.2, 1 - (p.currentCpe * 0.5));
const currentSpeed = p.baseSpeed * speedModifier;
// Move a partícula
p.position.x += windDir.x * currentSpeed + deflectX;
p.position.y += deflectY;
@@ -176,11 +211,11 @@ export function AirflowSystem({ windAngle, width, length, height, permeabilityCa
return (
<instancedMesh ref={meshRef} args={[undefined, undefined, count]}>
<cylinderGeometry args={[0.02, 0.02, 1.5, 4]} />
<cylinderGeometry args={[0.01, 0.01, 1.5, 4]} /> {/* Partículas ultra finas */}
<meshBasicMaterial
color="#ffffff"
transparent
opacity={0.7}
opacity={0.6}
blending={THREE.AdditiveBlending}
depthWrite={false}
/>